加减乘除运算(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);
}
}
//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;}
}
因为不能判断你的值是多少位 运算符号在什么地方
当然了要真不是WEB的截面的话 可以把输入的转化成ASCII进行比较
分解出是值还是运算符 然后进行操作
不过这个判断是有的写了
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;
}
}