1. 程式人生 > >用C#實現一個普通計算器——棧和佇列的應用

用C#實現一個普通計算器——棧和佇列的應用

這是大二上學期課設的一道題,我當時剛好學習了C#,C#窗體應用程式的介面程式碼和業務程式碼是分開的,這比其他同學使用的C++MFC要方便很多,分享給你,希望對你有幫助。閱讀本文並加以實現的話,需要有一定的C#程式設計基礎,當然,程式碼裡面計算中綴表示式的方法還是值得一看的。
在編輯區它是這樣子的:
這裡寫圖片描述

注意右側的解決方案資源管理器中的檔案,後面會一個一個粘上來~~~

在看看執行時的效果吧:
這裡寫圖片描述

如果瞭解C#窗體應用程式,實現起來應該是不會有問題的,我下面就開始貼程式碼了,敲黑板~~~我們的重點在棧和佇列的應用

Form1.cs

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 計算器的設計與實現CSharp { public partial class Form1 : Form { public Form1() { InitializeComponent(); } string
input=""; /// <summary> /// 監聽輸入函式 /// </summary> /// <param name="c">輸入的字元</param> void Input(char c) { input += c; } /// <summary> /// 顯示函式 /// </summary> void ShowMessage() { txtBox.Text = input; } #region
監聽輸入
private void btn1_Click(object sender, EventArgs e) { Input('1'); ShowMessage(); } private void btn2_Click(object sender, EventArgs e) { Input('2'); ShowMessage(); } private void btn3_Click(object sender, EventArgs e) { Input('3'); ShowMessage(); } private void btn4_Click(object sender, EventArgs e) { Input('4'); ShowMessage(); } private void btn5_Click(object sender, EventArgs e) { Input('5'); ShowMessage(); } private void btn6_Click(object sender, EventArgs e) { Input('6'); ShowMessage(); } private void btn7_Click(object sender, EventArgs e) { Input('7'); ShowMessage(); } private void btn8_Click(object sender, EventArgs e) { Input('8'); ShowMessage(); } private void btn9_Click(object sender, EventArgs e) { Input('9'); ShowMessage(); } private void btn0_Click(object sender, EventArgs e) { Input('0'); ShowMessage(); } private void btnAdd_Click(object sender, EventArgs e) { Input('+'); ShowMessage(); } private void btnSubtruct_Click(object sender, EventArgs e) { Input('-'); ShowMessage(); } private void btnRide_Click(object sender, EventArgs e) { Input('x'); ShowMessage(); } private void btnRemove_Click(object sender, EventArgs e) { Input('÷'); ShowMessage(); } private void btnDot_Click(object sender, EventArgs e) { Input('.'); ShowMessage(); } private void btnClear_Click(object sender, EventArgs e) { input = ""; txtBox.Text = ""; ShowMessage(); txtBox.ReadOnly = false; btnEqual.Enabled = true; } #endregion /// <summary> /// 判斷運算優先順序 /// </summary> /// <param name="sign"></param> /// <returns></returns> private int GetSignYouXianJi(char sign) // get sign priority { switch (sign) { case '+': case '-': return 1; case 'x': case '÷': return 2; } return -1; } /// <summary> /// 分析字尾表示式 /// </summary> /// <param name="obj">使用者輸入的資訊</param> /// <returns></returns> private char HouZhuiBiaoDaShi(string obj) { if (obj == "+") { return '+'; } else if (obj == "-") { return '-'; } else if (obj == "x") { return 'x'; } else if (obj == "÷") { return '÷'; } else { return '0'; } } /// <summary> /// 計算表示式的結果 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnEqual_Click(object sender, EventArgs e) { btnEqual.Enabled = false;//避免多次輸入"="帶來的異常 Stack<double> tempStack = new Stack<double>(); // 運算棧 Queue<string> houZhuiBiaoDaShiQueue = new Queue<string>(); // 儲存字尾表示式的佇列 Stack<char> signStack = new Stack<char>(); // 運算子棧 string tempStr = ""; // 臨時記錄輸入的數字或小數點 int objType; double tempDouble; try { #region 中綴表示式轉字尾表示式 for (int i = 0; i < input.Length; i++) { if (input[i] <= '9' && input[i] >= '0' || input[i] == '.') //找出運算數 { tempStr += input[i]; } else { if (tempStr.Length > 0) //如果符號前存在數字,則將數字新增到houZhuiBiaoDaShiQueue隊尾 { houZhuiBiaoDaShiQueue.Enqueue(tempStr); tempStr = ""; } if (signStack.Count == 0) //運算子棧為空,該運算子直接入棧 { signStack.Push(input[i]); } else //運算子棧不為空,需要判斷運算子的優先順序 { #region 判斷運算優先順序 if (GetSignYouXianJi(input[i]) > GetSignYouXianJi(signStack.Peek())) { signStack.Push(input[i]); } else { while (true) { houZhuiBiaoDaShiQueue.Enqueue(Convert.ToString(signStack.Pop())); if (signStack.Count == 0 || GetSignYouXianJi(input[i]) > GetSignYouXianJi(signStack.Peek())) break; } signStack.Push(input[i]); } #endregion } } } // end for if (tempStr.Length > 0) //將最後一個運算數新增到houZhuiBiaoDaShiQueue隊尾 { houZhuiBiaoDaShiQueue.Enqueue(tempStr); tempStr = ""; } while (signStack.Count > 0)//將所有運算子依次新增到隊尾,形成字尾表示式 { houZhuiBiaoDaShiQueue.Enqueue(Convert.ToString(signStack.Pop())); } #endregion signStack.Clear(); tempStr = ""; #region 計算字尾表示式 while (houZhuiBiaoDaShiQueue.Count > 0) { objType = HouZhuiBiaoDaShi(houZhuiBiaoDaShiQueue.Peek()); switch (objType) { case '0': // 如果是運算數,則直接入棧(並在字尾表示式佇列中移除該運算數) tempStack.Push(Convert.ToDouble(houZhuiBiaoDaShiQueue.Dequeue())); break; case '+': houZhuiBiaoDaShiQueue.Dequeue();//在後綴表示式佇列中移除該運算子 tempStack.Push(tempStack.Pop() + tempStack.Pop()); break; case '-': houZhuiBiaoDaShiQueue.Dequeue(); tempDouble = tempStack.Pop();//提取出減數 tempStack.Push(tempStack.Pop() - tempDouble); break; case 'x': houZhuiBiaoDaShiQueue.Dequeue(); tempStack.Push(tempStack.Pop() * tempStack.Pop()); break; case '÷': houZhuiBiaoDaShiQueue.Dequeue(); tempDouble = tempStack.Pop();//提取出除數 if (tempDouble != 0) { tempStack.Push(tempStack.Pop() / tempDouble); } else { MessageBox.Show("Error: 0是被除數!"); } break; default: MessageBox.Show("未知錯誤!"); break; } } #endregion input += "=" + Convert.ToString(tempStack.Pop()); ShowMessage(); txtBox.ReadOnly = true; } catch (Exception) { MessageBox.Show("請輸入正確的運算式!"); throw; } } } }

當時我正好看了設計模式這本書,下面的程式碼有點走架構風,不過感覺也不影響理解

Operation.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 計算器的設計與實現CSharp
{
    public class Operation:Form1
    {
        public double NumberA { get; set; }
        public double NumberB { get; set; }
        public virtual double GetResult()
        {
            double result = 0;
            return result;
        }

    }
}

OperationAdd.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 計算器的設計與實現CSharp
{
    public class OperationAdd : Operation
    {
        public override double GetResult()
        {
            return NumberA + NumberB;
        }

    }
}

OperationRemove.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 計算器的設計與實現CSharp
{
   public class OperationRemove:Operation
    {
        public override double GetResult()
        {
            if (NumberB!=0.0)
            {
                return NumberA / NumberB;
            }
            else
            {
                return 0;
            }
        }

    }
}

OperationRide.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 計算器的設計與實現CSharp
{
    public class OperationRide:Operation
    {
        public override double GetResult()
        {
            return NumberA * NumberB;
        }

    }
}

OperationSubtruct.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 計算器的設計與實現CSharp
{
    public class OperationSubtruct : Operation
    {
        public override double GetResult()
        {
            return NumberA - NumberB;
        }

    }
}


自我感覺註釋寫得很清楚了,希望對你有幫助~~~