精华内容
下载资源
问答
  • 后缀表达式实现计算器
    2021-12-21 16:47:23


    前言

    最近在看数据结构,看到如此神奇的后缀表达式运用思想,于是就自己写代码实现了


    一、原理

    简单算术表达式是使用中缀表达式进行表达的,但是这样就无法解决表达式优先级问题,因此利用栈先进后出原理转换为后缀表达来解决简单算术表达式优先级问题。

    二、使用步骤

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

    遍历中缀表达式,数字则直接输出,(除括号外)符号则进栈,进栈前先判断栈顶元素的符号优先级和当前需要进栈的符号的优先级,如果栈顶符号优先级要高的话就栈顶元素先出栈输出,然后当前元素入栈,否则直接入栈。左括号直接入栈,因为优先规则最高,右括号则将栈元素一个一个出栈直到找到与之匹配的左括号。遍历完成后查看栈中是否还存在元素,如果存在则一个一个出栈输出。

    2.计算结果

    遍历后缀表达式,遇到符号就将符号前两个元素进行计算并保存计算后的结果删除两个计算元素

    三、实现代码

    1.启动类

    代码如下(示例):

    public class CalculateTest {
    
    
        public static void main(String[] args) {
    
            System.out.println("请输入:(只支持+ - * / ( ) 符号 )");
            Scanner scanner = new Scanner(System.in);
            String express = scanner.nextLine();
    
            express = express.replaceAll("\\("," ( ").replaceAll("\\)"," ) ")
                    .replaceAll("\\+"," + ").replaceAll("-"," - ")
                    .replaceAll("\\*"," * ").replaceAll("/"," / ");
            // 切割一个或多个空格
            String[] expressArray = express.split("\\s+");
            CalculateUtils.isValid(expressArray);
            BigDecimal result = CalculateUtils.calculate(CalculateUtils.translate(expressArray));
    
            System.out.println("结果:" + result.toString());
    
        }
    }
    

    2.工具类

    代码如下(示例):

    public class CalculateUtils {
    
        private static final Map<String, SymbolInterface> SYMBOL_STRATEGY_MAP;
        private static final List<String> CALCULATE_SYMBOL_LIST = SymbolConstants.getCalculateSymbol();
    
    
        static {
            SYMBOL_STRATEGY_MAP = new HashMap<>(8);
            SYMBOL_STRATEGY_MAP.put(SymbolConstants.LEFT_PARENTHESIS_SYMBOL, new LeftParenthesisSymbolStrategy());
            SYMBOL_STRATEGY_MAP.put(SymbolConstants.RIGHT_PARENTHESIS_SYMBOL, new RightParenthesisSymbolStrategy());
            SYMBOL_STRATEGY_MAP.put(SymbolConstants.PLUS_SYMBOL, new PlusOrSubtractionSymbolStrategy());
            SYMBOL_STRATEGY_MAP.put(SymbolConstants.SUBTRACTION_SYMBOL, new PlusOrSubtractionSymbolStrategy());
            SYMBOL_STRATEGY_MAP.put(SymbolConstants.MULTIPLICATION_SYMBOL, new MultiplicationOrDivisionSymbolStrategy());
            SYMBOL_STRATEGY_MAP.put(SymbolConstants.DIVISION_SYMBOL, new MultiplicationOrDivisionSymbolStrategy());
        }
    
    
        /**
         * 校验字符是否输入合法
         *
         * @param expressArray
         */
        public static void isValid(String[] expressArray) {
    
            int lengthFlag = 3;
            int leftParenthesisCount = 0;
            int rightParenthesisCount = 0;
            int specialCount = 0;
            for (String express : expressArray) {
                if (express.equals(SymbolConstants.LEFT_PARENTHESIS_SYMBOL)) {
                    leftParenthesisCount++;
                    specialCount++;
                } else if (express.equals(SymbolConstants.RIGHT_PARENTHESIS_SYMBOL)) {
                    rightParenthesisCount++;
                    specialCount++;
                }
                if (CALCULATE_SYMBOL_LIST.contains(express)) {
                    specialCount++;
                }
            }
            if (leftParenthesisCount != rightParenthesisCount) {
                throw new RuntimeException("表达式异常");
            }
            int numberCount = expressArray.length - specialCount;
            int calculateSymbolCount = specialCount - leftParenthesisCount - rightParenthesisCount;
            if (numberCount - calculateSymbolCount != 1) {
                throw new RuntimeException("表达式异常");
            }
            if (expressArray.length < lengthFlag) {
                throw new RuntimeException("表达式异常");
            }
        }
    
        /**
         * 中缀表达式 转换为后缀表达式
         *
         * @param expressArray
         * @return
         */
        public static LinkedList<String> translate(String[] expressArray) {
            // 初始化栈大小
            Stack<String> stack = new Stack<>();
    
            LinkedList<String> suffixLinkedList = Lists.newLinkedList();
    
            for (String temp : expressArray) {
                boolean numberFlag = isNumber(temp);
                if (numberFlag) {
                    suffixLinkedList.add(temp);
                    continue;
                }
                SymbolInterface symbolInterface = SYMBOL_STRATEGY_MAP.get(temp);
                if (null == symbolInterface) {
                    throw new RuntimeException("不支持该字符计算");
                }
                if (stack.isEmpty()) {
                    stack.push(temp);
                } else {
                    symbolInterface.operate(stack, suffixLinkedList, temp);
                }
            }
            while (!stack.isEmpty()) {
                String pop = stack.pop();
                suffixLinkedList.add(pop);
            }
    
    
            return suffixLinkedList;
        }
    
        /**
         * 校验是否是数字
         *
         * @param express
         * @return
         */
        public static Boolean isNumber(String express) {
            boolean hasDecimal = express.contains(".");
            if (hasDecimal) {
                String[] integerAndDecimal = express.split("\\.");
                int decimalFlag = 2;
                if (integerAndDecimal.length != decimalFlag) {
                    throw new RuntimeException("表达式异常");
                }
                boolean isInteger = isNumber(integerAndDecimal[0]);
                boolean isDecimal = isNumber(integerAndDecimal[1]);
                if (!isInteger || !isDecimal) {
                    throw new RuntimeException("表达式异常");
                }
            }
            for (Character temp : express.toCharArray()) {
                if (!Character.isDigit(temp) && express.length() > 1) {
                    throw new RuntimeException("表达式异常");
                } else if (!Character.isDigit(temp) && express.length() == 1) {
                    return false;
                }
            }
    
            return true;
        }
    
        /**
         * 计算结果
         *
         * @param list
         * @return
         */
        public static BigDecimal calculate(LinkedList<String> list) {
    
    
            for (int i = 2; i < list.size(); i++) {
                // list.get(i) 内部是循环获取
                String express = list.get(i);
                if (CALCULATE_SYMBOL_LIST.contains(express)) {
                    String pre = list.get(i - 1);
                    String prePre = list.get(i - 2);
                    SymbolInterface symbolInterface = SYMBOL_STRATEGY_MAP.get(express);
                    if (null == symbolInterface) {
                        throw new RuntimeException("不支持该字符计算");
                    }
                    String result = symbolInterface.calculate(pre, prePre, express);
                    list.set(i - 2, result);
                    // 清除计算的两个元素
                    list.remove(i - 1);
                    list.remove(i - 1);
                    // 复原下标
                    i = 1;
    
                }
            }
    
    
            return new BigDecimal(list.get(0));
        }
    }
    
    

    3.策略类

    代码如下(示例):

    /**
     * 中缀表达式转换为后缀表达式时各符号策略接口
     *
     */
    public interface SymbolInterface {
    
        /**
         * 符号进栈出栈操作
         *
         * @param stack
         * @param suffixList
         * @param express
         */
        void operate(Stack<String> stack, LinkedList<String> suffixList, String express);
    
        /**
         * 计算
         *
         * @param left
         * @param right
         * @param express
         * @return
         */
        String calculate(String left, String right, String express);
    
    }
    
    
    
    /**
     * 左括号策略
     */
    public class LeftParenthesisSymbolStrategy implements SymbolInterface {
        @Override
        public void operate(Stack<String> stack, LinkedList<String> suffixList, String express) {
            // 左括号优先级最高 直接入栈
            stack.push(express);
        }
    
        @Override
        public String calculate(String left, String right, String express) {
            return null;
        }
    
    
    }
    /**
     * 乘除策略
     */
    public class MultiplicationOrDivisionSymbolStrategy implements SymbolInterface {
        @Override
        public void operate(Stack<String> stack, LinkedList<String> suffixList, String express) {
            // 获取栈顶元素
            String peek = stack.peek();
            if (peek.equals(SymbolConstants.LEFT_PARENTHESIS_SYMBOL) || peek.equals(SymbolConstants.SUBTRACTION_SYMBOL) || peek.equals(SymbolConstants.PLUS_SYMBOL)) {
                stack.push(express);
            } else {
                String pop = stack.pop();
                stack.push(express);
                suffixList.add(pop);
            }
    
        }
    
        @Override
        public String calculate(String left, String right, String express) {
            BigDecimal result;
            BigDecimal rightBigDecimal = new BigDecimal(right);
            BigDecimal leftBigDecimal = new BigDecimal(left);
            if (express.equals(SymbolConstants.MULTIPLICATION_SYMBOL)) {
                result = leftBigDecimal.multiply(rightBigDecimal);
            } else {
                int zero = 0;
                if (zero == rightBigDecimal.signum()) {
                    throw new RuntimeException("表达式异常");
                }
                result = rightBigDecimal.divide(leftBigDecimal, 2, BigDecimal.ROUND_HALF_UP);
            }
            return result.toString();
        }
    
    
    }
    /**
     * 加减策略
     */
    public class PlusOrSubtractionSymbolStrategy implements SymbolInterface {
        @Override
        public void operate(Stack<String> stack, LinkedList<String> suffixList, String express) {
            // 获取栈顶元素
            String peek = stack.peek();
            if (peek.equals(SymbolConstants.LEFT_PARENTHESIS_SYMBOL)) {
                stack.push(express);
            } else {
                String pop = stack.pop();
                stack.push(express);
                suffixList.add(pop);
            }
    
        }
    
        @Override
        public String calculate(String left, String right, String express) {
            BigDecimal result ;
            if(express.equals(SymbolConstants.SUBTRACTION_SYMBOL)){
                result =  new BigDecimal(left) .subtract(new BigDecimal(right));
            }else{
                result =  new BigDecimal(left) .add(new BigDecimal(right));
            }
            return result.toString();
        }
    }
    
    /**
     * 右括号策略
     */
    public class RightParenthesisSymbolStrategy implements SymbolInterface {
        @Override
        public void operate(Stack<String> stack, LinkedList<String> suffixList, String express) {
            // 获取栈顶元素
            while (!stack.isEmpty() && !stack.peek().equals(SymbolConstants.LEFT_PARENTHESIS_SYMBOL)) {
                String pop = stack.pop();
                suffixList.add(pop);
            }
            if (!stack.isEmpty() && stack.peek().equals(SymbolConstants.LEFT_PARENTHESIS_SYMBOL)) {
                stack.pop();
                return;
            }
        }
    
        @Override
        public String calculate(String left, String right, String express) {
            return null;
        }
    
    
    }
    
    

    4.常量类

    代码如下(示例):


    /**
     * 符号常量
     */
    public final class SymbolConstants {
        /**
         * 乘号
         */
        public static final String MULTIPLICATION_SYMBOL = "*";
        /**
         * 除号
         */
        public static final String DIVISION_SYMBOL = "/";
    
        /**
         * 加号
         */
        public static final String PLUS_SYMBOL = "+";
    
        /**
         * 减号
         */
        public static final String SUBTRACTION_SYMBOL = "-";
    
        /**
         * 左括号
         */
        public static final String LEFT_PARENTHESIS_SYMBOL = "(";
    
        /**
         * 右括号
         */
        public static final String RIGHT_PARENTHESIS_SYMBOL = ")";
    
        /**
         * 获取计算符号
         *
         * @return
         */
        public static List<String> getCalculateSymbol() {
            List<String> list = Lists.newArrayListWithExpectedSize(4);
            list.add(MULTIPLICATION_SYMBOL);
            list.add(DIVISION_SYMBOL);
            list.add(PLUS_SYMBOL);
            list.add(SUBTRACTION_SYMBOL);
            return list;
        }
    
    
    }
    
    

    总结

    如何保持对这一行业的热爱,就是不断的将想法付出实践。

    努力了的才叫梦想,不努力的就是空想!如果你一直空想的话,无论看多少正能量语录,也赶不走满满的负能量!你还是原地踏步的你,一直在看别人进步的你。

    更多相关内容
  • java使用后缀表达式实现计算器,其中有将一般数学运算式(7-9+5/5-5*6)转换成后缀表达式的方法,以及后缀表达式的求解方法
  • C++的后缀表达式计算器,运用栈,可以方便地得出浮点数运算的结果。支持的运算符有+、-、*、/、&、|、^、<(左移)、>(右移)、`(乘方)、!(整数阶乘)、\(绝对值),其中整数阶乘和绝对值是单目运算符,其它的...
  • 本文实例为大家分享了python实现计算器功能的具体代码,供大家参考,具体内容如下前缀表达式运算符在数字的前面1 + (2 + 3) * 4 - 5 (中缀)- + 1 * + 2 3 4 5 (前缀)前缀表达式的计算方法和后缀表达式类似,只是变成...

    本文实例为大家分享了python实现计算器功能的具体代码,供大家参考,具体内容如下

    前缀表达式

    运算符在数字的前面

    1 + (2 + 3) * 4 - 5 (中缀)

    - + 1 * + 2 3 4 5  (前缀)

    前缀表达式的计算方法和后缀表达式类似,只是变成了从右往左扫描

    中缀表达式

    运算符在中间,运算时需要考虑运算符优先级

    1+2*3-5

    要先算2*3....

    后缀表达式

    运算符在数字的后面,运算时不考虑优先级,只需要遇到符号,就把他前面的两个数字进行运算就好了

    例如: a b c + + 即: a + (b + c)

    1 + (2 + 3) * 4 - 5 (中缀)

    1 2 3 + 4 * + 5 -  (后缀)

    因为无需考虑优先级,运算是线性结构的,其用栈实现会很简单

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

    运算规律,运算数位置不变,改变的是符号的位置

    2 + 9 / 3 - 5   (中缀)

    2 9 3 / + 5 -  (后缀)

    具体方式

    1.从左到右进行遍历

    2.运算数,直接输出.3.左括号,直接压入堆栈,(括号是最高优先级,无需比较)(入栈后优先级降到最低,确保其他符号正常入栈)

    4.右括号,(意味着括号已结束)不断弹出栈顶运算符并输出直到遇到左括号(弹出但不输出)

    5.运算符,将该运算符与栈顶运算符进行比较,如果优先级高于栈顶运算符则压入堆栈(该部分运算还不能进行),

    如果优先级低于等于栈顶运算符则将栈顶运算符弹出并输出,然后比较新的栈顶运算符.

    (低于弹出意味着前面部分可以运算,先输出的一定是高优先级运算符,等于弹出是因为同等优先级,从左到右运算)

    直到优先级大于栈顶运算符或者栈空,再将该运算符入栈.

    **6.*如果对象*处理完毕,则按顺序弹出并输出栈中所有运算符.

    0789e8b45dcb1f477808de465824f89f.png

    后缀表达式运算步骤

    后缀表达式运算步骤:

    (以堆栈储存)

    从左到右,遇到运算符就弹出相应的运算数,运算后再把结果入栈.最终结果就是栈顶数的值.

    (由于该运算为线性结构,具体运算时是不需要储存输出后的运算符,一般是输出一个运算符就进行一次运算,不像图中要储存输出状态.)

    注意点:

    有时候'-'(负号)是单目运算符,则要修改运算数.

    遇到其他运算符(如幂运算)也类似.

    python代码例子

    '''

    中缀转换为后缀

    '''

    a = "1+(2+6/1+2)"

    #a = "2+9/3-5"

    # 可能出现的符号

    symbol_1 = ['+','-','*','/']

    symbol_2 = ['(']

    symbol_3 = [')']

    # 符号的优先级

    priority = {'#':-1,'(':1,'+':2,'-':2,'*':3,'/':3}

    match_2 = {')':'('}

    # 存储符号的栈

    zhan = []

    zhan.append("#")

    # 结果

    result = []

    '''

    ### 这里只是对表达式进行转换

    for i in a:

    # 如果是数字直接添加到结果

    if i.isdigit():

    result.append(i)

    # 如果是 + - * / 运算,则先出栈更低优先级的,然后入栈

    elif i in symbol_1:

    # 如果优先级低,则出栈所有优先级>=的符号

    while priority[i] <= priority[zhan[-1]]:

    result.append(zhan.pop())

    # 压入符号

    zhan.append(i)

    # 如果是左括号,直接压入

    elif i in symbol_2:

    zhan.append(i)

    # 如果是右括号,则出栈,直到遇到了匹配的左括号,然后吧左括号也出栈

    elif i in symbol_3:

    while zhan[-1] != match_2[i]:

    result.append(zhan.pop())

    zhan.pop()

    result.append(zhan.pop())

    print(''.join(result))

    '''

    # 下面通过将中缀表达式转换为后缀表达式,并进行运算

    def my_operation(symbol, a, b):

    a,b = int(a),int(b)

    if symbol == '+':

    return a + b

    elif symbol == '-':

    return a - b

    elif symbol == '*':

    return a * b

    elif symbol == '/':

    return a / b

    def to_operation(result, zhan):

    two = result.pop()

    one = result.pop()

    symbol = zhan.pop()

    ret = my_operation(symbol, one, two)

    print(f"{one}{symbol}{two} = {ret}")

    result.append(ret)

    ### 在表达式转换的时候就一边进行了运算

    for i in a:

    # 如果是数字直接添加到结果

    if i.isdigit():

    result.append(i)

    # 如果是 + - * / 运算,则先出栈更低优先级的,然后入栈

    elif i in symbol_1:

    # 如果优先级低,则出栈所有优先级>=的符号

    while priority[i] <= priority[zhan[-1]]:

    to_operation(result, zhan)

    # 压入符号

    zhan.append(i)

    # 如果是左括号,直接压入

    elif i in symbol_2:

    zhan.append(i)

    # 如果是右括号,则出栈,直到遇到了匹配的左括号,然后吧左括号也出栈

    elif i in symbol_3:

    while zhan[-1] != match_2[i]:

    to_operation(result, zhan)

    zhan.pop()

    to_operation(result, zhan)

    print(result)

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    展开全文
  • C++的后缀表达式计算器,运用栈,可以方便地得出浮点数运算的结果。支持的运算符有+、-、*、/、&、|、^、<(左移)、>(右移)、`(乘方)、!(整数阶乘)、\(绝对值),其中整数阶乘和绝对值是单目运算符,其它的...
  • 源代码 博文链接:https://sylinx.iteye.com/blog/215322
  • 输入一个逆波兰表达式(后缀表达式), 使用栈(Stack), 计算其结果 支持小括号和多位数整数, 因为这里我们主要针对于数据结构, 因此计算器进行简化, 只支持对整数的计算 思路分析 代码完成 package com.beyond.stack; ...

    逆波兰计算器的实现

    1. 输入一个逆波兰表达式(后缀表达式), 使用栈(Stack), 计算其结果
    2. 支持小括号和多位数整数, 因为这里我们主要针对于数据结构, 因此计算器进行简化, 只支持对整数的计算
    3. 思路分析
    4. 代码完成
    package com.beyond.stack;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Stack;
    
    public class PolandNotation {
    
    	public static void main(String[] args) {
    		// 先定义一个逆波兰表达式
    		// (3+4)*5-6  => 3 4 + 5 * 6 -
    		// 为了方便, 逆波兰表达式 的数字和符号使用空格隔开
    		String suffixExpression = "3 4 + 5 * 6 -";
    		
    		// 思路:
    		// 1. 先将 "3 4 + 5 * 6 -" => 放到 ArrayList中
    		// 2. 将 ArrayList 传递给一个方法, 遍历ArrayList 配合 栈 完成计算
    		
    		List<String> rpnList = getListString(suffixExpression);
    		System.out.println(rpnList);
    		System.out.println(calculate(rpnList));
    	}
    
    	
    	// 将一个逆波兰表达式, 依次将数据和运算符 放入 ArrayList 中
    	public static List<String> getListString(String suffixExpression){
    		// 将suffixExpression 分割
    		String split [] = suffixExpression.split(" ");
    		List<String> list = new ArrayList<String>();
    		for(String ele: split) {
    			list.add(ele);
    		}
    		return list;
    	}
    	
    	// 完成对逆波兰表达式的运算
    	/**
    	 * 1. 从左到右扫描, 将3和4压入堆栈;
    	 * 2. 遇到 + 运算符, 因此弹出 4和3 (4 为栈顶元素,3为次栈顶元素), 计算 3+4 的值, 得7, 再将7 入栈
    	 * 3. 将 5 入栈
    	 * 4. 接下来是 * 运算符, 因此 弹出 5和7, 计算出 7*5 = 35, 将35 入栈
    	 * 5. 将6入栈
    	 * 6. 最后是 - 运算符, 计算出 35 -6 的值, 即29, 由此得出最终结果
    	 */
    	public static int calculate(List<String> ls) {
    		// 创建个栈, 一个栈即可
    		Stack<String> stack = new Stack<String>();
    		// 遍历 ls
    		for(String item: ls) {
    			// 使用一个正则表达式来取出数
    			if (item.matches("\\d+")) {  // 匹配的是多位数
    				// 入栈
    				stack.push(item);
    			}else {
    				// pop 出两个数, 并运算, 再入栈
    				int num2 = Integer.parseInt(stack.pop());
    				int num1 = Integer.parseInt(stack.pop());
    				int res = 0; 
    				if (item.equals("+")) {
    					res = num1 + num2;
    				}else if (item.equals("-")) {
    					res = num1 - num2;
    				}else if (item.equals("*")) {
    					res = num1 * num2;
    				}else if (item.equals("/")) {
    					res = num1 / num2;
    				}else {
    					throw new RuntimeException("运算符有误!");
    				}
    				
    				// 把 res 入栈
    				stack.push(String.valueOf(res)); // 转成字符串, 还可以 Integer.toString(res) 或者使用 +""
    				
    			}
    		}
    	
    		// 最后留在 stack 中的数据就是运算结果
    		return Integer.parseInt(stack.pop());
    		
    	}
    	
    	
    }
    
    

    在这里插入图片描述

    展开全文
  • 后缀表达式计算器(csdn)————程序
  • 前缀表达式的计算方法和后缀表达式类似,只是变成了从右往左扫描 中缀表达式 运算符在中间,运算时需要考虑运算符优先级 1+2*3-5 要先算2*3.... 后缀表达式 运算符在数字的后面,运算时不考虑优先级,只需要...

    前缀表达式

    运算符在数字的前面,

    1 + (2 + 3) * 4 - 5 (中缀)
    - + 1 * + 2 3 4 5  (前缀)
    
    • 前缀表达式的计算方法和后缀表达式类似,只是变成了从右往左扫描

    中缀表达式

    运算符在中间,运算时需要考虑运算符优先级

    1+2*3-5
    要先算2*3....
    

    后缀表达式

    运算符在数字的后面,运算时不考虑优先级,只需要遇到符号,就把他前面的两个数字进行运算就好了

    例如: a b c + + 即: a + (b + c)

    1 + (2 + 3) * 4 - 5 (中缀)
    1 2 3 + 4 * + 5 -  (后缀)
    
    • 因为无需考虑优先级,运算是线性结构的,其用栈实现会很简单

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

    • 运算规律,运算数位置不变,改变的是符号的位置
    2 + 9 / 3 - 5   (中缀)
    2 9 3 / + 5 -  (后缀)
    

    具体方式

    1.从左到右进行遍历
    2.运算数,直接输出.
    3.左括号,直接压入堆栈,(括号是最高优先级,无需比较)(入栈后优先级降到最低,确保其他符号正常入栈)
    4.右括号,(意味着括号已结束)不断弹出栈顶运算符并输出直到遇到左括号(弹出但不输出)
    5.运算符,将该运算符与栈顶运算符进行比较,
    如果优先级高于栈顶运算符则压入堆栈(该部分运算还不能进行),
    如果优先级低于等于栈顶运算符则将栈顶运算符弹出并输出,然后比较新的栈顶运算符.
    (低于弹出意味着前面部分可以运算,先输出的一定是高优先级运算符,等于弹出是因为同等优先级,从左到右运算)
    直到优先级大于栈顶运算符或者栈空,再将该运算符入栈.
    **6.*如果对象*处理完毕,则按顺序弹出并输出栈中所有运算符.

    后缀表达式运算步骤

    后缀表达式运算步骤:
    (以堆栈储存)
    从左到右,遇到运算符就弹出相应的运算数,运算后再把结果入栈.最终结果就是栈顶数的值.
    (由于该运算为线性结构,具体运算时是不需要储存输出后的运算符,一般是输出一个运算符就进行一次运算,不像图中要储存输出状态.)
    注意点:
    有时候’-’(负号)是单目运算符,则要修改运算数.
    遇到其他运算符(如幂运算)也类似.

    python代码例子

    '''
    中缀转换为后缀
    '''
    
    a = "1+(2+6/1+2)"
    #a = "2+9/3-5"
    # 可能出现的符号 
    symbol_1 = ['+','-','*','/']
    symbol_2 = ['(']
    symbol_3 = [')']
    # 符号的优先级
    priority = {'#':-1,'(':1,'+':2,'-':2,'*':3,'/':3}
    match_2 = {')':'('}
    # 存储符号的栈
    zhan = []
    zhan.append("#")
    # 结果
    result = []
    
    '''
    ###  这里只是对表达式进行转换
    for i in a:
        # 如果是数字直接添加到结果
        if i.isdigit():
            result.append(i)
        # 如果是 + - * / 运算,则先出栈更低优先级的,然后入栈
        elif i in symbol_1:
            # 如果优先级低,则出栈所有优先级>=的符号
            while priority[i] <= priority[zhan[-1]]:
                result.append(zhan.pop())
            # 压入符号
            zhan.append(i)
        # 如果是左括号,直接压入
        elif i in symbol_2:
            zhan.append(i)
        # 如果是右括号,则出栈,直到遇到了匹配的左括号,然后吧左括号也出栈
        elif i in symbol_3:
            while zhan[-1] != match_2[i]:
                result.append(zhan.pop())
            zhan.pop()
                
    result.append(zhan.pop())
    print(''.join(result))
    
    '''
    # 下面通过将中缀表达式转换为后缀表达式,并进行运算
    def my_operation(symbol, a, b):
        a,b = int(a),int(b)
        if symbol == '+':
            return a + b
        elif symbol == '-':
            return a - b
        elif symbol == '*':
            return a * b
        elif symbol == '/':
            return a / b
    
    def to_operation(result, zhan):
        two = result.pop()
        one = result.pop()
        symbol = zhan.pop()
        ret = my_operation(symbol, one, two)
        print(f"{one}{symbol}{two} = {ret}")
        result.append(ret)
    
    ### 在表达式转换的时候就一边进行了运算
    for i in a:
        # 如果是数字直接添加到结果
        if i.isdigit():
            result.append(i)
        # 如果是 + - * / 运算,则先出栈更低优先级的,然后入栈
        elif i in symbol_1:
            # 如果优先级低,则出栈所有优先级>=的符号
            while priority[i] <= priority[zhan[-1]]:
                to_operation(result, zhan)
            # 压入符号
            zhan.append(i)
        # 如果是左括号,直接压入
        elif i in symbol_2:
            zhan.append(i)
        # 如果是右括号,则出栈,直到遇到了匹配的左括号,然后吧左括号也出栈
        elif i in symbol_3:
            while zhan[-1] != match_2[i]:
                to_operation(result, zhan)
            zhan.pop()
                
    to_operation(result, zhan)
    print(result)
    
    
    
    展开全文
  • 文章目录中缀表达式转后缀表达式思路逆波兰表达式计算思路代码实现 中缀表达式转后缀表达式思路 1、初始化两个栈:运算符栈s1和储存中间结果的栈s2 2、从左至右扫描中缀表达式 3、遇到操作数时,将其压入s2 4、遇到...
  • 后缀表达式计算器 代码实现 public class SuffixCulator { public static void main(String[] args) { String infixExpression = "(10+20/2*3)/2+8"; //"10 20 2 / 3 * + 2 / 8 + " //调用中缀转后缀类的方法 ...
  • 后缀表达式计算器

    2021-11-26 19:46:22
    printf("请输入后缀表达式(并以$结尾):\n"); ch=getchar(); while(ch!='$') { if(!In(ch)) //判断读取到的字符是不是数字 { //字符是数字 while(!In(ch)) { ch=ch-'0'; m=m*10+ch; ch=getchar(); } if(m!=0) { ...
  • 它遵循”先进后出,后进先出“原则,底层一般由数组或者单向链表实现的,接下来介绍一下栈应该场景,用栈实现中缀表达式转后缀表达式(逆波兰表达式)和实现简单计算器计算。 2.中缀表达式转后缀表达式:中缀表达式...
  • 计算器(表达式计算-后缀表达式实现) 【问题描述】 从标准输入中读入一个整数算术运算表达式,如24 / ( 1 + 2 + 36 / 6 / 2 - 2) * ( 12 / 2 / 2 )= ,计算表达式结果,并输出。 要求: 1、表达式运算符只有+、-、*...
  • 这种格式的后缀表达式, 把表达式放入ArrayList集合中操作,用空格隔开 使用一个方法来计算表达式,直接使用item.matches();正则表达式来匹配一。 整型变成字符串 数字加上一个 " "空字符就好 package com.demo;...
  • } string zzh(string zfs) //中缀表达式转后缀表达式 { string ts; stack<char> zhan; zhan.push('0'); int len = zfs.length(); for (int i = 0; i ; i++) { if (zfs[i] >= '0' && zfs[i] || zfs[i]=='.')...
  • 后缀表达式计算器的C++实现

    千次阅读 2018-11-30 12:27:12
    首先百度百科上抄一下定义:后缀表达式,指的是不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则)。 计算过程是这样的:建立一个栈S 。从...
  • 后缀表达式(逆波兰表达式)计算器
  • 【数据结构--栈】c语言实现计算器|后缀表达式|栈的操作
  • java数据结构day11--栈实现逆波兰表达式(后缀表达式)计算器
  • 后缀表达式对于人来说是比较难理解的,但是对于计算机来说,缺失比较简单易懂的结构,这主要是由于计算机内存是栈式结构。当我们知道一个表达式的后缀表达式的时候,... * 逆波兰表达式计算器 */ public class PolandN
  • 前缀表达式转后缀表达式,及后缀表达式计算器[Java]前缀表达式转后缀表达式 前缀表达式转后缀表达式 总体思路: 创建一个字符型的顺序栈栈和字符型的顺序表存放数字和运算符(顺序表和顺序栈创建参考1,2篇)。 将...
  • 循环输入,获取逆波兰表达式(后缀表达式),然后进行以下步骤,直到测试完所有的测试用例: 遇到数字字符串,将该数字字符串转化为数字然后入栈。利用int atio(const char ptr)将数字类型的字符串转换成整形数据...
  • 实现逆波兰表达式其实并不是很难,但是为什么要将看似简单的中缀表达式转成后缀表达式呢? 其实中缀表达式只是对人类而言是简单的,然而对于计算机来说,中缀表达式是一个非常复杂的结构。而后缀表达式对于计算机是...
  • 中缀表达式改后缀表达式,而且有计算器功能,一般的加减乘除都能

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,756
精华内容 2,702
热门标签
关键字:

后缀表达式实现计算器