这是大二上学期课设的一道题,我当时刚好学习了C#,C#窗体应用程序的界面代码和业务代码是分开的,这比其他同学使用的C++MFC要方便很多,分享给你,希望对你有帮助。阅读本文并加以实现的话,需要有一定的C#编程基础,当然,代码里面计算中缀表达式的方法还是值得一看的。
在编辑区它是这样子的:
注意右侧的解决方案资源管理器中的文件,后面会一个一个粘上来~~~
如果了解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