用C#实现一个普通计算器——栈和队列的应用

这是大二上学期课设的一道题,我当时刚好学习了C#,C#窗体应用程序的界面代码和业务代码是分开的,这比其他同学使用的C++MFC要方便很多,分享给你,希望对你有帮助。阅读本文并加以实现的话,需要有一定的C#编程基础,当然,代码里面计算中缀表达式的方法还是值得一看的。
在编辑区它是这样子的:
用C#实现一个普通计算器——栈和队列的应用_第1张图片

注意右侧的解决方案资源管理器中的文件,后面会一个一个粘上来~~~

在看看运行时的效果吧:
用C#实现一个普通计算器——栈和队列的应用_第2张图片

如果了解C#窗体应用程序,实现起来应该是不会有问题的,我下面就开始贴代码了,敲黑板~~~我们的重点在栈和队列的应用

(哇,还是上GitHub的地址吧,非代码的操作有点多——https://github.com/DongjinLiu/Csharp)

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="";
        /// 
        /// 监听输入函数
        /// 
        /// 输入的字符
        void Input(char c)
        {
            input += c;
        }
        /// 
        /// 显示函数
        /// 
        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

        /// 
        /// 判断运算优先级
        /// 
        /// 
        /// 
        private int GetSignYouXianJi(char sign)  // get sign priority
        {
            switch (sign)
            {
                case '+':
                case '-':
                    return 1;
                case 'x':
                case '÷':
                    return 2;
            }
            return -1;
        }

        /// 
        /// 分析后缀表达式
        /// 
        /// 用户输入的信息
        /// 
        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';
            }
        }


        /// 
        /// 计算表达式的结果
        /// 
        /// 
        /// 
        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;
        }

    }
}


自我感觉注释写得很清楚了,希望对你有帮助~~~

GitHub源码https://github.com/DongjinLiu/Csharp

你可能感兴趣的:(数据结构,C#)