C# 表达式计算器----数据结构

using System;

using System.Collections.Generic;

using System.Linq; using System.Text;

using System.Collections;

namespace ConsoleApplication7

{   

  class Calculator

    {       

  static void Main(string[] args)

        {            

//string exp = "345*2^(4+2*2-1*3)-5";     

        for (; ; )     

        {         

        Console.WriteLine("input a values:");        

         string exp = Console.ReadLine();       

          Console.WriteLine("output reslut:");    

             Console.WriteLine(Calculate(exp));       

          Console.WriteLine("END");             }     

       // string exp = "130+20";              

          //Console.ReadKey();         }      

   public static double  Calculate(string _exp)    

     {             Stack operandStack = new Stack();//操作数   

          Stack operatorStack = new Stack();//运算符        

     operatorStack.Push('#');       

      char[] exp = (_exp + "#").ToCharArray();

StringBuilder sb = new StringBuilder();     

        for (int i = 0; i < exp.Length; i++)    

         {        

         if (IsPerand(exp[i]))          

       {              

       sb.Append(exp[i]);          

       }          

       else        

         {             

        string sbstr = sb.ToString();         

            if (sbstr!="")

               {                

         operandStack.Push(sb);        

             }               

      sb = new StringBuilder();             

        //优先级大于当前栈顶运算符的优先级  

        if (PriorityBeforeIn(exp[i]) > priorityAferIn((char)operatorStack.Peek()))

               {               

          operatorStack.Push(exp[i]);//#*      

               }              

       else if (PriorityBeforeIn(exp[i]) < priorityAferIn((char)operatorStack.Peek()))         

            {                                   

              object sbd =operandStack.Pop();             

            string str = sbd.ToString();                  

       object sbd1 =operandStack.Pop();             

            string str1 = sbd1.ToString();              

           double dou= Convert.ToDouble(str);          

               double dou1= Convert.ToDouble(str1);

                 operandStack.Push(Count((char)operatorStack.Pop(),dou,dou1));  

                       i--;           

          }                

     else if (PriorityBeforeIn(exp[i]) == priorityAferIn((char)operatorStack.Peek()))       

              {                   

      if (exp[i] == ')')              

           {                        

     while (true)                  

           {                          

       char c = (char)operatorStack.Peek();          

                       if (c == '(')                    

             {                            

         operatorStack.Pop();                

                     break;                   

              }                            

                           object sbd = operandStack.Pop();                       

          string str = sbd.ToString();          

                       object sbd1 = operandStack.Pop();           

                      string str1 = sbd1.ToString();               

                  double dou = Convert.ToDouble(str);                

                 double dou1 = Convert.ToDouble(str1); 

                    operandStack.Push(Count((char)operatorStack.Pop(), dou, dou1));        

                     }                         }             

            else if (exp[i] == '#')            

             {                       

      while (true)                      

       {                              

   char c = (char)operatorStack.Peek();            

                     if (c == '#')                     

            {                               

      operatorStack.Pop();                     

                break;                        

         }                               

object sbd = operandStack.Pop();                

                 string str = sbd.ToString();              

                   object sbd1 = operandStack.Pop();            

                     string str1 = sbd1.ToString();                      

           double dou = Convert.ToDouble(str);                     

            double dou1 = Convert.ToDouble(str1);//出错                  

               operandStack.Push(Count((char)operatorStack.Pop(), dou, dou1));          

                   }                         }                     }                 }

            }         

    return (double)operandStack.Pop();    

     }     

    //判断字符是否为操作数    

     private static bool IsPerand(char c)     

    {             bool flag = false;//不执行    

         switch (c)        

     {            

     case'.':       

          case '0':      

           case '1':       

          case '2':        

         case '3':          

       case '4':           

      case '5':         

        case '6':       

          case '7':        

         case '8':          

       case '9':         

            flag = true;     

                break;         

    }          

   return flag;      

   }        

//获取操作符入栈前的优先级  

       private static int PriorityBeforeIn(char _opertor)    

     {           

  int priority = -1;        

     switch (_opertor)        

     {             

    case '#':        

             priority = 0;           

          break;           

      case '(':           

          priority = 8;           

          break;          

       case '^':              

       priority = 6;           

          break;         

        case '*':        

         case '/':        

         case '%':        

             priority = 4;       

              break;           

      case '+':           

      case '-':           

          priority = 2;     

                break;         

        case ')':          

           priority = 1;     

                break;          

       default:           

          break;         

    }           

  return priority;    

     }       

  //获取操作符入站后的优先级

        private static int priorityAferIn(char _operator)     

    {          

   int priority = -1;     

        switch (_operator)   

          {              

   case '#':          

           priority = 0;       

              break;          

       case '(':                

     priority = 1;           

          break;             

    case '^':               

      priority = 7;             

        break;            

     case '*':            

     case '/':            

     case '%':         

            priority = 5;       

              break;           

      case '+':             

    case '-':           

          priority = 3;        

             break;            

     case ')':                

     priority = 8;          

           break;           

      default:              

       break;         

    }         

    return priority;     

    }      

   //按照指定操作对两个数字进行相应的计算

        private static double  Count(char _operator, double  a, double b)     

    {          

   double result = 0;      

       switch (_operator)       

      {             

    case '^':         

            result = (double)Math.Pow(b, a);    

                 break;         

        case '*':             

        result = b * a;            

         break;           

      case '/':            

         result = b / a;     

                break;         

        case '%':              

       result = b % a;       

              break;          

       case '+':             

        result = b + a;        

             break;           

      case '-':                

     result = b - a;          

           break;            

     default:             

        break;          

   }             return result;   

  }    

  }

}

 

posted on 2013-11-30 23:04  小马哥~程序之美  阅读(1034)  评论(0编辑  收藏  举报

导航