【华为机试053】四则运算

题目描述:

请实现如下接口

    /* 功能:四则运算

     * 输入:strExpression:字符串格式的算术表达式,如: "3+2*{1+2*[-4/(8-6)+7]}"

         * 返回:算术表达式的计算结果

     */

    public static int calculate(String strExpression)

    {

        /* 请实现*/

        return 0;

    } 

约束:

  1. pucExpression字符串中的有效字符包括[‘0’-‘9’],‘+’,‘-’, ‘*’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。

  2. pucExpression算术表达式的有效性由调用者保证; 

Java实现:

import java.util.*;
 
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String str = sc.nextLine();
            Stack<Character> symbolStack = new Stack<Character>();
            String suffix = infixToSuffix(str, symbolStack);// 中缀表达式变为后缀表达式。
            System.out.println(calculateSuffix(suffix));// 计算后缀表达式的结果
        }
    }
  

    public static String infixToSuffix(String infix, Stack<Character> stack) {
        StringBuffer suffix = new StringBuffer();
        char[] ch = infix.toCharArray();
        for (int i = 0; i < ch.length; i++) {
            if (ch[i] == '(' || ch[i] == '[' || ch[i] == '{') {
                stack.push('(');
            } else if (ch[i] >= '0' && ch[i] <= '9')
                suffix.append(ch[i]);
            else if (ch[i] == '+' || ch[i] == '-')
            {
                if (ch[i] == '-')
                {
                    char before = ch[i - 1];
                    if (before == '(' || before == '[' || before == '{' || before == '+' || before == '-' || before == '*' || before == '/')
                        suffix.append(" ").append(ch[i]);
                    else {
                        while (!stack.isEmpty()) {
                            if (stack.peek() != '(')
                                suffix.append(" ").append(stack.pop());
                            else
                                break;
                        }
                        stack.push(ch[i]);
                        suffix.append(" ");
                    }
                } else {
                    while (!stack.isEmpty()) {
                        if (stack.peek() != '(') {
                            suffix.append(" ").append(stack.pop());
                        } else
                            break;
                    }
                    stack.push(ch[i]);
                    suffix.append(" ");
  
                }
            } else if (ch[i] == '*' || ch[i] == '/') {
                while (!stack.isEmpty()) {
                    char tmp = stack.peek();
                    if (tmp == '*' || tmp == '/') {
                        suffix.append(" ").append(stack.pop()).append(" ");
                    } else {
                        break;
                    }
                }
                stack.push(ch[i]);
                suffix.append(" ");
            } else {
                while (!stack.isEmpty()) {
                    char tmp = stack.pop();
                    if (tmp != '(') {
                        suffix.append(" ").append(tmp);
  
                    } else
                        break;
                }
            }
        }
        while (!stack.isEmpty()) {
            suffix.append(" ").append(stack.pop());
        }
        return suffix.toString();
    }
  
    public static int calculateSuffix(String suffix) {
        Stack<Integer> numStack = new Stack<Integer>();
        String[] str = suffix.split("\\s+");
        int n1, n2;
        for (int i = 0; i < str.length; i++) {
            String s = str[i];
            if (s.equals("+") || s.equals("-") || s.equals("*") || s.equals("/"))// 读到运算符则从栈中依次弹出两个数分别到n2和n1,然后以“X运算符Y”的形式计算机出结果,再压加栈S中;
            {
                n2 = numStack.pop();
                n1 = numStack.pop();
                if (s.equals("+"))
                    numStack.push(n1 + n2);
                else if (s.equals("-"))
                    numStack.push(n1 - n2);
                else if (s.equals("*"))
                    numStack.push(n1 * n2);
                else if (s.equals("/"))
                    numStack.push(n1 / n2);
            } else
                numStack.push(Integer.valueOf(s));// 遇到数字,便将它转换为数值压入栈中
        }
        return numStack.pop();// 将最终的结果弹出栈
    }
}

关键点:

中缀表达式与后缀表达式

中缀表达式就是运算符号在运算数中间的表达式,而后缀表达式就是运算符在运算数后面的表达式,还有前缀表达式也叫波兰式,运算符在运算数前面。计算机进行四则运算时后缀表达式会比中缀表达式方便许多。那么如何运算后缀表达式呢?
举个例子:计算9+(3-1)*3+6/2,转换为后缀表达式即为9 3 1 - 3 * + 6 2 / +(怎么转换后面再讲)。计算规则就是建立一个空栈,遇到数字就入栈,遇到符号就以符号前面的两个数为运算数进行计算(不好理解?请看图)

中缀表达式转换为后缀表达式

法则:
1)如果遇到数字,就直接将其输出;
2)如果遇到非数字,若栈为空或者该符号为左括号或者栈顶元素为括号,直接入栈;
3)如果遇到一个右括号,持续出栈并输出符号,直到栈顶元素为左括号,然后将左括号出栈(注意,左括号只出栈,不输出),右括号不入栈;
4)如果遇到运算符号且栈非空,查看栈顶元素,如果栈顶元素的运算优先级大于或者等于该运算符号,则持续出栈,直到栈顶元素优先级小于该运算符。最后将该元素入栈;
5)如果读到了输入的末尾,则将栈中所有元素依次弹出。

比如上面的9+(3-1)*3+6/2

1、遇到9 输出9,此时屏幕显示9,栈为空

2、遇到+号,此时栈空,直接入栈,此时屏幕显示9,栈元素只有一个+号

3、遇到左括号,直接入栈,此时屏幕显示9,栈元素为 + (

4、遇到3,输出3,此时屏幕显示9 3,栈元素为+ (

5、遇到-号,栈顶元素为(,入栈,此时屏幕显示9 3,栈元素为+ ( -

6、遇到1,输出1,此时屏幕显示9 3 1,栈元素为+ ( -

7、遇到),持续出栈,直到栈顶为(,并将(出栈但不输出,且)不入栈。此时屏幕显示9 3 1 -,栈元素为+

8、遇到*,此时栈顶元素为+,优先级大于栈顶元素,入栈,此时,屏幕显示9 3 1 -,栈元素为+ *

9、遇到3,输出3,此时屏幕显示9 3 1 - 3,栈元素为+ *

10、遇到+,此时栈顶元素为*,优先级大于等于+,出栈并输出,之后栈顶元素为+,优先级依然大于等于+,出栈并输出,此时栈空,+入栈,此时屏幕显示9 3 1 - 3 * +,栈元素为+

11、遇到6,输出6.此时屏幕显示9 3 1 - 3 * + 6,栈元素为+

12、遇到/,优先级大于栈顶元素,入栈,此时屏幕显示9 3 1 - 3 * + 6,栈元素为+ /

13、遇到2,输出2,此时屏幕显示9 3 1 - 3 * + 6 2

14、此时所有输入读取完毕,将栈中元素依次出栈至空,最后,屏幕显示9 3 1 - 3 * + 6 2 / +

以上就是中缀表达式转换为后缀表达式的全过程展示。

猜你喜欢

转载自blog.csdn.net/heyiamcoming/article/details/81065729