zoukankan      html  css  js  c++  java
  • 算法:逆波兰表达式求值

    背景

    运算符求值的一种常见做法是:先将中缀表达式转换为后缀表达式(逆波兰表达式),然后再对后缀表达式求值,之所以这么做的原因是后缀表达式的求值非常简单。

    代码实现

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Linq;
      4 using System.Text;
      5 using System.Threading.Tasks;
      6 
      7 namespace DataStuctureStudy.Stacks
      8 {
      9     public static class Calculator
     10     {
     11         private static readonly Dictionary<string, int> _operators = new Dictionary<string, int>
     12         {
     13             { "+", 1 },
     14             { "-", 1 },
     15             { "*", 2 },
     16             { "/", 2 },
     17             { "%", 2 }
     18         };
     19 
     20         public static void Test(string expression)
     21         {
     22             var postfixTokens = GetPostfixTokens(GetTokens(expression));
     23             Console.WriteLine(expression + " = " + Calculate(postfixTokens));
     24         }
     25 
     26         private static int Calculate(IEnumerable<string> postfixTokens)
     27         {
     28             var stack = new Stack<int>();
     29 
     30             foreach (var item in postfixTokens)
     31             {
     32                 if (IsOperator(item))
     33                 {
     34                     switch (item)
     35                     {
     36                         case "+":
     37                             stack.Push(stack.Pop() + stack.Pop());
     38                             break;
     39                         case "-":
     40                             stack.Push(stack.Pop() - stack.Pop());
     41                             break;
     42                         case "*":
     43                             stack.Push(stack.Pop() * stack.Pop());
     44                             break;
     45                         case "/":
     46                             stack.Push(stack.Pop() / stack.Pop());
     47                             break;
     48                         case "%":
     49                             stack.Push(stack.Pop() % stack.Pop());
     50                             break;
     51                     }
     52                 }
     53                 else
     54                 {
     55                     stack.Push(int.Parse(item));
     56                 }
     57             }
     58 
     59             return stack.Pop();
     60         }
     61 
     62         private static IEnumerable<string> GetPostfixTokens(IEnumerable<string> infixTokens)
     63         {
     64             var postfixTokens = new List<string>();
     65             var stack = new Stack<string>();
     66 
     67             foreach (var token in infixTokens)
     68             {
     69                 if (IsOperator(token))
     70                 {
     71                     var curOperator = token;
     72 
     73                     if (stack.Count == 0)
     74                     {
     75                         stack.Push(curOperator);
     76                     }
     77                     else
     78                     {
     79                         while (stack.Count != 0)
     80                         {
     81                             var popOperator = stack.Pop();
     82                             if (popOperator == "(")
     83                             {
     84                                 stack.Push(popOperator);
     85                                 break;
     86                             }
     87 
     88                             if (_operators[curOperator] <= _operators[popOperator])
     89                             {
     90                                 postfixTokens.Add(popOperator);
     91                             }
     92                             else
     93                             {
     94                                 stack.Push(popOperator);
     95                                 break;
     96                             }
     97                         }
     98 
     99                         stack.Push(curOperator);
    100                     }
    101                 }
    102                 else if (token == "(")
    103                 {
    104                     stack.Push(token);
    105                 }
    106                 else if (token == ")")
    107                 {
    108                     var popOperator = stack.Pop();
    109                     while (popOperator != "(")
    110                     {
    111                         postfixTokens.Add(popOperator);
    112                         popOperator = stack.Pop();
    113                     }
    114                 }
    115                 else
    116                 {
    117                     postfixTokens.Add(token);
    118                 }
    119             }
    120 
    121             while (stack.Count != 0)
    122             {
    123                 postfixTokens.Add(stack.Pop());
    124             }
    125 
    126             return postfixTokens;
    127         }
    128 
    129         private static IEnumerable<string> GetTokens(string expression)
    130         {
    131             var tokens = new List<string>();
    132             var sb = new StringBuilder();
    133 
    134             foreach (var item in expression)
    135             {
    136                 if (IsOperator(item.ToString()) || item == '(' || item == ')')
    137                 {
    138                     if (sb.Length > 0)
    139                     {
    140                         tokens.Add(sb.ToString());
    141                         sb.Clear();
    142                     }
    143 
    144                     tokens.Add(item.ToString());
    145                 }
    146                 else
    147                 {
    148                     sb.Append(item);
    149                 }
    150             }
    151 
    152             return tokens;
    153         }
    154 
    155         private static bool IsOperator(string token)
    156         {
    157             return _operators.ContainsKey(token);
    158         }
    159     }
    160 }
  • 相关阅读:
    时间日期事件处理、长按事件
    单选按钮触发事件、下拉列表触发事件
    事件
    笔记3
    笔记2
    笔记1
    布局管理器
    08、shell三剑客之sed
    07、shell三剑客之grep
    06、shell正则表达式
  • 原文地址:https://www.cnblogs.com/happyframework/p/3485451.html
Copyright © 2011-2022 走看看