package cal;
import java.util.*;
import javax.swing.*;public class Cal{
 private String input,inputcopy;
 private Stack stk1,stk2;
 private Vector vc1,vc2;
 private int result;
 
 Cal(){
  input=JOptionPane.showInputDialog(null,"Please input the expression:","mcalc",JOptionPane.INFORMATION_MESSAGE);
  inputcopy=input;
  StringTokenizer stinput=new StringTokenizer(input,"+-*/");
  StringTokenizer stinputcopy=new StringTokenizer(inputcopy,"0123456789");
  vc1=new Vector();
  vc2=new Vector();
while(stinput.hasMoreTokens()){
vc1.add(stinput.nextElement());
}
while(stinputcopy.hasMoreTokens()){
vc2.add(stinputcopy.nextElement());
}
 }
 
  public void calculater(){
   int num1=0,num2=0,num3=0,temp=0,k=0;
   try{
   result=Integer.parseInt((String)vc1.get(0));
   }catch(Exception e){e.printStackTrace();}
   int vc2size=vc2.size();
   System.out.println("vc2.size() is:"+vc2size);
   for(int i=0;i<vc2.size();i++){
   System.out.println(i);
   try{
   //第i个符号为*/运算形式为连乘或者连除的时候
   if((!((String)vc2.get(i)).equals("+"))&&(!((String)vc2.get(i)).equals("-"))){
   if(((String)vc2.get(i)).equals("*")){
   result*=Integer.parseInt((String)vc1.get(i+1));
  
   }
   else{
   result/=Integer.parseInt((String)vc1.get(i+1));
  
   }
   }
   //第i个符号为+or -
   else{
   //第i个符号为最后一个符号了
   if((i+1)==vc2size){
   if(((String)vc2.get(i)).equals("+")){
   result+=Integer.parseInt((String)vc1.get(i+1));
   }
   else{
   result-=Integer.parseInt((String)vc1.get(i+1));
   }
  
   }
   //第i个符号不是最后一个符号,  即还有符号?
   else{
   //第i+1个符号是+—   
   if(((i+1)<vc2.size())&&((((String)vc2.get(i+1)).equals("+"))||(((String)vc2.get(i+1)).equals("-")))){
   if(((String)vc2.get(i)).equals("+")){
   result+=Integer.parseInt((String)vc1.get(i+1));
   }
   else{
   result-=Integer.parseInt((String)vc1.get(i+1));
   }
   }
   //第i+1个符号为*/
   if(((i+1)<vc2.size())&&((((String)vc2.get(i+1)).equals("*"))||(((String)vc2.get(i+1)).equals("/")))){
   k=i;
   temp=Integer.parseInt((String)vc1.get(i+1));
   //if is *
   if((i<vc2size)&&((String)vc2.get(i+1)).equals("*")){
   temp*=Integer.parseInt((String)vc1.get(i+2));
   i++;
   }
   //if is /
if((i<vc2size)&&((String)vc2.get(i+1)).equals("/")){
   temp/=Integer.parseInt((String)vc1.get(i+2));
   i++;
   }
   //is not the last 
   while(i!=vc2size){
   //if next is * or /
   while((i<(vc2size-1))&&(((String)vc2.get(i+1)).equals("*"))||(((String)vc2.get(i+1)).equals("/"))){
   if(((String)vc2.get(i+1)).equals("*")){
   temp*=Integer.parseInt((String)vc1.get(i+2));
   i++;
   }
if(((String)vc2.get(i+1)).equals("/")){
   temp/=Integer.parseInt((String)vc1.get(i+2));
   i++;
   }
   }
if((i<(vc2size-1))&&(((String)vc2.get(i+1)).equals("+"))||(((String)vc2.get(i+1)).equals("-"))){
   if(((String)vc2.get(i+1)).equals("+")){
   result+=temp;
   i++;
   break;
   }
if(((String)vc2.get(i+1)).equals("-")){
   result-=temp;
   i++;
   break;
   }
}
}
if(i==vc2size){
   if(((String)vc2.get(k)).equals("+")){
   result+=temp;
   }
   if(((String)vc2.get(k)).equals("-")){
   result-=temp;
   }
}
  
  
  
   }
   }
  
   }
   }catch(Exception ee){ee.printStackTrace();} 
   }
   //System.out.println(result);
      JOptionPane.showMessageDialog(null,result+"","Answer:",JOptionPane.WARNING_MESSAGE);
  }
 public static void main(String args[]){
  new Cal().calculater();
 }
 
}

解决方案 »

  1.   

    刚才找了几段代码,可是还是没有搞明白怎么回事
    编译原来偶没有学过
    递归的方法偶也想过,但是终于还是因为没有想透而放弃了
    sigh
    本来以为很简单的
    竟然也这么复杂
    打消偶学习java的积极性阿
    ft
      

  2.   

    没有必要自己写一个,expression是任何Computer language的基本元素,可以使用anltr非常容易的实现之,如下:
    primitiveElement
    : NUM 
    | LPAREN 
    ( PLUS 
    | MINUS 

    NUM RPAREN 
    | ( LPAREN expression RPAREN ) 
    ;
    expression
    : multiplyingExpression ( ( PLUS 
    | MINUS 

    multiplyingExpression )* 
    ;
    multiplyingExpression
    : primitiveElement ( ( TIMES 
    | DIV 

    primitiveElement )* 
    ;
      

  3.   

    billh2003(比尔) :怎么看不懂阿?anltr是什么阿?
    水平差,不好意思
      

  4.   

    : hlding(淋东) :谢谢你啦
      

  5.   

    这个是很容易的事情:
    2个栈:A B   从左向右扫描
    原则:1.碰到数字,直接入A栈
          2.如果是符号(只考虑+-*/(),优先级别为'(','*' '/','+' '-',')' 逗号分隔不同级别,*/为同一级别,+-也为同一级别)则判断B栈栈顶的元素是否优先级别大于目前符号,如果小于目前符号,则把目前符号入B栈,注意如果B栈为空则视为优先级别小于任何符号
          3.如果B栈顶符号优先级别大于目前扫描到的符号,则做如下处理:
             弹出A栈顶最上2个数字m,n,弹出B栈顶符号op,做运算m op n,结果压回A栈
            处理完成后回到2继续扫描比较,如果仍然B栈顶符号优先级别仍然大于等于当前符号,则继续按照3处理,直到小于。
          4.注意如果碰到(,是无条件压入B,但是碰到)以后,必须按照3的步骤把B中的符号一个一个弹出(当然同时弹出A里面的数据做相应运算)直到碰到(为止,记得要弹出()
    按照以上步骤,最后扫描完成以后,留在A栈内的一个数字(只有一个数字)就是结果
    如果中间发生任何错误,比如需要A提供最上2个数据时候却没有2个数据,或者扫描最后A多余2个数字,以及其他任何不符合我的情况的情况均说明表达式有错误累死我了,楼主给分啊!
      

  6.   

    其实只要知道了规律就很简单了,我原来就写过科学计算器(用Delphi写的),比你这个复杂多了,基本上实现了高中使用的科学计算器80%的功能。
    我只简单讲下规律:
       首先不考虑括号的情况下,其实你最多只要维护三个数值和两个符号,这种情况就是:
         a+b*c 这样你就根本不用知道下个数值是什么,就可以把上面的替换成a+b(此时的b=b+c)
       如此下去就可以了,当然你必须要自已来维护他们的优先级。
      同样: 如果是a+b+c 等价为 a+b ( a=a+b,b=c)  
             如果 a*b  就直接把a 等为a*b了。这样其实你的程序只要有5个变量,3个存储数值,2个用来存储符号就可以。
      如果要考虑括号的话,你就要使用栈了,当遇到‘(’时就要入栈了,入栈也要先按照上面的原则处理后再入,遇到‘)’就出栈,使用后进先出法,直到栈为空,你就算完了。
      其中计算会用到递归(记得当时我就用了),按照上面的方法一定行的,我当时就是这样做的。
      

  7.   

    qhgary(Shining)谢谢了,会给你分的,偶光划逻辑图就划了好几个了,就是写程序的时候偶尔搞错一点就完了,ft
      

  8.   

    qhgary(Shining) 说的很对。用两个堆来做。
      

  9.   

    正好我机器上有写过的一个程序:主函数里面有演示: 你可以直接调用Caculater类
    比如计算1+2*3的结果:
    String s="1+2*3";
    Caculater cacu = new Caculater(s);
    cacu.caculate()得到的就是计算结果
    import java.util.Stack;final class MyNum{
    private static char[]num = { '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' };
    //判断一个字符是否数字
    public final static boolean isDigit(char n) {
    for( int i = 0 ; i < 10 ; i++){
    if( num[i] == n ){
    return true;
    }
    }
    return false;
    }
    }//操作符对象
    final class Operator{
    //大小结果
    public static final int LARGER =  1;
    public static final int EQUAL  =  0;
    public static final int LESSER = -1;

    //操作符优先级列表
    private final static char[][]oper =
     {  {'+' , 1 },
    {'-' , 1 },
    {'*' , 2 },
    {'/' , 2 },

    {'{' , 10 },
    {'}' , 11 },
    {'[' , 12 },
    {']' , 13 },
    {'(' , 14 },
    {')' , 15 } };
    //判断一个字符是否操作符
    public final static boolean isOperator(char op){
    int length = oper.length;
    for( int i = 0 ; i < length ; i++ ) {
    if( oper[i][0] == op ){
    return true;
    }
    }
    return false;
    }

    //操作符匹配
    public final static boolean isMatching(char op){
    //优先级相同,但是不是同一个操作符
    if( getPriority( op ) > 9) {
    return true;
    }
    return false;
    }
    //是右则匹配符
    public final static boolean isRightMatching(char op){
    if( op=='}' || op==']' || op==')')
    {
    return true;
    }
    return false;
    }

    //取得操作符优先级
    public final static int getPriority(char op){
    int prior = -1;
    int length = oper.length;
    //查找操作符的优先级
    for( int i = 0 ; i <  length; i++ ) {
    if( oper[i][0] == op) {
    prior = oper[i][1];
    break;
    }
    }

    if( prior == -1 ) {
    throw new java.lang.IllegalArgumentException("操作符不存在!");
    }

    return prior;
    }
    //比较是否相同的操作符
    public final static boolean compare(char op1 , char op2 ) {
    if ( op1 == op2 )
    return true;
    return false;
    }
    //比较两个操作符的优先级
    public final static int comparePriority(char op1 , char op2 ) {
    int res = 0;

    int prior1 = -1;
    int prior2 = -1;

    prior1 = getPriority(op1);
    prior2 = getPriority(op2);

    if( prior1 > prior2){
    res = 1;
    }
    if( prior1 < prior2){
    res = -1;
    }

    return res;
    }

    }//表达式对象
    final class Expression{
    private String exp; //表达式
    private int offset = 0;
    private int oldoff = 0;

    public Expression(String s){
    exp =  s ;
    if( !checkRule() ){
    throw new IllegalArgumentException( "表达式不符合规则!" );
    }
    System.out.println( exp );
    }

    //检查是否符合表达式规则并去掉空格
    private boolean checkRule(){
    StringBuffer expbuf = new StringBuffer();
    int len = exp.length();
    for( int i = 0 ; i < len ; i++ ){
    char tep = exp.charAt( i );
    if( !Operator.isOperator( tep ) && !MyNum.isDigit( tep ) && tep != '.' && tep !=' ' ){
    return false;
    }
    if( tep != ' ' )
    expbuf.append( tep );
    }

    exp = new String( expbuf );
    return true;
    }

    //判断是否还有下一个操作符或则操作数
    public boolean hasNext(){
    if( offset >= exp.length() ){
    return false;
    }
    return true;
    }

    //取下一个操作数或则操作符
    public final String  nextOp(){
    String tep = null;

    while( offset < exp.length() ){
    //判断是否操作符
    if( Operator.isOperator( exp.charAt( offset++ ) ) ){
    break;
    }
    }

    //取操作数或符
    if( ( (offset - oldoff) > 1) ){
    tep = exp.substring( oldoff , --offset );//取数
    }
    else{
    tep = String.valueOf( exp.charAt( oldoff ) );//取符
    }
    oldoff = offset;

    return tep;
    }
    //取下一个操作符
    public final char nextMatch(){
    char tep = 0;
    for( int i=offset ; i < exp.length() ; i++ ){
    //判断是否操作符
    if( Operator.isOperator( exp.charAt( i ) ) ){
    tep = exp.charAt( i );
    break;
    }
    }
    return tep;
    }
    }         --------to be continue
      

  10.   


    //计算逻辑实现类
    final class Caculater{
    private Expression exp;//表达式对象
    private Stack op_stack  = new Stack();//操作符堆栈
    private Stack num_stack = new Stack();//操作数堆栈

    public Caculater(String s){
    num_stack.push( "#" );
    exp = new Expression( s );
    }

    //判断是否操作符
    public final boolean isOperator( Object op ){
    String tep = (String)op;
    if( tep.length() > 1 ){
    return false;
    }
    if( Operator.isOperator( tep.charAt( 0 ) ) ){
    return true;
    }
    return false;
    }

    //判断是否匹配符
    public final boolean isMatching( Object op ){
    if( isOperator( op ) ){
    if( Operator.isMatching( ( ( String ) op ).charAt( 0 ) ) ){
    return true;
    }
    }
    return false;
    }
    //判断是否右则匹配符
    public final boolean isRightMatching( Object op ){
    if( isOperator( op ) ){
    if( Operator.isRightMatching( ((String)op).charAt( 0) ) ){
    return true;
    }
    }
    return false;
    }
    //比较算符优先级别
    public final int comparePriority(Object op1 , Object op2 ) {
    char cop1 = ((String)op1).charAt(0);
    char cop2 = ((String)op2).charAt(0);
    return Operator.comparePriority( cop1 ,cop2 );
    }

    //计算结果
    public final double caculate(){
    Object curOper;

    while( num_stack.size() > 0 ){
    //取得当前操作数或操作符
    if( exp.hasNext() ){
    curOper = exp.nextOp();
    }else{//从操作数堆栈中取出操作数
    curOper = num_stack.pop();
    } /*
    //打印数据堆栈
    System.out.print("数据堆栈: ");
    for( int d = 0 ; d<num_stack.size() ; d++){
    System.out.print( num_stack.elementAt(d) );
    }
    System.out.println(); //打印操作符堆栈
    System.out.print("Operator stack: ");
    for( int d = 0 ; d < op_stack.size() ; d++){
    System.out.print(op_stack.elementAt(d));
    }
    System.out.println();
    */ //如果是操作数--------------------------------------------------------------------
    if( !isOperator( curOper ) ){
    if(exp.hasNext() ){//压入
    num_stack.push( curOper );
    continue;
    }else{
    Object op   = op_stack.pop()  ;//取出操作符
    Object num2 = num_stack.pop() ;//取出第二个操作数
    Object tres = logicCacu( num2 , curOper , op ) ;//按优先级计算 , num2在前curOper在后
    if( tres != null ){
    return Double.valueOf((String)tres).doubleValue();
    }
    }
    }else{
    //不是操作数----------------------------------------------------------------------
    //不是右则匹配符
    if( !isRightMatching( curOper ) ){
    op_stack.push( curOper );
    continue;
    }
    while( true ){//循环计算直到佐则匹配
    Object op  = op_stack.pop();//取出操作符
    //如果是佐则匹配符则不计算
    if( isMatching( op ) ){
    break;
    }
    //如果不是匹配符则进行计算(即为算符)
    Object num1 = num_stack.pop() ;//取出第一个操作数
    Object num2 = num_stack.pop() ;//取出第二个操作数
    Object tres = logicCacu( num2 , num1 , op ) ;//按优先级计算,num2在前num1在后有先后顺序
    if( tres != null ){
    return Double.valueOf((String)tres).doubleValue();
    }
    }//end while
    }
    }
    return 0;
    }
    //按优先级计算两个数的值,返回空时表示未计算完毕
    private final Object logicCacu(Object num1 , Object num2 , Object op ){

    if( op_stack.isEmpty() ){//如果操作符堆栈空
    //计算结果
    Object tres = cacu( num1 , num2 , op );
    //如果操作数栈剩下#并且没有操作符存在就返回结果
    if( ( ((String)num_stack.peek()).equals("#") ) && ( op_stack.size() == 0 ) ){
    return tres;
    }
    num_stack.push( tres );//压入操作数
    return null;
    }

    //取得下一个算符
    Object op_next = op_stack.pop(); //比较当前算符和下一个算符的优先级
    if( ( comparePriority( op , op_next ) != Operator.LESSER ) || isMatching( op_next ) ){//当前>=或下一个是匹配符
    //压入下一个操作符
    op_stack.push( op_next );
    //计算结果
    Object tres = cacu( num1 , num2 , op );
    //如果操作数栈剩下#并且没有操作符存在就返回结果
    if( ( ((String)num_stack.peek()).equals("#") ) && ( op_stack.size() == 0 ) ){
    return tres;
    }
    num_stack.push( tres );//压入操作数

    }else{//当前<=
    op_stack.push( op );
    //取出下一个操作数
    Object num3 = num_stack.pop();

    //计算结果
    Object tres = cacu( num3 , num1 ,  op_next );
    //如果操作数栈剩下#并且没有操作符存在就返回结果
    if( ( ( ( String )num_stack.peek()).equals( "#" ) ) && ( op_stack.size() == 0 ) ){
    return tres;
    }
    num_stack.push( tres );//压入操作数
    num_stack.push( num2 );//压入第一个操作数

    }
    return null;
    }

    //计算
    private final Object cacu(Object c1 , Object c2 , Object op){
    double rs = 0 ;
    //格式化
    java.text.NumberFormat nf = java.text.NumberFormat.getNumberInstance();
    nf.setGroupingUsed( false );
    nf.setMaximumFractionDigits(12);
    //取参数值
    double nc1 = Double.valueOf( (String)c1 ).doubleValue() ;
    double nc2 = Double.valueOf( (String)c2 ).doubleValue() ;
    String top = (String)op;
    //计算
    switch( top.charAt( 0 ) ){
    case '+' :
    rs = nc1 + nc2; break;
    case '-' : 
    rs = nc1 - nc2; break;
    case '*' : 
    rs = nc1 * nc2; break;
    case '/' : 
    rs = nc1 / nc2;
    }
    System.out.println( c1 +" "+op+" "+ c2+ " = "+ nf.format( rs ) );
    return nf.format( rs );
    }
    }public class Class1
    { public static void main (String[] args)
    {
    //String myc = "5+(3+2)*2";
    String myc = "2*(2+3)/2+3*7-4*8 ";
    //String myc = " 12.4567 * ( 2 + 3.1232 ) + { [ 1 + 3.232 * ( 10 + 6.89656 ) / (2+3.123) + 1.63 ] + 13.89 } ";
    //String myc = "(25.5/7+25.5+30.5)*2";
    //分离操作数或操作符
    //Expression exp = new Expression( myc );
    /*
    while( exp.hasNext() ){
    System.out.println("op::"+ exp.nextOp() );
    }
    */

    Caculater c = new Caculater(myc);

    System.out.println(""+myc+" = "+ c.caculate() );

    try{
    System.in.read();
    }catch(Exception e){
    }
    }
    }
      

  11.   

    看我的,简单明了,短小精悍!
    public class Compute
    {
        private String[] a={"10","/","2","*","(","7","+","2",")","*","3",")"};
        private int elementP = 0;
        private boolean isNum(String d)
        {
            boolean ok=true;
            try
            {
                double dd = Double.parseDouble(d);
            }catch(Exception ex)
            {
                ok = false;
            }
            return ok;
        }
        private void init(String s)
        {
            java.util.ArrayList aL = new java.util.ArrayList();
            String e ="";
            for(int i=0;i<s.length();i++)
                if (getSeq(""+s.charAt(i))<0)
                    e+=s.charAt(i);
                else
                {
                    aL.add(e);
                    aL.add(""+s.charAt(i));
                    e="";
                }
            aL.add(e); aL.add(")");
            a = new String[aL.size()];
            aL.toArray(a);
        }
        int getSeq(String s)
        {
            if (s.equals("+") || s.equals("-"))
                return 2;
            else
            if (s.equals("*") || s.equals("/"))
                return 3;
            if (s.equals(")"))
                return 1;
            if (s.equals("("))
                return 0;
            else
                return -1;
        }
        boolean isPop(String op,java.util.Stack opStack)
        {
            int s1 = getSeq(op);
            int s2 = getSeq((String) opStack.get(opStack.size()-1));
            if (s1==s2)
            {
                if (s1==0) return false;
                return true;
            }
            if (s1<s2)
                return true;
            return false;
        }
        String computeResult(Object n1,Object n2,Object op)
        {
            double d1 = Double.parseDouble((String)n1);
            double d2 = Double.parseDouble((String)n2);
            double d3 = 0;
            if (op.equals("+"))
                d3 = d1+d2;
            if (op.equals("-"))
                d3 = d1-d2;
            if (op.equals("*"))
                d3 = d1*d2;
            if (op.equals("/"))
                d3 = d2/d1;
            return ""+d3;
        }
        private String getNextElement()
        {
            if (elementP<a.length)
                return a[elementP++];
            else
                return null;
        }
        private String go()
        {
            java.util.Stack opStack=new java.util.Stack();
            java.util.Stack numStack=new java.util.Stack();
            opStack.push("(");
            while (true)
            {
                String element = getNextElement();
                System.out.print(element);
                if (element.equals("("))
                    element = go();
                if (isNum(element))
                    numStack.push(element);
                else
                {
                    while ( isPop(element,opStack) )
                    {
                        String result = computeResult(numStack.pop(),numStack.pop(),opStack.pop() );
                        numStack.push(result);
                    }
                    opStack.push(element);
                }
                if (element.equals(")"))
                    break;
            }
            return (String) numStack.pop();
        }
        public static void main(String[] args)
        {
            Compute t = new Compute();
            t.init("1+2+3");
            System.out.print("(");
            String s=t.go();
            System.out.println("="+s);
        }
    }