public class Demo {
public static void main(String[] args)
{
System.out.println("请输入您要计算的表达式:");
Scanner in = new Scanner(System.in);
String s = in.nextLine();   //创建字符串接收输入的表达式
String str = Check(s);

double result = Ergo(str);
System.out.println(result); }

public static String Check(String str) //剔除符号,字母
{
String expstr = "";
int i = 0;
while (i<str.length())
{
char ch = str.charAt(i);
if (i<str.length() && ch>= '(' && ch<= '9'||ch=='#'){ expstr += ch; }
i++;
}
return expstr;

}

public static int lp(char op)//左操作符优先级
{
switch(op)
{
case '+':
case '-':return 3;
case '*':
case '/':return 5;
case '(':return 1;
case ')':return 6;
case '#':return 0;
default:return -1;
}
}

public static int rp(char op)//右操作符优先级
{
switch(op)
{
case '+':
case '-':return 2;
case '*':
case '/':return 4;
case '(':return 6;
case ')':return 1;
case '#':return 0;
default:return -1;
}
}

public static double Ergo(String str)//三栈遍历计算得值
{
SeqStack<Double>    Num= new SeqStack<Double>();//操作数栈,double类型;
SeqStack<Character> Op = new SeqStack<Character>();//操作符栈,char类型;
SeqStack<Character> Tem= new SeqStack<Character>();//临时栈,char类型;
String numstr = "";
System.out.println("1");
int i = 0;
while(str.charAt(i)!='#')
{
System.out.println("2");
if(str.charAt(i)>='0'&&str.charAt(i)<='9'||str.charAt(i)=='.'&&!Tem.isEmpty())//指向数字字符
{
System.out.println("3");
Tem.push(str.charAt(i));//str顺序入临时栈
i++;
}
else if( lp(Op.get()) < rp(str.charAt(i)) || Op.isEmpty() )
{
System.out.println("4");
while(!Tem.isEmpty())
{
numstr += Tem.pop();
}

Num.push(toNum(numstr));//转换为浮点数   
Op.push(str.charAt(i)); i++;
}
else if( lp(Op.get()) > rp(str.charAt(i)) )
{
System.out.println("5");
char op = Op.pop();

while(!Tem.isEmpty())
{
numstr += Tem.pop();
}
Num.push(toNum(numstr));//转换为浮点数   

double y = Num.pop();
double x = Num.pop();
double r = Value(x,y,op);
Num.push(r);
while( lp(Op.get()) > rp(str.charAt(i)) || !Op.isEmpty())
{
System.out.println("6");
char op2 = Op.pop();
double y2 = Num.pop();
double x2 = Num.pop();
double r2 = Value(x2,y2,op2);
Num.push(r2);
}i++;
}
else i++;
}
double result = Num.pop();
return result;



}

public static double toNum(String str)//将临时栈里的数字字符转换为数字
{
SeqStack<Character> stack = new SeqStack<Character>();
int i = 0;
stack.push(str.charAt(i));
int j = 0, k = 0;
double num = 0;
while(!stack.isEmpty())
{
if(stack.pop()=='.')
{
k=j;continue;
}
else num+= stack.pop()*Math.pow(10,j);j++;
}
return num;
}

public static double Value(double x,double y,char op)
{
double result = 0;
switch(op)
{
case '+': result = x+y;break;
case '-': result = x-y;break;
case '*': result = x*y;break;
case '/': if(y==0){
System.out.println("输入有误");break;
}
else result = x/y;break;
}
return result;
}
}
//这个程序其他地方应该都没错,主要是Ergo里的while循环是有问题的,我给大家一组输入输出
输入:12+3-4
输出:1
2
3
2
3
2
不知道为什么,自己就中断循环了,就算遇到运算符if不执行,那也应该无限循环啊,为什么就自己中断循环了

解决方案 »

  1.   

    public class Demo {
    public static void main(String[] args)
    {
    System.out.println("请输入您要计算的表达式:");
    Scanner in = new Scanner(System.in);
    String s = in.nextLine();   //创建字符串接收输入的表达式
    String str = Check(s);

    double result = Ergo(str);
    System.out.println(result); }

    public static String Check(String str) //剔除符号,字母
    {
    String expstr = "";
    int i = 0;
    while (i<str.length())
    {
    char ch = str.charAt(i);
    if (i<str.length() && ch>= '(' && ch<= '9'||ch=='#'){ expstr += ch; }
    i++;
    }
    return expstr;

    }

    public static int lp(char op)//左操作符优先级
    {
    switch(op)
    {
    case '+':
    case '-':return 3;
    case '*':
    case '/':return 5;
    case '(':return 1;
    case ')':return 6;
    case '#':return 0;
    default:return -1;
    }
    }

    public static int rp(char op)//右操作符优先级
    {
    switch(op)
    {
    case '+':
    case '-':return 2;
    case '*':
    case '/':return 4;
    case '(':return 6;
    case ')':return 1;
    case '#':return 0;
    default:return -1;
    }
    }

    public static double Ergo(String str)//三栈遍历计算得值
    {
    SeqStack<Double>    Num= new SeqStack<Double>();//操作数栈,double类型;
    SeqStack<Character> Op = new SeqStack<Character>();//操作符栈,char类型;
    SeqStack<Character> Tem= new SeqStack<Character>();//临时栈,char类型;
    String numstr = "";
    System.out.println("1");
    int i = 0;
    while(str.charAt(i)!='#')
    {
    System.out.println("2");
    if(str.charAt(i)>='0'&&str.charAt(i)<='9'||str.charAt(i)=='.'&&!Tem.isEmpty())//指向数字字符
    {
    System.out.println("3");
    Tem.push(str.charAt(i));//str顺序入临时栈
    i++;
    }
    else if( lp(Op.get()) < rp(str.charAt(i)) || Op.isEmpty() )
    {
    System.out.println("4");
    while(!Tem.isEmpty())
    {
    numstr += Tem.pop();
    }

    Num.push(toNum(numstr));//转换为浮点数   
    Op.push(str.charAt(i)); i++;
    }
    else if( lp(Op.get()) > rp(str.charAt(i)) )
    {
    System.out.println("5");
    char op = Op.pop();

    while(!Tem.isEmpty())
    {
    numstr += Tem.pop();
    }
    Num.push(toNum(numstr));//转换为浮点数   

    double y = Num.pop();
    double x = Num.pop();
    double r = Value(x,y,op);
    Num.push(r);
    while( lp(Op.get()) > rp(str.charAt(i)) || !Op.isEmpty())
    {
    System.out.println("6");
    char op2 = Op.pop();
    double y2 = Num.pop();
    double x2 = Num.pop();
    double r2 = Value(x2,y2,op2);
    Num.push(r2);
    }i++;
    }
    else i++;
    }
    double result = Num.pop();
    return result;



    }

    public static double toNum(String str)//将临时栈里的数字字符转换为数字
    {
    SeqStack<Character> stack = new SeqStack<Character>();
    int i = 0;
    stack.push(str.charAt(i));
    int j = 0, k = 0;
    double num = 0;
    while(!stack.isEmpty())
    {
    if(stack.pop()=='.')
    {
    k=j;continue;
    }
    else num+= stack.pop()*Math.pow(10,j);j++;
    }
    return num;
    }

    public static double Value(double x,double y,char op)
    {
    double result = 0;
    switch(op)
    {
    case '+': result = x+y;break;
    case '-': result = x-y;break;
    case '*': result = x*y;break;
    case '/': if(y==0){
    System.out.println("输入有误");break;
    }
    else result = x/y;break;
    }
    return result;
    }
    }
      

  2.   

    看着好晕,自从用Java之后没怎么写过类似这种手写的代码了,多用类库吧
    还是先变后缀式再计算思路比较清楚,下边是我以前写的一个可以参考一下
    public class Calculator {
    public static void main(String[] args) {
    System.out.println(calculate(toSuffix("2*(3+4)/(7-5)+6")));
    }

    static List<Object> toSuffix(String s) {
    Map<String, Integer> map = new HashMap<String, Integer>();
    map.put("+", 0);
    map.put("-", 0);
    map.put("*", 1);
    map.put("/", 1);
    map.put("(", -1);
    s = s.trim();
    List<Object> list = new ArrayList<Object>();
    String numberRegex = "\\d+";
    String operatorRegex = "\\+|\\-|\\*|/|(|)";
    String regex = numberRegex + "|[" + operatorRegex + "]";
    Matcher matcher = Pattern.compile(regex).matcher(s);
    Stack<String> stack = new Stack<String>();
    while (matcher.find()) {
    String t = matcher.group();
    if (t.equals("(")) {
    stack.push(t);
    } else if (t.equals(")")) {
    while (!stack.peek().equals("(")) {
    list.add(stack.pop());
    }
    stack.pop();
    } else if (map.containsKey(t)) {
    while (!stack.isEmpty() && map.get(t) <= map.get(stack.peek())) {
    list.add(stack.pop());
    }
    stack.push(t);
    } else {
    list.add(Double.parseDouble(t));
    }
    }
    while (!stack.isEmpty()) {
    list.add(stack.pop());
    }
    return list;
    }

    static double calculate(List<Object> list) {
    Stack<Double> stack = new Stack<Double>();
    for (Object obj : list) {
    if (obj instanceof Double) {
    stack.push((Double) obj);
    } else {
    double b = stack.pop();
    double a = stack.pop();
    if (obj.equals("+"))
    stack.push(a + b);
    if (obj.equals("-"))
    stack.push(a - b);
    if (obj.equals("*"))
    stack.push(a * b);
    if (obj.equals("/"))
    stack.push(a / b);
    }
    }
    return stack.pop();
    }
    }