新手求教!麻烦大触帮我看下代码,多谢~
第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;
}
}
了解下逆波兰表示法,利用栈的数据结构来实现,最复杂的地方在于怎么把正常的四则运算转换为后缀表达式。