• 数据结构习作之应用 "栈(Stack)" 实现: 解析算术表达式及计算求值 (C#/Java) (技术含量少许)


    今天看到博客堂在讨论
    《动态计算字串表达式值的类》 挺热闹!
    如果从数据结构角度讨论思路应该是:
    中缀表达式到后缀表达式的转换,要把表达式从中缀表达式的形式转换成用后缀表示法表示的等价表达式!

    这段程序只支持 正数的 + - * / () ,还很不完善,负数 -X 只能通过 (0-X) 来表示!
    代码不多150行,功能有限,但的确是 解析算术表达式及计算求值 的经典算法

    当然还很不成熟! 权当复习一下 stack 的功能 LIFO 中缀表达式到后缀表达式
    代码非常简单任何多余的类库都没用,可以移植到任何语言!
    C# Code:
    //using System;
    class Class1
    {
     
    public static void Main()
     
    {
      System.Console.WriteLine(
    "Hello World!");
      
    //中缀 => 后缀表达式
      string s = "(  1.9   +  (20 +  41)    / (25 * 11) -     3          )              * 2"//中缀; //中缀
      string S = ""//后缀
      char[] Operators = new char[s.Length];
      
    int Top = -1;
      
    for (int i = 0; i < s.Length; i++)
      
    {
       
    char C = s[i];
       
    switch (C)
       
    {
        
    case ' ' : //忽略空格
         break;
        
    case '+' : //操作符
        case '-' :
         
    while (Top >= 0//栈不为空时
         {
          
    char c = Operators[Top--]; //pop Operator
          if (c == '(')
          
    {
           Operators[
    ++Top] = c; //push Operator
           break;
          }

          
    else
          
    {
           S 
    = S + c;
          }

         }

         Operators[
    ++Top] = C; //push Operator
         S += " ";
         
    break;
        
    case '*' : //忽略空格
        case '/' :
         
    while (Top >= 0//栈不为空时
         {
          
    char c = Operators[Top--]; //pop Operator
          if (c == '(')
          
    {
           Operators[
    ++Top] = c; //push Operator
           break;
          }

          
    else
          
    {
           
    if (c == '+' || c == '-')
           
    {
            Operators[
    ++Top] = c; //push Operator
            break;
           }

           
    else
           
    {
            S 
    = S + c;
           }

          }

         }

         Operators[
    ++Top] = C; //push Operator
         S += " ";
         
    break;
        
    case '(' :
         Operators[
    ++Top] = C;
         S 
    += " ";
         
    break;
        
    case ')' :
         
    while (Top >= 0//栈不为空时
         {
          
    char c = Operators[Top--]; //pop Operator
          if (c == '(')
          
    {
           
    break;
          }

          
    else
          
    {
           S 
    = S + c;
          }

         }

         S 
    += " ";
         
    break;
        
    default :
         S 
    = S + C;
         
    break;
        
       }

      }

      
    while (Top >= 0)
      
    {
       S 
    = S + Operators[Top--]; //pop Operator
      }


      System.Console.WriteLine(S); 
    //后缀

      
    //后缀表达式计算
      double[] Operands = new double[S.Length];
      
    double x, y, v;
      Top 
    = - 1;
      
    string Operand = "";
      
    for (int i = 0; i < S.Length; i++)
      
    {
       
    char c = S[i];
       
    if ((c >= '0' && c <= '9'|| c == '.')
       
    {
        Operand 
    += c;
       }


       
    if ((c == ' ' || i == S.Length - 1&& Operand != ""//Update
       {
        Operands[
    ++Top] = System.Convert.ToDouble(Operand) ; //push Operands
        Operand = "";
       }


       
    if (c == '+' || c == '-' || c == '*' || c == '/')
       
    {
        
    if ((Operand != ""))
        
    {
         Operands[
    ++Top] = System.Convert.ToDouble(Operand) ; //push Operands
         Operand = "";
        }

        y 
    = Operands[Top--]; //pop 双目运算符的第二操作数 (后进先出)注意操作数顺序对除法的影响
        x = Operands[Top--]; //pop 双目运算符的第一操作数
        switch (c)
        
    {
         
    case '+' :
          v 
    = x + y;
          
    break;
         
    case '-' :
          v 
    = x - y;
          
    break;
         
    case '*' :
          v 
    = x * y;
          
    break;
         
    case '/' :
          v 
    = x / y; // 第一操作数 / 第二操作数 注意操作数顺序对除法的影响
          break;
         
    default :
          v 
    = 0;
          
    break;
        }

        Operands[
    ++Top] = v; //push 中间结果再次入栈
       }

      }

      v 
    = Operands[Top--]; //pop 最终结果
      System.Console.WriteLine(v);
      System.Console.ReadLine();
     }

    }



    Java Code:
    class Class1
    {
     
    public static void main(String[] args) 
     
    {
      System.
    out.println("Hello World!");
      
    //中缀 => 后缀表达式
      String s = "(  1.9   +  (20 +  41)    / (25 * 11) -     3          )              * 2"//中缀
      String S = ""//后缀
      char[] Operators = new char[s.length()];
      
    int Top = -1;
      
    for (int i = 0; i < s.length(); i++)
      
    {
       
    char C = s.charAt(i);
       
    switch(C)
       
    {
        
    case ' ' :
         
    break;
        
    case '+' : //操作符
        case '-' :
         
    while (Top >= 0//栈不为空时
         {
          
    char c = Operators[Top--]; //pop Operator
          if (c == '(')
          
    {
           Operators[
    ++Top] = c; //push Operator
           break;
          }

          
    else
          
    {
           S 
    = S + c;
          }

         }

         Operators[
    ++Top] = C; //push Operator
         S += " ";
         
    break;
        
    case '*' : //操作符
        case '/' :
         
    while (Top >= 0//栈不为空时
         {
          
    char c = Operators[Top--]; //pop Operator
          if (c == '(')
          
    {
           Operators[
    ++Top] = c; //push Operator
           break;
          }

          
    else
          
    {
           
    if (c == '+' || c == '-')
           
    {
            Operators[
    ++Top] = c; //push Operator
            break;
           }

           
    else
           
    {
            S 
    = S + c;
           }

          }

         }

         Operators[
    ++Top] = C; //push Operator
         S += " ";
         
    break;
        
    case '(' : //操作符
         Operators[++Top] = C;
         S 
    += " ";
         
    break;
        
    case ')' : //操作符
         while (Top >= 0//栈不为空时
         {
          
    char c = Operators[Top--]; //pop Operator
          if (c == '(')
          
    {
           
    break;
          }

          
    else
          
    {
           S 
    = S + c;
          }

         }

         S 
    += " ";
         
    break;
        
    default : //操作数
         S = S + C;
         
    break;
       }

      }

      
    while (Top >= 0)
      
    {
       S 
    = S + Operators[Top--]; //pop Operator
      }


      System.
    out.println(S); //后缀

      
    //后缀表达式计算
      double[] Operands = new double[S.length()];
      
    double x, y, v;
      Top 
    = - 1;
      String Operand 
    = "";
      
    for (int i = 0; i < S.length(); i++)
      
    {
       
    char c = S.charAt(i);
       
    if ((c >= '0' && c <= '9'|| c == '.')
       
    {
        Operand 
    += c;
       }


       
    if ((c == ' ' || i == S.length() - 1&& Operand != ""//Update
       {
        Operands[
    ++Top] = java.lang.Double.parseDouble(Operand) ; //push Operands
        Operand = "";
       }


       
    if (c == '+' || c == '-' || c == '*' || c == '/')
       
    {
        
    if ((Operand != ""))
        
    {
         Operands[
    ++Top] = java.lang.Double.parseDouble(Operand) ; //push Operands
         Operand = "";
        }

        y 
    = Operands[Top--]; //pop 双目运算符的第二操作数 (后进先出)注意操作数顺序对除法的影响
        x = Operands[Top--]; //pop 双目运算符的第一操作数
        switch (c)
        
    {
         
    case '+' :
          v 
    = x + y;
          
    break;
         
    case '-' :
          v 
    = x - y;
          
    break;
         
    case '*' :
          v 
    = x * y;
          
    break;
         
    case '/' :
          v 
    = x / y; // 第一操作数 / 第二操作数 注意操作数顺序对除法的影响
          break;
         
    default :
          v 
    = 0;
          
    break;
        }

        Operands[
    ++Top] = v; //push 中间结果再次入栈
       }

      }

      v 
    = Operands[Top--]; //pop 最终结果
      System.out.println(v);
     }

    }

  • 相关阅读:
    keepalived 结合mysql 自动切换
    haproxy 配置日志
    haproxy 配置日志
    keepalive的 nopreempt 非抢占
    keepalive的 nopreempt 非抢占
    keepavlied一些参数
    keepavlied一些参数
    mysql 结合keepalived测试
    【转载】[小红猪]11个物理难题,11种基本粒子 分类: 生活百科 2013-07-26 11:04 317人阅读 评论(0) 收藏
    【转载】上帝粒子证实存在宇宙末日来临?(图) 分类: 生活百科 2013-07-26 11:04 336人阅读 评论(0) 收藏
  • 原文地址:https://www.cnblogs.com/Microshaoft/p/132593.html
Copyright © 2020-2023  润新知