栈的应用之算数表达式

对于一个算术表达式,我们可以用栈这种数据结构来计算它的值,也就是说可以将一个标准形式的表达式(或叫中缀表达式)转换成后缀表达式,并坚持普通的优先级法则,将一般问题浓缩成小规模问题,我们假设有运算符 + - * / ( )中缀表达式是合法的,比如 :a + b * c + ( d * e + f )  * g 转换成后缀表达式 a b c * + d e * f + g * + ,对表达式进行遍历,当读到数字字符时,把它添加到后缀表达式中,当第一次读到运算符时,将它入栈,如果栈顶元素的的优先级高于后面读到的运算符的优先级时,则该运算符入栈,否则将栈顶元素出栈。为了理解这种机制,我们把上述中缀表达式转换成后缀表达式。

首先,a被读入,把它添加到后缀表达式中,然后读到 + ,将它入栈,接着b读入并添加到后缀表达式中,然后读到 * ,此时栈顶元素是+,优先级低于*,所以将 * 入栈,接着c读入并输出到后缀表达式中。然后又读到 + , 此时我们检查一下栈,需要将 * 弹出放到后缀中,栈顶元素变成了 + ,不高于刚读到的 + ,所以将栈顶元素 + 弹出到后缀中,并将刚读到的 + 放到栈顶,此时的后缀表达式是 : a b c * + .下一个读到的的符号是 ( ,由于具有最高的优先级,所以它入栈,然后 d读入并输出到后缀中。继续进行,我们又读到 * 除非正在处理右括号 ) ,否则左括号 ( 不会从栈中弹出,所以 * 没有弹出,下一个是 e ,它被读入并输出到后缀中,。此时的后缀表达式是a b c * + d e.再往后读到 + 我们栈顶元素 * 弹出,然后将 + 入栈,然后我们读到 f 并输出到后缀中。接下来我们读到 ) 因此将栈顶元素直到 ( ,此时后缀表达式为 a b c * + d e * f + 下面又读到 * 该运算符入栈,最后g被读入并输出到后缀中。现在中缀表达式已经被遍历完了,我们将栈中所有元素弹出,直到栈变为空栈。最后后缀表达式为a b c * + d e * f + g * +  这样就得到了我们需要的结果了。下面在Java代码中实现具体的过程(myString为中缀表达式,suffixExpression为后缀表达式,集合list实现栈的结构)。

</pre><pre name="code" class="java">for(int i =0;i<myString.length();i++){
                    if(myString.charAt(i) == '+'||myString.charAt(i) == '-'){                       //将加减添加到后缀表达式
                        if(list.isEmpty()){
                            list.add(myString.charAt(i));
                        }else {
                            while (!list.isEmpty()) {
                                if(!(suffixExpression.charAt(suffixExpression.length()-1) == ' '))
                                    suffixExpression += " ";
                                suffixExpression += list.get(list.size() - 1);
                                suffixExpression += " ";
                                list.remove(list.size() - 1);
                            }
                            list.add(myString.charAt(i));
                        }
                    }else if(myString.charAt(i) == '*'||myString.charAt(i) == '/'){                 //将乘除添加到后缀表达式
                        if(list.isEmpty()){
                            list.add(myString.charAt(i));
                        }else if(list.get(list.size() - 1) == '*'
                                ||list.get(list.size() - 1) == '/') {
                            do {
                                if(!(suffixExpression.charAt(suffixExpression.length()-1) == ' '))
                                    suffixExpression += " ";
                                suffixExpression += list.get(list.size() - 1);
                                suffixExpression += " ";
                                list.remove(list.size() - 1);
                                if(list.isEmpty())
                                    break;
                            }while (list.get(list.size() - 1) == '+'
                                    ||list.get(list.size() - 1) == '-');
                            list.add(myString.charAt(i));
                        }
                        else {
                            list.add(myString.charAt(i));
                        }
                    }else {                                                                         //将数字添加到后缀表达式
                        suffixExpression += myString.charAt(i);
                        if(i+1<myString.length() && !(myString.charAt(i+1) == '.')
                                && !(myString.charAt(i+1)>=48 && myString.charAt(i+1)<=57))
                            suffixExpression += " ";
                    }
                }
                while(!list.isEmpty()){                                                             //所有符号出栈
                    if(!(suffixExpression.charAt(suffixExpression.length()-1) == ' '))
                        suffixExpression += " ";
                    suffixExpression += list.get(list.size() - 1);
                    list.remove(list.size() - 1);
                }
                System.out.println("000000");
                System.out.println(suffixExpression);
                for(int i = 0;i<suffixExpression.length();i++){
                    if(suffixExpression.charAt(i) == '+') {
                        int j = i-2;
                        while(suffixExpression.charAt(j) != ' '){                                   //寻找第一个空格
                            if(j == 0)
                                break;
                            else{
                                j--;
                            }
                        }
                        if(j == 0){
                            result = Double.parseDouble(suffixExpression.substring(j,i-1));         //当输入不完整时   ??? +
                            suffixExpression = String.valueOf(result);
                            break;
                        }else
                            num1 = Double.parseDouble(suffixExpression.substring(j + 1, i - 1));    //获取第一个数
                        System.out.println(num1);
                        int n = j;  j--;                                                            //标记第一个空格的位置


                        while(suffixExpression.charAt(j) != ' '){                                   //寻找第二个空格
                            if(j == 0)
                                break;
                            else
                                j--;
                        }
                        if(j == 0) {                                                                //运算结束
                            result = Double.parseDouble(suffixExpression.substring(j,n));
                            System.out.println(result);
                            result = result + num1;
                            System.out.println(result);
                            if(i == suffixExpression.length()-1) {
                                suffixExpression = suffixExpression.replace(suffixExpression.substring(j), String.valueOf(result));
                                System.out.println(suffixExpression);
                                break;
                            }
                            suffixExpression = suffixExpression.replace(suffixExpression.substring(j,i+1), String.valueOf(result));
                        }else{
                            result = Double.parseDouble(suffixExpression.substring(j+1,n));         //寻找第二个数
                            result += num1;
                            System.out.println(result);
                            suffixExpression = suffixExpression.replace(suffixExpression.substring(j+1,i+1), String.valueOf(result));
                            System.out.println(suffixExpression);
                        }
                        System.out.println(suffixExpression);
                        i = 0;
                    } else if(suffixExpression.charAt(i) == '-') {
                        int j = i-2;
                        while(suffixExpression.charAt(j) != ' '){                                   //寻找第一个空格
                            if(j == 0)
                                break;
                            else{
                                j--;
                            }
                        }
                        if(j == 0){
                            result = Double.parseDouble(suffixExpression.substring(j,i-1));         //当输入不完整时   ??? +
                            suffixExpression = String.valueOf(result);
                            break;
                        }else
                            num1 = Double.parseDouble(suffixExpression.substring(j + 1, i - 1));    //获取第一个数


                        int n = j;  j--;                                                            //标记第一个空格的位置


                        while(suffixExpression.charAt(j) != ' '){                                   //寻找第二个空格
                            if(j == 0)
                                break;
                            else
                                j--;
                        }
                        if(j == 0) {                                                                //运算结束
                            result = Double.parseDouble(suffixExpression.substring(j,n));
                            result -= num1;
                            if(i == suffixExpression.length()-1) {
                                suffixExpression = suffixExpression.replace(suffixExpression.substring(j), String.valueOf(result));
                                break;
                            }
                            suffixExpression = suffixExpression.replace(suffixExpression.substring(j,i+1), String.valueOf(result));
                        }else{
                            result = Double.parseDouble(suffixExpression.substring(j+1,n));         //寻找第二个数
                            result -= num1;
                            suffixExpression = suffixExpression.replace(suffixExpression.substring(j+1,i+1), String.valueOf(result));
                        }
                        i = 0;
                    } else if(suffixExpression.charAt(i) == '*') {
                        int j = i-2;
                        while(suffixExpression.charAt(j) != ' '){                                   //寻找第一个空格
                            if(j == 0)
                                break;
                            else{
                                j--;
                            }
                        }
                        if(j == 0){
                            result = Double.parseDouble(suffixExpression.substring(j,i-1));         //当输入不完整时   ??? +
                            suffixExpression = String.valueOf(result);
                            break;
                        }else
                            num1 = Double.parseDouble(suffixExpression.substring(j + 1, i - 1));    //获取第一个数
                        System.out.println(num1);
                        int n = j;  j--;                                                            //标记第一个空格的位置


                        while(suffixExpression.charAt(j) != ' '){                                   //寻找第二个空格
                            if(j == 0)
                                break;
                            else
                                j--;
                        }
                        if(j == 0) {                                                                //运算结束
                            result = Double.parseDouble(suffixExpression.substring(j,n));
                            result *= num1;
                            if(i == suffixExpression.length()-1) {
                                suffixExpression = suffixExpression.replace(suffixExpression.substring(j), String.valueOf(result));
                                break;
                            }
                            suffixExpression = suffixExpression.replace(suffixExpression.substring(j,i+1), String.valueOf(result));
                        }else{
                            result = Double.parseDouble(suffixExpression.substring(j+1,n));         //寻找第二个数
                            result *= num1;
                            suffixExpression = suffixExpression.replace(suffixExpression.substring(j+1,i+1), String.valueOf(result));
                        }
                        System.out.println(result);
                        System.out.println(suffixExpression);
                        System.out.println(suffixExpression);
                        i = 0;
                    } else if(suffixExpression.charAt(i) == '/') {
                        int j = i - 2;
                        while (suffixExpression.charAt(j) != ' ') {                                   //寻找第一个空格
                            if (j == 0)
                                break;
                            else {
                                j--;
                            }
                        }
                        if (j == 0) {
                            result = Double.parseDouble(suffixExpression.substring(j, i - 1));         //当输入不完整时   ??? +
                            suffixExpression = String.valueOf(result);
                            break;
                        } else {
                            num1 = Double.parseDouble(suffixExpression.substring(j + 1, i - 1));    //获取第一个数
                            if (num1 == 0) {
                                suffixExpression = "Error";
                                break;
                            }
                        }


                        int n = j;
                        j--;                                                            //标记第一个空格的位置


                        while (suffixExpression.charAt(j) != ' ') {                                   //寻找第二个空格
                            if (j == 0)
                                break;
                            else
                                j--;
                        }
                        if (j == 0) {                                                                //运算结束
                            result = Double.parseDouble(suffixExpression.substring(j, n));
                            result /= num1;
                            if (i == suffixExpression.length() - 1) {
                                suffixExpression = suffixExpression.replace(suffixExpression.substring(j), String.valueOf(result));
                                break;
                            }
                            suffixExpression = suffixExpression.replace(suffixExpression.substring(j, i + 1), String.valueOf(result));
                        } else {
                            result = Double.parseDouble(suffixExpression.substring(j + 1, n));         //寻找第二个数
                            result /= num1;
                            suffixExpression = suffixExpression.replace(suffixExpression.substring(j + 1, i + 1), String.valueOf(result));
                        }
                        i = 0;
                    }
                }
上面的代码只是实现了 + - *  / 四种运算,左右括号没有加进去,读者感兴趣的话可以自己去实现,并且 写的比较臃肿,运算符里边的内容完全可以写成一个方法。通过参数来实现不同运算。不妥之处望读者见谅,希望这些内容对大家能有所帮助。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值