[转载]数据结构中用C#实现"表达式计算"

    技术2022-05-11  134

    最近重新翻起以前学的数据结构,原来是用C写的,今天用C#重新回温一下,加深一点印象.

    目前还不支持单目操作符,只支持双目的,以后改进吧.:)

    using System;using System.Drawing;using System.Collections;using System.ComponentModel;using System.Windows.Forms;using System.Data;

    namespace Expression1{ /// <summary> /// Form1 的摘要说明。 /// </summary> public class Form1 : System.Windows.Forms.Form {  private System.Windows.Forms.Label label1;  private System.Windows.Forms.Label label2;  private System.Windows.Forms.TextBox txtInfix;  private System.Windows.Forms.TextBox txtPostfix;  private System.Windows.Forms.Button btnPostfix;  private System.Windows.Forms.Button btnCalc;  private System.Windows.Forms.TextBox txtCalc;  /// <summary>  /// 必需的设计器变量。  /// </summary>  private System.ComponentModel.Container components = null;

      public Form1()  {   //   // Windows 窗体设计器支持所必需的   //   InitializeComponent();

       //   // TODO: 在 InitializeComponent 调用后添加任何构造函数代码   //  }

      /// <summary>  /// 清理所有正在使用的资源。  /// </summary>  protected override void Dispose( bool disposing )  {   if( disposing )   {    if (components != null)     {     components.Dispose();    }   }   base.Dispose( disposing );  }

      #region Windows 窗体设计器生成的代码  /// <summary>  /// 设计器支持所需的方法 - 不要使用代码编辑器修改  /// 此方法的内容。  /// </summary>  private void InitializeComponent()  {   this.txtInfix = new System.Windows.Forms.TextBox();   this.txtPostfix = new System.Windows.Forms.TextBox();   this.btnPostfix = new System.Windows.Forms.Button();   this.label1 = new System.Windows.Forms.Label();   this.label2 = new System.Windows.Forms.Label();   this.btnCalc = new System.Windows.Forms.Button();   this.txtCalc = new System.Windows.Forms.TextBox();   this.SuspendLayout();   //    // txtInfix   //    this.txtInfix.Location = new System.Drawing.Point(88, 24);   this.txtInfix.Name = "txtInfix";   this.txtInfix.Size = new System.Drawing.Size(176, 21);   this.txtInfix.TabIndex = 0;   this.txtInfix.Text = "";   //    // txtPostfix   //    this.txtPostfix.Location = new System.Drawing.Point(88, 88);   this.txtPostfix.Name = "txtPostfix";   this.txtPostfix.Size = new System.Drawing.Size(176, 21);   this.txtPostfix.TabIndex = 1;   this.txtPostfix.Text = "";   //    // btnPostfix   //    this.btnPostfix.FlatStyle = System.Windows.Forms.FlatStyle.System;   this.btnPostfix.Location = new System.Drawing.Point(120, 56);   this.btnPostfix.Name = "btnPostfix";   this.btnPostfix.TabIndex = 2;   this.btnPostfix.Text = "转化";   this.btnPostfix.Click += new System.EventHandler(this.btnPostfix_Click);   //    // label1   //    this.label1.Location = new System.Drawing.Point(8, 24);   this.label1.Name = "label1";   this.label1.Size = new System.Drawing.Size(72, 23);   this.label1.TabIndex = 3;   this.label1.Text = "中缀表达式";   this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;   //    // label2   //    this.label2.Location = new System.Drawing.Point(8, 88);   this.label2.Name = "label2";   this.label2.Size = new System.Drawing.Size(72, 23);   this.label2.TabIndex = 4;   this.label2.Text = "后缀表达式";   this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;   //    // btnCalc   //    this.btnCalc.FlatStyle = System.Windows.Forms.FlatStyle.System;   this.btnCalc.Location = new System.Drawing.Point(24, 136);   this.btnCalc.Name = "btnCalc";   this.btnCalc.TabIndex = 5;   this.btnCalc.Text = "计算结果";   this.btnCalc.Click += new System.EventHandler(this.btnCalc_Click);   //    // txtCalc   //    this.txtCalc.Location = new System.Drawing.Point(120, 136);   this.txtCalc.Name = "txtCalc";   this.txtCalc.Size = new System.Drawing.Size(144, 21);   this.txtCalc.TabIndex = 6;   this.txtCalc.Text = "";   //    // Form1   //    this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);   this.ClientSize = new System.Drawing.Size(292, 182);   this.Controls.Add(this.txtCalc);   this.Controls.Add(this.btnCalc);   this.Controls.Add(this.label2);   this.Controls.Add(this.label1);   this.Controls.Add(this.btnPostfix);   this.Controls.Add(this.txtPostfix);   this.Controls.Add(this.txtInfix);   this.MaximizeBox = false;   this.Name = "Form1";   this.Text = "表达式计算";   this.ResumeLayout(false);

      }  #endregion

      /// <summary>  /// 应用程序的主入口点。  /// </summary>  [STAThread]  static void Main()   {   Application.EnableVisualStyles();   Application.DoEvents();   Application.Run(new Form1());  }

      private void btnPostfix_Click(object sender, System.EventArgs e)  {   try   {    Calculator calc = new Calculator(this.txtInfix.Text.Replace(" ",""));    this.txtPostfix.Text = calc.PostFix();   }   catch(Expressception ex)   {    MessageBox.Show(ex.Message);   }  }

      private void btnCalc_Click(object sender, System.EventArgs e)  {   try   {    Calculator calc = new Calculator(this.txtInfix.Text.Replace(" ",""));    this.txtCalc.Text = calc.Run().ToString();   }   catch(Expressception ex)   {    MessageBox.Show(ex.Message);   }  } }

     public class Calculator {  private string _expression;  private Stack s;

      public Calculator(string expression)  {   this._expression = expression;   s = new Stack();  }

      public double Run()  {   string expression=PostFix();   string[] aryString = expression.Split('|');

       foreach(string str in aryString)   {    if(IsNumber(str))    {     double d = Convert.ToDouble(str.ToString());     AddOperands(d);    }    else    {     DoOperator(str);    }

       }   return (double)s.Pop();  }

      private bool IsNumber(string str)  {   if(str.Length>1)   {    return true;   }   else   {    return Char.IsDigit(str[0]);   }  }

      private void AddOperands(double val)  {   s.Push(val);  }

      private bool Get2Operands(out double left,out double right)  {      try   {    right = (double)s.Pop();    left = (double)s.Pop();   }   catch(InvalidOperationException)   {    right = 0;    left = 0;    return false;   }   return true;  }

      private void DoOperator(string op)  {   double left,right;   bool result = Get2Operands(out left,out right);   if(result)    switch(op)    {     case "+": s.Push(left+right); break;     case "-": s.Push(left-right); break;     case "*": s.Push(left*right); break;     case "/":      if(right == 0.0)      {       s.Clear();       //Divide by 0!       throw new Expressception("除数不能为零");             }      else       s.Push(left/right);      break;     case "^":      s.Push(Math.Pow(left,right));      break;    }   else    s.Clear();  }

      public string PostFix()  {   string str = this._expression+"#";   char tempc;   char[] chars = str.ToCharArray();   Stack ts = new Stack();   ts.Push('#');   string str1="";   string tmpStr="";   bool isNum = false;   foreach(char c in chars)   {    if(Char.IsDigit(c)||c=='.')    {     tmpStr += c.ToString();     isNum = true;    }    else    {     if(isNum)     {      str1 += tmpStr+"|";      tmpStr = "";      }     isNum=false;     if(c == ')')     {      for(tempc = Convert.ToChar(ts.Pop());tempc!='(';tempc = Convert.ToChar(ts.Pop()))       str1+=tempc.ToString()+"|";     }     else     {      for(tempc = Convert.ToChar(ts.Pop());Isp(tempc)>Icp(c);tempc = Convert.ToChar(ts.Pop()))       str1+=tempc.ToString()+"|";      ts.Push(tempc);      ts.Push(c);     }    }   }   return str1.Substring(0,str1.Length-1);  }

      private int Isp(char c)  {   int k;   switch(c)   {    case '#': k=0; break;    case '(': k=1; break;    case '^': k=7; break;    case '*':    case '/':    case '%': k=5; break;    case '+':    case '-': k=3; break;    case ')': k=8; break;    default:     //Unknown operator!     throw new Expressception("不知道的操作符!");   }   return k;  }

      private int Icp(char c)  {   int k;   switch(c)   {    case '#': k=0; break;    case '(': k=8; break;    case '^': k=6; break;    case '*':    case '/':    case '%': k=4; break;    case '+':    case '-': k=2; break;    case ')': k=1; break;    default:     //Unknown operator!     throw new Expressception("不知道的操作符!");   }   return k;  }

     }

     public class Expressception : Exception {  public Expressception(string msg) : base(msg)  {  } }


    最新回复(0)