• 算法基础系列之四:表达式计算及逆波兰栈


    简单的表达式计算及逆波兰栈

    今天Boss不在,可以偷偷玩会。想写一个程序计算一个字符串表达式(假定表达式合法),使用逆波兰栈的原理。一开始觉得很容易,写了一会倒也出了不少问题,好在都是些小问题。

    1.在字符串拆分那块就琢磨半天,也没想出什么好方法,最后用很土的方法实现的(方法StringSplit

    2.发现老是要判断符号栈是否有元素,干脆先压入一个“$”(operStack.Push("$")),类似“哨兵”。

    3.遇到类似“-15*2+3*(1+2)”这样的式子时出错,所以在数字栈中先压入0numStack.Push(0)

    4.为了在扫描字符串结束后自动弹出符号栈中的符号并计算,在原字符末加上“$”,让程序在遇“$”时弹出所有符号。

    程序如下,错误的或都不好的地方大家多多批评,感谢:

     

    private static Regex regOper = new Regex(@"[\+\-\*/\(\)$]");
    static void Main(string[] args)

        
    string expression = Console.ReadLine();
        Stack
    <double> numStack = new Stack<double>();
        Stack
    <string> operStack = new Stack<string>();
        numStack.Push(
    0);
        operStack.Push(
    "$");

        List
    <string> list = StringSplit(expression);
        
    string oper = "";
        
    foreach (string element in list)
        
    {
            
    if (regOper.IsMatch(element))
            
    {
                
    switch (element)
                
    {
                    
    case "+":
                    
    case "-":
                        
    while ((oper = operStack.Pop()) != "$" && oper != "(")
                        
    {
                            
    double temp = Cal(numStack.Pop(), numStack.Pop(), oper);
                            numStack.Push(temp);
                        }

                        operStack.Push(oper);
                        operStack.Push(element);
                        
    break;
                    
    case "*":
                    
    case "/":
                        
    while ((oper = operStack.Pop()) == "*" || oper == "/")
                        
    {
                            
    double temp = Cal(numStack.Pop(), numStack.Pop(), oper);
                            numStack.Push(temp);
                        }

                        operStack.Push(oper);
                        operStack.Push(element);
                        
    break;
                    
    case "(":
                        operStack.Push(element);
                        
    break;
                    
    case ")":
                        
    while ((oper = operStack.Pop()) != "(")
                        
    {
                            
    double temp = Cal(numStack.Pop(), numStack.Pop(), oper);
                            numStack.Push(temp);
                        }

                        
    break;
                    
    default:
                        
    while ((oper = operStack.Pop()) != "$")
                        
    {
                            
    double temp = Cal(numStack.Pop(), numStack.Pop(), oper);
                            numStack.Push(temp);
                        }

                        
    break;
                }

            }

            
    else
            
    {
                numStack.Push(Convert.ToDouble(element));
            }

        }

        Console.WriteLine(
    "表达式结果:" + numStack.Pop());
        Console.Read();
    }


    //拆分表达式
    static List<string> StringSplit(string s)
    {
        List
    <string> list = new List<string>();
        
    int position = -1;
        s 
    += "$";
        
    for (int i = 0; i < s.Length; i++)
        
    {
            
    if (regOper.IsMatch(s[i].ToString()))
            
    {
                
    if (i - position > 1)
                
    {
                    list.Add(s.Substring(position 
    + 1, i - position - 1));
                }

                list.Add(s.Substring(i, 
    1));
                position 
    = i;
            }

        }

        
    return list;
    }


    //计算两个数值的运算结果
    static double Cal(double num1, double num2, string oper)
    {
        
    switch (oper)
        
    {
            
    case "+":
                
    return num2 + num1;
            
    case "-":
                
    return num2 - num1;
            
    case "*":
                
    return num2 * num1;
            
    case "/":
                
    return num2 / num1;
            
    default:
                
    return 0;
        }

    }

  • 相关阅读:
    Codeforces977D ---Divide by three, multiply by two 深搜+map存出现的数
    HDU4522 湫湫系列故事——过年回家
    2018浙江省赛记录
    POJ3259 :Wormholes(SPFA判负环)
    上海高校金马五校赛 F题:1 + 2 = 3?
    牛客练习赛15A-吉姆的运算式(Python正则表达式瞎搞)
    ZOJ2018/4月月赛G题Traffic Light(广搜)
    luogu 3960 列队
    noip2017
    10.3 模拟赛
  • 原文地址:https://www.cnblogs.com/morvenhuang/p/561627.html
Copyright © 2020-2023  润新知