C# 簡易計算器
阿新 • • 發佈:2017-09-14
reading collect 實現 ole back left ica can pen
編寫如下界面的簡易計算器界面代碼:
using System; using System.Windows.Forms; using exp; namespace calculator { public partial class Form1 : Form { public Form1() { InitializeComponent(); } enum symbol { plus,dec,mult,div}; private void button1_Click(objectView Codesender, EventArgs e) { Button currentButton = sender as Button; if(currentButton!= null) { textBox1.Text += currentButton.Text; } } private void equal_Click(object sender, EventArgs e) {//string text = textBox1.Text; // string[] value = text.Split(new char[4] { ‘+‘,‘-‘,‘x‘,‘/‘}); //foreach (string i in value) MessageBox.Show(i); //com.change(); compute cs = new compute(textBox1.Text); cs.PostFix(); textBox1.Text=cs.scanpost().ToString(); } private void clear_Click(object sender, EventArgs e) { textBox1.Text = ""; } } }
功能實現:(創建computeexp類文件)
思路:數字以及運算符按鈕共享一個點擊事件,則文本框裏的字符串為中綴表達式,將中綴表達式求值返回值到文本框即可。
在computeexp類中初始化操作符棧stack等,然後編寫方法轉化為後綴表達式,然後對後綴表達式求值
轉化為後綴表達式string:
掃描中綴表達式,對於多位數字依次添加到string中,並在每個數字結束後添加空格作為數字的分界,對於操作符按照其優先級判斷是否添加到stack或string中,註意括號()不出現在後綴表達式內。
優先級高的要先計算,所以運算符stack棧頂元素的優先級最高,因為要先pop出來先進行計算
後綴求值:
掃描後綴表達式,處理字符型數字為demical類型,進操作數棧,遇到運算符,從操作數棧中彈出兩個數運算,計算結果再次push操作數棧,直至掃描結束,同時操作數棧頂即為最後結果
問題:對於dowhile()循環條件的編寫不清楚
1.do while 先執行一次在判斷循環條件是否成立,成立繼續執行,不成立跳出循環
2.註意:在進行按照string位數掃描時,如果是多位數字,如何讓下一次遍歷的位數正確,不出現沒有掃描到操作符的問題,導致後綴表達式多個數字分 界符導致錯誤
功能實現代碼:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace exp { class compute { private string exp; private string postexp; private Stack<char> oper=new Stack<char>(); private Stack<decimal> opernum=new Stack<decimal>(); public compute() { exp = "((34.51+5x2)+3)/5+6/4x2+3"; exp += ‘#‘; postexp = ""; oper.Push(‘#‘); } public int prority(char c) { if (c == ‘x‘ || c == ‘/‘) return 3; if (c == ‘+‘ || c == ‘-‘) return 2; // if (c == ‘)‘) return 0; if (c == ‘(‘) return 1;//遇到(直接入棧 if (c == ‘#‘) return 0; return -1; } public void PostFix() { int i = 0; while(i<exp.Length) { if (exp[i]==‘#‘) { while(true) { if (oper.Peek() == ‘#‘) break; char tem = oper.Peek(); postexp += tem; oper.Pop(); } } else { if (exp[i] >= ‘0‘ && exp[i] <= ‘9‘) {//若為操作數 postexp += exp[i]; //加上小數點和多位數 while (exp[i + 1] >= ‘0‘ && exp[i + 1] <= ‘9‘) { i++; postexp += exp[i]; } postexp += ‘ ‘; } else {//若為其他符號 switch (exp[i]) { case ‘(‘: oper.Push(exp[i]); break; case ‘)‘: while (true) { if (oper.Peek() == ‘(‘) break; char cur = oper.Peek(); postexp += cur; oper.Pop(); } oper.Pop(); break; case ‘.‘: postexp = postexp.Substring(0,postexp.Length-1);//截取字符串 postexp += ‘.‘;break; default: if (prority(oper.Peek()) < prority(exp[i])) oper.Push(exp[i]); else { while (true) { if (prority(exp[i]) > prority(oper.Peek())) break; char tem = oper.Peek(); postexp += tem; oper.Pop(); } oper.Push(exp[i]); } break; }//switch }//numelse }//#else i++; }//while }//函數 public void show() { Console.WriteLine(exp); Console.WriteLine(postexp); } public decimal computepost(char c) { decimal first, second,res=0; second = opernum.Pop();//第二操作數 first = opernum.Pop();//第一操作數 if (c == ‘+‘) res = first + second; if (c == ‘-‘) res = first - second; if (c == ‘x‘) res = first * second; if (c == ‘/‘) res = first / second; return res; } public decimal scanpost() { int i = 0; while (i <= postexp.Length - 1) { if(postexp[i]>=‘0‘&&postexp[i]<=‘9‘) {//讀到操作數 decimal num = 0; string nu =""; nu += postexp[i]; while(postexp[i+1]!=‘ ‘) { i++; nu += postexp[i]; } num = Convert.ToDecimal(nu); opernum.Push(num); } else if(postexp[i]!=‘ ‘) {//讀到操作符或空格 opernum.Push(computepost(postexp[i])); } i++; } Console.WriteLine("result="+opernum.Peek()); return oper.Peek(); } } }View Code
C# 簡易計算器