c#实验,写一个计算器,输入表达式,求值。用到了栈和字符优先级,下面我是由中序遍历转化为后序,也就是逆波兰式求值...界面不是很复杂..
实现思路可以参考这里:http://www.cnblogs.com/souso/articles/1643365.html
直接贴上代码..
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace LgmCalculator { public partial class Form1 : Form { public Form1() { InitializeComponent(); BindEvent(); } private void Form1_Load(object sender, EventArgs e){} private void button1_Click(object sender, EventArgs e) { if (sender is Button) { Button btn = sender as Button; if(btn==btn0||btn==btn1||btn==btn2||btn==btn3||btn==btn4|| btn==btn5||btn==btn6||btn==btn7||btn==btn8||btn==btn9|| btn==btnAdd||btn==btnAddSub||btn==btnSub||btn==btnMul|| btn==btnDiv||btn==btnLeft||btn==btnRight||btn==btnPnt){ textBox1.Text += btn.Text; }else if(btn==btnSin||btn==btnCos||btn==btnTg||btn==btnLn||btn==btnSqrt){ textBox1.Text+=btn.Text; } else if (btn == btnPow) { textBox1.Text+="^"; } else if (btn == btnBack) { if (textBox1.Text.Length > 0) { textBox1.Text = textBox1.Text.Substring(0,textBox1.Text.Length-1); } } else if (btn == btnClear) { textBox1.Clear(); } else if (btn == btnCal) { //计算 double result = 0; Console.WriteLine(textBox1.Text); string[] str = splitText(textBox1.Text); for (int k = 0; k < str.Length; k++) { Console.WriteLine("str[" + k + "]=" + str[k]); } Calculate(str, out result); Console.WriteLine("Result="+result); textBox2.Text = result.ToString(); } } } public string[] splitText(string str) { StringBuilder str1 = new StringBuilder(str.Trim()); string[] str2 = new string[100]; int count = 0; char ch = ' '; for (int i = 0; i < str.Length; ) { StringBuilder sb = new StringBuilder(); ch = str1[i]; if (char.IsDigit(ch) || ch.Equals('.')) { while (char.IsDigit(ch) || ch.Equals('.')) { sb.Append(ch); i++; if (i >= str.Length) break; ch = str1[i]; } str2[count++] = sb.ToString(); } else if (char.IsLetter(ch)) { while (char.IsLetter(ch)) { sb.Append(ch); i++; if (i >= str.Length) break; ch = str1[i]; } if (sb.ToString().Equals("sqrt") || sb.ToString().Equals("sin") || sb.ToString().Equals("cos") || sb.ToString().Equals("tg") || sb.ToString().Equals("ln")) { str2[count++] = sb.ToString(); } else { MessageBox.Show("输入错误"); } } else { if (ch.Equals(' ')) { i++; } else if (ch.Equals('-') || ch.Equals('+') || ch.Equals('*') || ch.Equals('/') || ch.Equals('(') || ch.Equals(')') || ch.Equals('^')) { str2[count++] = ch.ToString(); i++; } } } for (int l = 0; l < count; l++) { Console.WriteLine("str2["+l+"]="+str2[l]); } string []result = new string[count]; int posResult = 0; double tmp; Stack<string> stack = new Stack<string>(); stack.Push("#"); for (int i = 0; i < count; i++) { if (double.TryParse(str2[i], out tmp)) { result[posResult++] = str2[i]; } else if (str2[i].Equals("(")){ stack.Push(str2[i]); } else if (str2[i].Equals(")")){ string strtmp = stack.Pop(); while(!strtmp.Equals("(")) { result[posResult++] = strtmp; strtmp = stack.Pop(); } if(stack.Peek().Equals("sin")||stack.Peek().Equals("cos")||stack.Peek().Equals("tg")||stack.Peek().Equals("ln")){ result[posResult++] = stack.Pop(); } }else if(Precedence(stack.Peek())<Precedence(str2[i])){ stack.Push(str2[i]); }else if(Precedence(stack.Peek())>=Precedence(str2[i])){ if (!(Precedence(stack.Peek()) == Precedence(str2[i]) && Precedence(stack.Peek()) == 3)) { result[posResult++] = stack.Pop(); while (Precedence(stack.Peek()) >= Precedence(str2[i])) { result[posResult++] = stack.Pop(); } } stack.Push(str2[i]); } } while (!stack.Peek().Equals("#")) { result[posResult++] = stack.Pop(); } string []str3 = new string[posResult]; for (int k = 0; k < posResult; k++) { str3[k] = result[k]; Console.WriteLine("str3["+k+"]="+str3[k]); } return str3; } public bool Calculate(string[]str,out double result){ Stack<string> stack = new Stack<string>(); double data1,data2; result = 0; stack.Push(str[0]); for (int i = 1; i < str.Length; i++) { if(str[i].Equals("+")||str[i].Equals("-")||str[i].Equals("*")||str[i].Equals("/")||str[i].Equals("^")){ data1 = Convert.ToDouble(stack.Pop()); data2 = Convert.ToDouble(stack.Pop()); stack.Push(Operator(data2,str[i],data1).ToString()); } else if (str[i].Equals("sin") || str[i].Equals("cos") || str[i].Equals("tg") || str[i].Equals("ln") || str[i].Equals("sqrt") || str[i].Equals("!")) { data1 = Convert.ToDouble(stack.Pop()); stack.Push(Operator(data1, str[i]).ToString()); } else { stack.Push(str[i].ToString()); } } result = Convert.ToDouble(stack.Pop()); return true; } public double Operator(double a,string sign,double b=0){ switch (sign) { case "+": return a + b; case "-": return a - b; case "*": return a * b; case "/": return a / b; case "^": return Math.Pow(a,b); case "sqrt": return Math.Sqrt(a); case "sin": return Math.Sin(a); case "cos": return Math.Cos(a); case "tg": return Math.Tan(a); case "ln": return Math.Log(Math.E,a); default: return 0; } } public int Precedence(string sign) { switch (sign) { case "#": return 0; case "+": case "-": return 1; case "*": case "/": return 2; case "^": return 3; case "sin": case "cos": case "sqrt": case "tg": case "ln": return 4; default: return 0; } } public void BindEvent() { foreach (Control ctl in groupBox1.Controls) { if (ctl is Button) { ctl.Click += new EventHandler(button1_Click); } } } } }