四则运算笔试题

方便日后回忆,立个flag。如果有好的解法,望各位不吝赐教。我这里采用的是将中缀表达式转换成后缀表达式。同时,要注意 负数 和 多位数的标记。
参考博客:https://www.cnblogs.com/dragondove/p/6445850.html

import java.util.Scanner;
import java.util.Stack;

/**
 * 四则运算
 * https://www.nowcoder.com/practice/9999764a61484d819056f807d2a91f1e?tpId=37&tqId=21273&tPage=3&rp=&ru=/ta/huawei&qru=/ta/huawei/question-ranking
 * Created by superhero on 2018/3/16.
 */
public class Main {
    public static void main(String[] args){
        Scanner scanner  = new Scanner(System.in);
        String strExpression = null;
        while (scanner.hasNext()){
            strExpression = scanner.nextLine();

            strExpression = strExpression.replaceAll("[\\[{]","(");
            strExpression = strExpression.replaceAll("[]}]",")");
            StringBuilder str = new StringBuilder();

            for(int i = 0;i < strExpression.length();i++){
                char var = strExpression.charAt(i);
                if(i == 0 && var == '-'){   //负号
                    str.append('0');
                    str.append(var);
                }
                else if(var == '-' && strExpression.charAt(i-1) == '(') {
                    str.append("(0");
                    str.append(var);        //将负数用括号包起来
                    i++;
                    while (strExpression.charAt(i) >= '0' && strExpression.charAt(i) <= '9')
                        str.append(strExpression.charAt(i++));
                    str.append(')');
                    str.append(strExpression.charAt(i));
                }
                else
                    str.append(var);
            }
            System.out.println(calculate(isPushStack(str.toString())));
        }
    }

    /**
     *  根据 后缀表达式 进行计算。
     *  法则:
     *      遇见数字就入栈,遇见符号,就与前两个数字进行运算。
     */
    public static int calculate(String strExpression){
        Stack<Integer> stack = new Stack<>();


        for(int i = 0;i < strExpression.length();i++){
            char var = strExpression.charAt(i);
            if(var == '(') {  //遇见数字
                StringBuilder num = new StringBuilder();
                i++;
                while(strExpression.charAt(i) != ')'){
                    num.append(strExpression.charAt(i));
                    i++;
                }
                stack.push(Integer.parseInt(num.toString()));
            }
            else{
                int count = 0;
                int var2 = stack.pop();
                int var1 = stack.pop();
                if(var == '+'){
                    count = var1 + var2;
                }
                else if(var == '-'){
                    count = var1 - var2;
                }
                else if(var == '*')
                    count = var1 * var2;
                else if(var == '/')
                    count = var1 / var2;
                stack.push(count);
            }
        }
        return stack.pop();
    }

    /**
     * 将 中缀表达式 转换成 后缀表达式
     * 法则:
     *     1)如果遇到数字,我们就直接将其输出。

           2)如果遇到非数字时,若栈为空或者该符号为左括号或者栈顶元素为括号,直接入栈。

           3)如果遇到一个右括号,持续出栈并输出符号,直到栈顶元素为左括号,然后将左括号出栈(注意,左括号只出栈,不输出),右括号不入栈

           4)如果遇到运算符号且栈非空,查看栈顶元素,如果栈顶元素的运算优先级大于或者等于该运算符号,则持续出栈,直到栈顶元素优先级小于该运算符。最后将该元素入栈

           5)如果我们读到了输入的末尾,则将栈中所有元素依次弹出。
     */
    private static String isPushStack(String strExpression){
        StringBuffer sb = new StringBuffer();   //保存转换后的后缀表达式
        Stack<Character> stack = new Stack<>();

        for(int i = 0;i < strExpression.length();i++){
            char var = strExpression.charAt(i);

            if(var >= '0' && var <= '9') {    //如果该符号为数字,直接输出
                sb.append('(');     //将数字用()包起来。以判断该数是个位数还是多位数
                while ( strExpression.charAt(i) >= '0' && strExpression.charAt(i) <= '9') {
                    sb.append(strExpression.charAt(i));
                    if( i < strExpression.length() - 1)
                        i++;
                    else
                        break;
                }
                sb.append(')');
                var = strExpression.charAt(i);
            }

            if((stack.isEmpty() && (var < '0' || var > '9')) || var == '(' || stack.peek() == '(' || stack.peek() == ')')    //如果栈为空、该符号为左括号、栈顶元素为括号,入栈
                stack.push(var);
            else if(var == ')' ){   //如果该符号为 右括号 。持续出栈并输出,直到栈顶元素为左括号,并出栈。
                while (stack.peek() != '(')
                    sb.append(stack.pop());
                stack.pop();
            }
            else if(!stack.isEmpty() && (var == '+' || var == '-' || var == '*' || var == '/')){  //栈非空,且为运算符
                while (!stack.isEmpty() && isFrist(stack.peek(),var))
                    sb.append(stack.pop());
                stack.push(var);
            }
        }

        while (!stack.isEmpty())        //遍历结束,将栈中的元素全部输出
            sb.append(stack.pop());
        return sb.toString();
    }

    private static boolean isFrist(char var1,char var2){   //判断两个运算符的优先级,var1 大于等于 var2 返回 true
        if(var1 == '*' || var1 == '/'){
            return true;
        }
        else if(var1 == '+' || var1 == '-'){
            if(var2 == '*' || var2 == '/')
                return false;
            else
                return true;
        }
        else                //指的是 var1 == '(' 的情况
            return false;
    }
}
#笔试题目#
全部评论

相关推荐

一名愚蠢的人类:多少games小鬼留下了羡慕的泪水
投递荣耀等公司10个岗位
点赞 评论 收藏
分享
评论
点赞
3
分享
牛客网
牛客企业服务