java,目标是控制台实现带括号的加减乘除运算

新手求教!麻烦大触帮我看下代码,多谢~

第4次改(依旧错

package com.calculator;
import java.io.*;
import java.util.regex.*;
public class calculator {
    public static StringBuilder first(StringBuilder s){
        int a,b;
        while(s.indexOf("(")!=-1){
            a=s.lastIndexOf(")");
            b=s.indexOf(")",a);
            s.replace(0,b+1,second(new StringBuilder(s.substring(a+1,b))).toString());
        }
        return s;
    }
    public static StringBuilder second(StringBuilder s){
        Pattern p=Pattern.compile("[-+*/]");
        String[] st=p.split(s.toString());
        char[] stll=new char[s.length()];
        int j=0;
        for(int i=0;i<s.length();i++){
            if(s.charAt(i)=='*') stll[j++]='*';
            else if(s.charAt(i)=='/') stll[j++]='/';
            else if(s.charAt(i)=='+') stll[j++]='+';
            else if(s.charAt(i)=='-') stll[j++]='-';        
        }
        char[] st1=new char[j];
        System.arraycopy(stll,0,st1,0,j);
        String[] str=new String[st.length];
        int x=0;
        if(st1[0]=='*'){
            str[x]=String.valueOf(Double.parseDouble(st[0])*Double.parseDouble(st[1]));
            st[1]=str[x];
        }
        else if(st1[0]=='/'){
            str[x]=String.valueOf(Double.parseDouble(st[0])/Double.parseDouble(st[1]));
            st[1]=str[x];
        }
        else if(st1[0]=='+'){
            str[x]=st[0];
            str[++x]="+";
            str[++x]=st[1];
        }
        else if(st1[0]=='-'){
            str[x]=st[0];
            str[++x]="-";
            str[++x]=st[1];
        }
        j=2;
        for(int i=1;i<st1.length;i++){
            if(st1[i]=='*'){
                str[++x]=String.valueOf(Double.parseDouble(st[j])*Double.parseDouble(st[++j]));
                st[j]=str[x];
            }else if(st1[i]=='/'){
                str[++x]=String.valueOf(Double.parseDouble(st[j])*Double.parseDouble(st[++j]));
                st[j]=str[x];
            }else if(st1[i]=='+'){
                str[++x]="+";
                str[++x]=st[++j];
            }else if(st1[i]=='-'){
                str[++x]="-";
                str[++x]=st[++j];
            }
        }
        StringBuilder ss=new StringBuilder();
        for(int i=0;i<=x;i++){
            ss.append(str[x]);
        }
        if(ss.indexOf("+")!=-1||ss.indexOf("-")!=-1){
            ss=third(ss);
        }
        return ss;
    }
    public static StringBuilder third(StringBuilder s){
        Pattern p=Pattern.compile("[+-]");
        String[] st=p.split(s.toString());
        int j=0;
        for(int i=0;i<s.length();i++){
            if(s.charAt(i)=='+'){
                  j++;
                  st[j]=String.valueOf(Double.parseDouble(st[j-1])+Double.parseDouble(st[j]));
            }
            else if(s.charAt(i)=='-'){
                  j++;
                  st[j]=String.valueOf(Double.parseDouble(st[j-1])-Double.parseDouble(st[j]));
            }
        }
        return new StringBuilder(st[j].trim());
      }
     public static void main(String[] args) {
        try {
            BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
            String s=in.readLine();
            StringBuilder ss=new StringBuilder(s);
            if(ss.indexOf("(")!=-1) ss=first(ss);
            else if(ss.indexOf("*")!=-1||ss.indexOf("/")!=-1) ss=second(ss);
            else ss=third(ss);
            System.out.println("="+ss);
     }catch(NumberFormatException e){
         System.err.println("NumberFormatException");
         e.printStackTrace();
     }catch(ArrayIndexOutOfBoundsException e){
         System.err.println("ArrayIndexOutOfBoundsException");
         e.printStackTrace();
     }catch (IOException e) {
         System.err.println("IOException");
         e.printStackTrace();
     }catch(Exception e){
         System.err.println("Exception");
         e.printStackTrace();
     }
  }
}

加减运算没问题,第二优先级1步运算没问题,2步开始出错:
2*2*2

ArrayIndexOutOfBoundsException
java.lang.ArrayIndexOutOfBoundsException: 3
at com.calculator.calculator.second(calculator.java:50)
at com.calculator.calculator.main(calculator.java:94)

(2+3)*2

Exception
java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.AbstractStringBuilder.substring(Unknown Source)
at java.lang.StringBuilder.substring(Unknown Source)
at com.calculator.calculator.first(calculator.java:10)
at com.calculator.calculator.main(calculator.java:93)

你可以去了解一下后缀表达式

你看报错,写着空指针表达式文本长度,未知来源,你的测试数据对么

http://www.open-open.com/lib/view/open1326806268546.html
http://speed-guo.iteye.com/blog/949372

split方法用得不对,分隔符太多了,不能分隔成数组。
试用一下,中序表达式算法

我写的 貌似可以用 12*-10+(9*9+2+(8/3-2)) 这样的可以算出来 在复杂一点就难说了
package com;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Calculator {
//+-*/()
public static void main(String[] args) {
// Pattern pattern = Pattern.compile("(?<=\d)(\+|-|\*|/)");
// Matcher matcher = pattern.matcher("2-4");//3*((5*(2-4))*(3-1*2))
// while(matcher.find()){
// System.out.println(matcher.group());
// };
double rs = 0;
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
rs=count(str);
System.out.println(rs);
}
public static double count(String str){
Pattern p1 = Pattern.compile("\([^\(^\)]*\)");
Matcher m1 = p1.matcher(str);
if(m1.find()){
if(m1.start()==0&&m1.end()==str.length()){
if(str.startsWith("(")&&str.endsWith(")")){
str = str.substring(1,str.length()-1);
}
}
}
double rs = 0;
Pattern pattern = Pattern.compile("\([^\(^\)]*\)");
Matcher matcher = pattern.matcher(str);
while(matcher.find()){//计算最里面的一对括号们
String str2 = matcher.group();
rs = count(str2);
str = str.replace(str2,String.valueOf(rs));
}
while(str.indexOf("(")>-1){//算完以后还有括号继续优先算
Matcher matcher2 = pattern.matcher(str);
while(matcher2.find()){
String str2 = matcher2.group();
rs = count(str2);
str = str.replace(str2,String.valueOf(rs));
}
}
rs = count2(str);
return rs;
}
private static double count2(String str) {
if(str.startsWith("(")&&str.endsWith(")")){
str = str.substring(1,str.length()-1);
}
double rs = 0;
String[] nums = str.split("(?<=\d)(\+|-|\*|/)");
String[] ctrls = str.replaceAll("[0-9.]|(?<!\d)(\+|-|\*|/)", "").split("");
List numsList = new ArrayList();
List ctrlsList = new ArrayList();
for (String string : nums) {
numsList.add(string);
}
for (String string : ctrls) {
ctrlsList.add(string);
}
for (int i = 1; i < ctrlsList.size(); i++) {
if("*".equals(ctrlsList.get(i))||"/".equals(ctrlsList.get(i))){
double start = Double.parseDouble(numsList.get(i-1));
double end = Double.parseDouble(numsList.get(i));
if("*".equals(ctrlsList.get(i))){
rs = start*end;
}else{
rs = start/end;
}
ctrlsList.remove(i);
numsList.remove(i);
numsList.set(i-1, String.valueOf(rs));
i--;
}
}
for (int i = 1; i < ctrlsList.size(); i++) {
if("+".equals(ctrlsList.get(i))||"-".equals(ctrlsList.get(i))){
double start = Double.parseDouble(numsList.get(i-1));
double end = Double.parseDouble(numsList.get(i));
if("+".equals(ctrlsList.get(i))){
rs = start+end;
}else{
rs = start-end;
}
ctrlsList.remove(i);
numsList.remove(i);
numsList.set(i-1, String.valueOf(rs));
i--;
}
}
return rs;
}
}

了解下逆波兰表示法,利用栈的数据结构来实现,最复杂的地方在于怎么把正常的四则运算转换为后缀表达式。