对于没有涉及到高级计算方法的同学们来说,觉得计算器的算法简单。其实不是的。科学领域的计算方法即不顺手也不容易使用,下面说下我在计算器制作过程中对算法心得。

表达式:(5+6)*4-9*(5/6)

这个为通常的表达式。我们用的最多的,这个叫做中缀表达式。但是这个算式在计算器中式难以解析的。尤其在算式长度很长的时候

所以我们通常我把他转为后缀表达式,前缀就不说了,咱PASS,不怎么用,还是后缀好哇。

后缀:56+4*956/*-

童鞋们有没发现这2中表达式的区别么,有么发现后缀的好处。

后缀3大特点:1.运算操作数顺序和中缀一样

    2.没有刮号

    3.不存在优先级

我们惊奇的发现这样的表达式是多么的好解析啊,尤其是在计算器中。


所以我们一般要转后缀表达式用来科学计算哦

至于怎么中转后缀呢?

方法有一些,比较常用的就是用栈机制

初始化2个空堆栈,都来不同时候存取。

一个数组或者STRING用来存结果集。

一:中转后

1.先遍历中缀字符

2.如果是操作数把他放入结果集

3.如果是操作符,弹出(POP),直到遇见刮号或优先级低的操作符,压入堆栈中。

4.遇到(,直接压入栈

5.遇到),在遇到(前面弹出所有操作符,在添加到结果集

6,遍历完毕,弹出所有操作符。添加。

二:后缀求值

1.遍历中缀字符

2.如果是操作数把他放入新堆栈

3.如果是操作符,弹出2个操作数执行操作

4,得到的值继续压入堆栈,求值,循环

5,最后剩一下一个值就是结果了。

 

三:

附加代码把。。


public double chunshi(String f) { 
         char c;//用于fortogo中字符的识别和比较 
         StringBuffer sb = new StringBuffer(f);//转换StringBuffer实现在运算式后面增加标记@的功能 
         sb.append('@'); 
         String fortogo = sb.toString();//在次转换成String用来提取单个字符 
         char[] anArray;//用来存取从栈中取出的数据, 
         anArray = new char[100];//不初始化字符不能存储。。。 
         Stack<Character> mystack = new Stack<Character>();//定义栈用来存运算符的栈 
         while (fortogo.charAt(allspc) != '@') {//遍历fortogo直到@,也就是最后的标记 
             c = fortogo.charAt(allspc);//把当前的值给C用于判断 
             switch (c) {//判断C 
                 case '('://是不是( 
                     mystack.push(new Character(c));//是的话入栈 
                     allspc++;//字符标记下移 
                     break;//跳出 
                 case ')'://实现()的优先级 
                     while (mystack.peek().charValue() != '(') {//保证()中有数据,弹出()中的运算符 
                         anArray[arrspc++] = mystack.pop().charValue(); 
                     } 
                     mystack.pop(); 
                     allspc++; 
                     break; 
                 case '+'://加减运算的一样。 
                 case '-': 
                     while (!mystack.empty() && mystack.peek().charValue() != '(') {//不为空,而且上个不为(才入栈 
                         anArray[arrspc++] = mystack.pop().charValue();//取得符号前的值入数组 
                     } 

                     mystack.push(new Character(c));//遍历完毕全部弹出 
                     allspc++; 
                     break; 
                 case '*'://乘除一样。。 
                 case '/': 
                     while (!mystack.empty() && (mystack.peek().charValue() == '*' ||//用于限定的入栈条件 
                             mystack.peek().charValue() == '/')) { 
                         anArray[arrspc++] = mystack.pop().charValue(); 
                     } 
                     mystack.push(new Character(c)); 
                     allspc++; 
                     break; 
                 default: 
                     while ((c >= '0' && c <= '9') || c == '.') {//当输入为数字和.是存入数组 
                         anArray[arrspc++] = c; 
                         allspc++; 
                         c = fortogo.charAt(allspc); 
                     } 
                     anArray[arrspc++] = '#';//在数字后面加上#做标记 
                     break; 
             } 
         } 
         while (!(mystack.empty())) {//把运算符合数据做好联系,好取值 
             anArray[arrspc++] = mystack.pop().charValue(); 
         } 
         allspc = 0;//初始化数组标记 
         int count;//用于double 型的数据提取 
         double a;//用于提取运算符对应的数据 
         double b; 
         double d;//用于计算一步的值 
         Stack<Double> mystack1 = new Stack<Double>();//定义double栈用来存新的值 
         while (allspc < arrspc) {//遍历数组 
             c = anArray[allspc]; 
             switch (c) {//取值并计算 
                 case '+': 
                     a = mystack1.pop().doubleValue(); 
                     b = mystack1.pop().doubleValue(); 
                     BigDecimal b1 = new BigDecimal(Double.toString(a)); 
                     BigDecimal b2 = new BigDecimal(Double.toString(b)); 
                     d = b1.add(b2).doubleValue(); 
                     mystack1.push(new Double(d));//运算完的值在次存入栈中 
                     allspc++; 
                     break; 

                 case '-': 
                     a = mystack1.pop().doubleValue(); 
                     b = mystack1.pop().doubleValue(); 
                     BigDecimal b11 = new BigDecimal(Double.toString(b));//math中用于精度的调整下面一样 
                     BigDecimal b22 = new BigDecimal(Double.toString(a)); 
                     d = b11.subtract(b22).doubleValue(); 
                     mystack1.push(new Double(d)); 
                     allspc++; 
                     break; 

                 case '*': 
                     a = mystack1.pop().doubleValue(); 
                     b = mystack1.pop().doubleValue(); 
                     BigDecimal b111 = new BigDecimal(Double.toString(a)); 
                     BigDecimal b222 = new BigDecimal(Double.toString(b)); 
                     d = b111.multiply(b222).doubleValue(); 
                     mystack1.push(new Double(d)); 
                     allspc++; 
                     break; 

                 case '/': 
                     a = mystack1.pop().doubleValue(); 
                     b = mystack1.pop().doubleValue(); 
                     try { 
                         if (a == 0) { 
                             throw new Exception(); 
                         } 
                         d = b / a; 
                         mystack1.push(new Double(d)); 
                         allspc++; 
                     } catch (Exception e) { 
                         jTextField1.setText("除数不能为0"); 
                         textshow = ""; 
                         allspc = 0; 
                         arrspc = 0; 
                         kuanum = 0; 
                         haonum = 0; 
                         Numcount = false; 
                         Symbolcount = false; 
                         Symbolcount2 = false; 
                         Numcount2 = false; 
                         Numcount3 = false; 
                         diancount = 0; 
                         diancount2 = false; 
                         textshow2 = ""; 
                         denone = 0; 
                         dentwo = 0; 
                         symbolastrict = true; 
                         zerocount = 0; 
                         denkua = ""; 
                         dencount = false; 
                     } 
                     break; 
                 default: 
                     d = 0;//用于取得一个完成的数据 
                     count = 0; 
                     while ((c >= '0' && c <= '9')) { 
                         d = 10 * d + c - '0'; 
                         allspc++; 
                         c = anArray[allspc]; 
                     } 
                     if (c == '.') {//让.能插入数据中 
                         allspc++; 
                         c = anArray[allspc]; 
                         while ((c >= '0' && c <= '9')) { 
                             count++; 
                             d = d + (c - '0') / Math.pow(10, count); 
                             allspc++; 
                             c = anArray[allspc]; 
                         } 
                     } 
                     if (c == '#') {//遇到#就完成一个数据的提取在存入 
                         mystack1.push(new Double(d)); 
                     } 
                     allspc++; 
                     break; 
             } 
         } 
         return (mystack1.peek().doubleValue()); 
     }