スタックの単純なアプリケーション (スタックを使用して混合四則演算を実行) (JAVA)

目次

中置式を後置式に変換する

コード実装プロセス:

完全なコード: 

後置式を使用して評価します。

完全なコード:


 

まず、逆ポーランド語の表現を理解する必要があります

中置式を後置式に変換する

いわゆる中置式は、実際には通常私たちが書くものです(例: 3+4\times (2+ 2)+2\div 2;)、そしてその接尾辞式 (逆ポーランド式とも呼ばれます)は;です。 3\;  4\;  2\;  2+ \倍 + 2\;  2 \;\div +

後置式: 括弧が含まれていないことを意味し演算子は2 つのオペランドの後に配置されます。すべての計算は、演算子が出現する順序で左から右に厳密に実行されます(演算子の優先規則は考慮されなくなりました)。 。

プログラムを使用して4 つの混合演算を実行する場合、最も重要なことは、入力の中置式を後置式に変換することです。

まず、演算子が足し算、引き算、掛け算、割り算、括弧だけだと仮定すると、プログラムが複雑になりすぎます(実際には書けません(泣))。

コード実装プロセス:

まず、戻り値動的文字列配列(後で計算しやすくするため) であり、仮パラメータが文字列型であるメソッドを作成します(入力値には数値だけでなく演算子も含まれるため)。ここではスタックを使用するので、スタックも定義します。

    public ArrayList<String> midChangeEng(String str) {
        //这里用动态数组就不用担心不够用
        ArrayList<String> ret = new ArrayList<String>();
        Stack<Character> stack = new Stack<>();
    }

この時点で、入力された文字が演算子であるかどうかを判断する 新しいメソッドを作成します。

    public boolean isOperator(char s) {
        if (s == '+' || s == '-' || s == '*' || s == '/' || s == '(' || s == ')') {
            return true;
        }
        return false;
    }

次に、ASCII コード内の演算子の位置を使用して、優先順位を表す配列を作成します

int[] able = {1,0,0,0,0,1};//分别代表 * + (null) - (null) / 的优先级 

 文字列をループする

        //遍历字符串
        for (int i = 0; i < str.length(); i++) {
            char a = str.charAt(i);
            String tmp = "";//用来暂时存储出栈的数字
            if (isOperator(a)) {
                //是操作数
            }else{
                //如果是数字就放到ret中
            }
        }

        return ret;

オペランドの操作については、このコードには繰り返されるコードが多すぎるため、メソッドにカプセル化できます。

            if (isOperator(a)) {
                //是操作数
                switch (a) {
                    case '+'://判断如果优先级不大于栈顶的元素那么就先出栈在入栈
                        if(!stack.isEmpty()) {//出栈
                            while(!stack.isEmpty() && stack.peek() != '(' && able[(int)stack.peek() - 42] >= able[(int)a-42]) {
                                String b = "";
                                b += stack.pop();
                                ret.add(b);
                            }
                        }
                        stack.push(a);
                        break;
                    case '-':
                        if(!stack.isEmpty()) {//出栈
                            while(!stack.isEmpty() && stack.peek() != '(' && able[(int)stack.peek() - 42] >= able[(int)a-42]) {
                                String b = "";
                                b += stack.pop();
                                ret.add(b);
                            }
                        }
                        stack.push(a);
                        break;
                    case '*':
                        if(!stack.isEmpty()) {//出栈
                            while(!stack.isEmpty() && stack.peek() != '(' && able[(int)stack.peek() - 42] >= able[(int)a-42]) {
                                String b = "";
                                b += stack.pop();
                                ret.add(b);
                            }
                        }
                        stack.push(a);
                        break;
                    case '/':
                        if(!stack.isEmpty()) {//出栈
                            while(!stack.isEmpty() && stack.peek() != '(' && able[(int)stack.peek() - 42] >= able[(int)a-42]) {
                                String b = "";
                                b += stack.pop();
                                ret.add(b);
                            }
                        }
                        stack.push(a);
                        break;
                    case '(':
                        stack.push(a);
                        break;
                    case ')':
                        while(!stack.isEmpty() && stack.peek() != '(') {
                            String b = "";
                            b += stack.pop();
                            ret.add(b);
                        }
                        stack.pop();//删除‘(’
                        break;
                }

            }

 数値の場合は次のようにします

            else{
                //如果是数字就放到ret中
                String tmp = "";
                while(i < str.length() && !isOperator(str.charAt(i))) {//数字有可能是多位的
                    tmp += str.charAt(i);
                    i++;
                }
                i--;
                ret.add(tmp);
            }

関数を終了する前に、まずスタック内のすべてをエクスポートする必要があります。

        //将栈里面剩余的全部出栈
        while(!stack.isEmpty()) {
            String b = "";
            b += stack.pop();
            ret.add(b);
        }
        return ret;

完全なコード: 

    public static ArrayList<String> midChangeEng(String str) {
        //这里用动态数组就不用担心不够用
        ArrayList<String> ret = new ArrayList<String>();
        Stack<Character> stack = new Stack<>();

        int[] able = {1,0,0,0,0,1};//分别代表 * + (null) - (null) / 的优先级
        //遍历字符串
        for (int i = 0; i < str.length(); i++) {
            char a = str.charAt(i);

            if (isOperator(a)) {
                //是操作数
                switch (a) {
                    case '+'://判断如果优先级不大于栈顶的元素那么就先出栈在入栈
                        abcd(ret, stack, able, a);
                        break;
                    case '-':
                        abcd(ret, stack, able, a);
                        break;
                    case '*':
                        abcd(ret, stack, able, a);
                        break;
                    case '/':
                        abcd(ret, stack, able, a);
                        break;
                    case '(':
                        stack.push(a);
                        break;
                    case ')':
                        while(!stack.isEmpty() && stack.peek() != '(') {
                            String b = "";
                            b += stack.pop();
                            ret.add(b);
                        }
                        stack.pop();//删除‘(’
                        break;
                }
            }else{
                //如果是数字就放到ret中
                String tmp = "";
                while(i < str.length() && !isOperator(str.charAt(i))) {//数字有可能是多位的
                    tmp += str.charAt(i);
                    i++;
                }
                i--;
                ret.add(tmp);
            }
        }
        //将栈里面剩余的全部出栈
        while(!stack.isEmpty()) {
            String b = "";
            b += stack.pop();
            ret.add(b);
        }
        return ret;
    }

後置式を使用して評価します。

この部分は比較的単純なので、直接示します。

完全なコード:

        public int evalRPN(String[] tokens) {
            Stack<Integer> stack = new Stack<>();
            for (int i = 0; i < tokens.length; i++) {
                if (isOperator(tokens[i])) {
                    int num2 = stack.pop();
                    int num1 = stack.pop();
                    switch(tokens[i].charAt(0)) {
                        case '+':
                            stack.push(num1 + num2);
                            break;
                        case '-':
                            stack.push(num1 - num2);
                            break;
                        case '*':
                            stack.push(num1 * num2);
                            break;
                        case '/':
                            stack.push(num1 / num2);
                            break;
                    }
                }else {
                    stack.push(Integer.parseInt(tokens[i]));
                }
            }
            return stack.pop();
        }


        public boolean isOperator(String str) {
            if (str.length() != 1) {
                return false;
            }
            if (str.charAt(0) == '+' || str.charAt(0) == '-' || str.charAt(0) == '*' || str.charAt(0) == '/') {
                return true;
            }
            return false;
        }

おすすめ

転載: blog.csdn.net/2302_76339343/article/details/133177034