加减乘除运算(Java)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了加减乘除运算(Java)相关的知识,希望对你有一定的参考价值。
需要输入一串字符串,(当然都是数字和运算符号)
然后得出结果
麻烦了
需要输入的是比如: 83-32+83*32/4+3
然后直接得出答案。
//Eval.java
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
public class Eval
public int eval(String exp)
List<String> list = infixExpToPostExp(exp);//转化成后缀表达式
return doEval(list);//真正求值
//遇到操作符压栈,遇到表达式从后缀表达式中弹出两个数,计算出结果,压入堆栈
private int doEval(List<String> list)
Stack<String> stack = new Stack<String>();
String element;
int n1,n2,result;
try
for(int i = 0; i < list.size();i++)
element = list.get(i);
if(isOperator(element))
n1 = Integer.parseInt(stack.pop());
n2 = Integer.parseInt(stack.pop());
result = doOperate(n1,n2,element);
stack.push(new Integer(result).toString());
else
stack.push(element);
return Integer.parseInt(stack.pop());
catch(RuntimeException e)
throw new IllegalExpressionException(e.getMessage());
private int doOperate(int n1, int n2, String operator)
if(operator.equals("+"))
return n1 + n2;
else if(operator.equals("-"))
return n1 - n2;
else if(operator.equals("*"))
return n1 * n2;
else
return n1 / n2;
private boolean isOperator(String str)
return str.equals("+") || str.equals("-") || str.equals("*") || str.equals("/");
private List<String> infixExpToPostExp(String exp)//将中缀表达式转化成为后缀表达式
List<String> postExp = new ArrayList<String>();//存放转化的后缀表达式的链表
StringBuffer numBuffer = new StringBuffer();//用来保存一个数的
Stack<Character> opStack = new Stack<Character>();//操作符栈
char ch,preChar;
opStack.push('#');
try
for(int i = 0; i < exp.length();)
ch = exp.charAt(i);
switch(ch)
case '+':
case '-':
case '*':
case '/':
preChar = opStack.peek();
// 如果栈里面的操作符优先级比当前的大,则把栈中优先级大的都添加到后缀表达式列表中
while(priority(preChar) >= priority(ch))
postExp.add(""+preChar);
opStack.pop();
preChar = opStack.peek();
opStack.push(ch);
i++;
break;
case '(':
// 左括号直接压栈
opStack.push(ch);
i++;
break;
case ')':
// 右括号则直接把栈中左括号前面的弹出,并加入后缀表达式链表中
char c = opStack.pop();
while(c != '(')
postExp.add("" + c);
c = opStack.pop();
i++;
break;
// #号,代表表达式结束,可以直接把操作符栈中剩余的操作符全部弹出,并加入后缀表达式链表中
case '#':
char c1;
while(!opStack.isEmpty())
c1 = opStack.pop();
if(c1 != '#')
postExp.add("" + c1);
i++;
break;
//过滤空白符
case ' ':
case '\t':
i++;
break;
// 数字则凑成一个整数,加入后缀表达式链表中
default:
if(Character.isDigit(ch))
while(Character.isDigit(ch))
numBuffer.append(ch);
ch = exp.charAt(++i);
postExp.add(numBuffer.toString());
numBuffer = new StringBuffer();
else
throw new IllegalExpressionException("illegal operator");
catch(RuntimeException e)
throw new IllegalExpressionException(e.getMessage());
return postExp;
private int priority(char op)//定义优先级
switch(op)
case'+':
case'-':
return 1;
case'*':
case'/':
return 2;
case'(':
case'#':
return 0;
throw new IllegalExpressionException("Illegal operator");
Main.java 主函数所在类
public class Main
public static void main(String[] args)
try
InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader br=new BufferedReader(isr);
String exp=br.readLine();
int result = eval.eval(exp);
System.out.println(result);
catch (IOException e)
// TODO Auto-generated catch block
e.printStackTrace();
IllegalExpressionException异常类
public class IllegalExpressionException extends RuntimeException
public IllegalExpressionException()
public IllegalExpressionException(String info)
super(info);
参考技术A
//MathX.java
//表达式计算程序,绝对原创,
//与网上多数介绍的方法思路有点不同,
//与采用直接调用js的方法有根本的不同,
//支持 加 减 乘 除 幂 及 开方 运算,支持多级括号,
//本程序在 JDK1.6_11下开发,低版本JDK兼容性未测试,
import java.text.DecimalFormat;
public class MathX
public static void main(String[] args)
String str = "83-32+83*32/4+3";
double d = Calc.doCalc(str).getValue();
System.out.println(Calc.getStr()+"="+d);
// public static double calc(String s)
// return Calc.doCalc(s).getValue();
//
// public static String getStr()
// return Calc.getStr();
//
// public static String getFormatted()
// return Calc.getFormatted();
//
class Calc
private static final DecimalFormat df = new DecimalFormat("0.000000");
private static CalcCore co;
private static NumberWrapper result;
public static NumberWrapper doCalc(String exp)
co = new CalcCore(exp);
result = co.getResult();
return result;
public static String getFormatted()
return df.format(result.getValue());
public static String getStr()return co.toString();
//数据外覆类
class NumberWrapper
public static final int IaN = 0;
public static final int NaN = 1;
public static final NumberWrapper NOTHING = new NumberWrapper(Double.NaN,NumberWrapper.NaN);
private double value;
private int id;
public NumberWrapper(double v)
this(v,NumberWrapper.IaN);
public double getValue()
return id==NumberWrapper.IaN?value:Double.NaN;
public NumberWrapper(double v,int id)
this.value=v;
this.id=id;
// +-*/^~
public NumberWrapper calc(NumberWrapper x,char o)
if(this.NaN()||x.NaN())
return NumberWrapper.NOTHING;
return new NumberWrapper(calc(this.getValue(),x.getValue(),o));
private double calc(double a,double b,char o)
try
switch(o)
case OStack.PLUS:return a+b;
case OStack.SUBTRACT:return a-b;
case OStack.MULTIPLY:return a*b;
case OStack.DIVIDE:return a/b;
case OStack.POWER:return Math.pow(a, b);
case OStack.EVOLUTION:return Math.pow(a, 1d/b);
default:return Double.NaN;
catch(Exception e)
return Double.NaN;
public void setId(int id)this.id=id;
public boolean NaN()return id==NaN;
class CalcCore
private NStack n;
private OStack o;
private NumberWrapper result;
private String src;
public CalcCore(String src)
this.src=src;
rebuildString();
this.n=new NStack();
this.o=new OStack();
this.split();
this.calc();
public String toString()
return src;
private void rebuildString()
// (...)(...) --> (...)*(...)
src=src.replaceAll("\\\\)\\\\(",")"+OStack.MULTIPLY+"(");
// 1234(...) --> 1234*(...)
// (...)1234 --> (...)*1234
int i=0;
while(i<src.length())
if(hasNext(i+1)&&this.isNumber(i)&&src.charAt(i+1)==OStack.LB||
hasNext(i+1)&&this.isNumber(i+1)&&src.charAt(i)==OStack.RB)
src=src.substring(0,i+1)+OStack.MULTIPLY+src.substring(i+1);
++i;
//~1234 -->2~1234
//(~1234) -->(2~1234)
i=0;
while(i<src.length())
if(src.charAt(i)==OStack.EVOLUTION && pio(i))
src=src.substring(0,i)+"2"+src.substring(i);
++i;
private void calc()
for(int i=0; i<o.size(); i++)
char ch = o.get(i);
if(ch==OStack.EVOLUTION||ch==OStack.POWER)
NumberWrapper n0 = n.remove(i);
NumberWrapper n1 = n.remove(i);
ch = o.remove(i);
NumberWrapper rs;
if(ch==OStack.EVOLUTION)
rs = n0.calc(n1, ch);
else
rs = n1.calc(n0, ch);
n.insert(i, rs);
--i;
for(int i=o.size()-1; i>=0; i--)
char ch = o.get(i);
if(ch==OStack.MULTIPLY||ch==OStack.DIVIDE)
NumberWrapper n0 = n.remove(i+1);
NumberWrapper n1 = n.remove(i);
ch = o.remove(i);
NumberWrapper rs = n0.calc(n1, ch);
n.insert(i, rs);
for(int i=o.size()-1; i>=0; i--)
char ch = o.get(i);
NumberWrapper n0 = n.remove(i+1);
NumberWrapper n1 = n.remove(i);
ch = o.remove(i);
NumberWrapper rs = n0.calc(n1, ch);
n.insert(i, rs);
if(n.isEmpty()||n.size()>1)
result = NumberWrapper.NOTHING;
else
result = n.pop();
public NumberWrapper getResult()
return result;
private void split()
int cont;
for(int i=0; i<src.length(); i++)
char c = src.charAt(i);
switch(c)
case '(':
int pair = nextPair(src,i+1);
String sub = substring(i+1,pair);
n.push(Calc.doCalc(sub));
i=pair;
break;
case '-':
case '+':
boolean iso = pio(i);
cont = continuous(i+1);
if(iso)
n.push(new NumberWrapper(parse(substring(i,cont))));
i=cont-1;
break;
case '*':
case '/':
case '%':
case '^':
case '~':o.push(c);break;
default :
cont = continuous(i+1);
n.push(new NumberWrapper(parse(substring(i,cont))));
i=cont-1;
private double parse(String s)
try
return Double.parseDouble(s);
catch(Exception e)
return Double.NaN;
private String substring(int i, int cont)
return src.substring(i,cont);
private boolean hasNext(int i)
return src.length()>i;
private int continuous(int i)
while(hasNext(i) && isNumber(i))
++i;
return i;
private boolean pio(int i)
return i<1?true:OStack.iso(src.charAt(i-1));
public boolean isNumber(int pos)
char c = src.charAt(pos);
return c<='9' && c>='0' || c=='.';
public int nextPair(String src,int pos)
int inner = 0;
int len = src.length();
for(int i=pos; i<len; i++)
char c = src.charAt(i);
if(c==')')
if(inner==0)return i;
else --inner;
else if(c=='(')++inner;
return -1;
//操作符栈(半角符号)
class OStack
public static final char PLUS = '+';
public static final char SUBTRACT = '-';
public static final char MULTIPLY = '*';
public static final char DIVIDE = '/';
public static final char POWER = '^';
public static final char EVOLUTION = '~';
public static final char LB = '(';
public static final char RB = ')';
public static boolean iso(char c)
switch(c)
case PLUS:
case SUBTRACT:
case MULTIPLY:
case DIVIDE:
case POWER:
case EVOLUTION:
case LB:
// case RB:
return true;
return false;
public boolean hasNext(int i)
return this.length>i+1;
private char[] stack;
private int length;
public OStack()
this.stack=new char[0];
this.length=0;
public boolean isEmpty()
return length==0;
public void push(char c)
char[] tmp = new char[this.length+1];
tmp[0]=c;
System.arraycopy(stack, 0, tmp, 1, length);
++length;
this.stack=tmp;
public char pop()
if(this.isEmpty())throw new StackOverflowError();
char c = stack[0];
char[] tmp = new char[length-1];
System.arraycopy(stack, 1, tmp, 0, tmp.length);
--length;
this.stack=tmp;
return c;
public char remove(int i)
if(i<0||i>=length)throw new StackOverflowError();
char[] tmp = new char[length-1];
System.arraycopy(stack,0,tmp,0,i);
System.arraycopy(stack,i+1,tmp,i,tmp.length-i);
this.length--;
char n=stack[i];
this.stack=tmp;
return n;
public void insert(int i,char n)
if(i<0||i>length)throw new StackOverflowError();
char[] tmp = new char[length+1];
System.arraycopy(stack,0,tmp,0,i);
System.arraycopy(stack,i,tmp,i+1,this.length-i);
tmp[i]=n;
this.length++;
this.stack=tmp;
public char get(int i)
return this.stack[i];
public int size()return this.length;
//数据栈
class NStack
private NumberWrapper[] stack;
private int length;
public NStack()
this.stack=new NumberWrapper[0];
this.length=0;
public NStack(NStack n)
this.stack=new NumberWrapper[n.length];
this.length=n.length;
for(int i=0; i<length; i++)
this.stack[i]=n.stack[i];
public void push(NumberWrapper d)
NumberWrapper[] tmp = new NumberWrapper[this.length+1];
System.arraycopy(stack, 0, tmp, 1, this.length);
tmp[0] = d;
this.stack=tmp;
this.length++;
public NumberWrapper pop() throws StackOverflowError
if(this.isEmpty())throw new StackOverflowError();
NumberWrapper[] tmp = new NumberWrapper[this.length-1];
System.arraycopy(stack, 1, tmp, 0, tmp.length);
NumberWrapper d = stack[0];
this.stack=tmp;
this.length--;
return d;
public NumberWrapper get(int i)
return this.stack[i];
public NumberWrapper remove(int i)
if(i<0||i>=length)throw new StackOverflowError();
NumberWrapper[] tmp = new NumberWrapper[length-1];
System.arraycopy(stack,0,tmp,0,i);
System.arraycopy(stack,i+1,tmp,i,tmp.length-i);
this.length--;
NumberWrapper n=stack[i];
this.stack=tmp;
return n;
public void insert(int i,NumberWrapper n)
if(i<0||i>length)throw new StackOverflowError();
NumberWrapper[] tmp = new NumberWrapper[length+1];
System.arraycopy(stack,0,tmp,0,i);
System.arraycopy(stack,i,tmp,i+1,this.length-i);
tmp[i]=n;
this.length++;
this.stack=tmp;
public boolean isEmpty()
return this.length==0;
public int size()return this.length;
本回答被提问者采纳 参考技术B 大体就跟 fantasy316 写的大同小异,使用堆栈做。一个一个字符读,操作符入栈,操作数直接写出,然后根据运算优先级写出符号,建立后缀表达式;再根据后缀表达式利用栈结构算出最后结果。 参考技术C 应该是JS的吧 不与WEB交互计算的话估计取值有点麻烦因为不能判断你的值是多少位 运算符号在什么地方
当然了要真不是WEB的截面的话 可以把输入的转化成ASCII进行比较
分解出是值还是运算符 然后进行操作
不过这个判断是有的写了 参考技术D class test3
public static void main(String[] args)throws Exception
try
System.out.println(myMath("(12+15)*56+45681"));
catch(javax.script.ScriptException se)
public static double myMath(String s) throws javax.script.ScriptException
Object o = new javax.script.ScriptEngineManager().getEngineByName("JavaScript").eval(s);
return (Double)o;
以上是关于加减乘除运算(Java)的主要内容,如果未能解决你的问题,请参考以下文章