c#计算器,支持+-*/()的混合运算,对负号不支持.
原理:将点击的按钮赋给inputStr,然后对inputStr分析、计算。看懂代码的重要前提是你有一定的算法基础(前缀、中缀、后缀表达式)和数据结构基础(链表、栈)。
当初写这份代码的时候还是小白,随着对C#的深入学习,个人觉得本文代码还有很多可以优化的地方。
wybing最后编辑于20190510
截图:

运行截图:

界面控制代码:
-
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 计算器
-
{
-
public
partial
class
FrmMain :
Form
-
{
-
public static List<char> inputStr=
new List<
char>(
1000);
//用户的输入
-
public FrmMain()
-
{
-
InitializeComponent();
-
}
-
-
private void Btn0_Click(object sender, EventArgs e)
-
{
-
inputStr.Add(
'0');
-
textBox1.AppendText(
"0");
-
}
-
-
private void BtnDot_Click(object sender, EventArgs e)
-
{
-
inputStr.Add(
'.');
-
textBox1.AppendText(
".");
-
}
-
-
private void Btn1_Click(object sender, EventArgs e)
-
{
-
inputStr.Add(
'1');
-
textBox1.AppendText(
"1");
-
}
-
-
private void Btn2_Click(object sender, EventArgs e)
-
{
-
inputStr.Add(
'2');
-
textBox1.AppendText(
"2");
-
}
-
-
private void Btn3_Click(object sender, EventArgs e)
-
{
-
inputStr.Add(
'3');
-
textBox1.AppendText(
"3");
-
}
-
-
private void Btn4_Click(object sender, EventArgs e)
-
{
-
inputStr.Add(
'4');
-
textBox1.AppendText(
"4");
-
}
-
-
private void Btn5_Click(object sender, EventArgs e)
-
{
-
inputStr.Add(
'5');
-
textBox1.AppendText(
"5");
-
}
-
-
private void Btn6_Click(object sender, EventArgs e)
-
{
-
inputStr.Add(
'6');
-
textBox1.AppendText(
"6");
-
}
-
-
private void Btn7_Click(object sender, EventArgs e)
-
{
-
inputStr.Add(
'7');
-
textBox1.AppendText(
"7");
-
}
-
-
private void Btn8_Click(object sender, EventArgs e)
-
{
-
inputStr.Add(
'8');
-
textBox1.AppendText(
"8");
-
}
-
-
private void Btn9_Click(object sender, EventArgs e)
-
{
-
inputStr.Add(
'9');
-
textBox1.AppendText(
"9");
-
}
-
-
private void BtnLeft_Click(object sender, EventArgs e)
-
{
-
inputStr.Add(
'(');
-
textBox1.AppendText(
"(");
-
}
-
-
private void BtnRig_Click(object sender, EventArgs e)
-
{
-
inputStr.Add(
')');
-
textBox1.AppendText(
")");
-
}
-
-
private void BtnEqual_Click(object sender, EventArgs e)
-
{
-
//等号代码
-
textBox1.AppendText(
"=");
-
textBox2.Text = textBox1.Text;
-
textBox1.Text = DataOp.DataMain();
-
-
string temp= DataOp.DataMain();
-
inputStr.Clear();
-
for(
int i =
0; i < temp.Length; i++)
-
{
-
inputStr.Add(temp[i]);
-
}
-
}
-
-
private void BtnAdd_Click(object sender, EventArgs e)
-
{
-
inputStr.Add(
'+');
-
textBox1.AppendText(
"+");
-
}
-
-
private void BtnSubt_Click(object sender, EventArgs e)
-
{
-
inputStr.Add(
'-');
-
textBox1.AppendText(
"-");
-
}
-
-
private void BtnMul_Click(object sender, EventArgs e)
-
{
-
inputStr.Add(
'*');
-
textBox1.AppendText(
"*");
-
}
-
-
private void BtnDivi_Click(object sender, EventArgs e)
-
{
-
inputStr.Add(
'/');
-
textBox1.AppendText(
"/");
-
}
-
-
private void BtnCe_Click(object sender, EventArgs e)
-
{
-
textBox1.Text =
"";
-
inputStr.Clear();
//清空链表的所有元素
-
}
-
-
private void BtnC_Click(object sender, EventArgs e)
-
{
-
//界面撤销
-
inputStr.RemoveAt(inputStr.Count
-1);
-
textBox1.Text =
"";
-
for (
int i=
0;i<inputStr.Count;i++)
-
{
-
textBox1.Text += inputStr[i];
-
}
-
}
-
}
-
}
数据操作代码:
-
using System;
-
using System.Collections.Generic;
-
using System.Linq;
-
using System.Text;
-
using System.Threading.Tasks;
-
-
namespace 计算器
-
{
-
//表达式存在inputStr中
-
class
DataOp :
FrmMain
-
{
-
static Stack<double> m =
new Stack<
double>();
//数字栈
-
static Stack<char> s =
new Stack<
char>();
//符号栈
-
public static void Read() //Read()从inputStr输入流中读值
-
{
-
for (
int i =
0; i < inputStr.Count; i++)
-
{
-
if (!IsOperator(inputStr[i]))
//数字和小数点
-
{
-
string s =
null;
-
while (i < inputStr.Count && !IsOperator(inputStr[i]))
-
{
-
s += inputStr[i];
-
i++;
-
}
-
i--;
-
double mm = Convert.ToDouble(s);
-
m.Push(mm);
-
}
-
else
if (IsOper(inputStr[i]))
//+ - * /
-
{
-
if (s.Count.Equals(
0) || s.Peek().Equals(
'('))
-
{
-
s.Push(inputStr[i]);
-
}
-
else
if (OperatorPrecedence(inputStr[i]) > OperatorPrecedence(s.Peek()))
-
{
-
s.Push(inputStr[i]);
-
}
-
else
-
{
-
double n1, n2;
-
char s1;
-
n2 = m.Pop();
-
n1 = m.Pop();
-
s1 = s.Pop();
-
double sum = Operat(n1, n2, s1);
-
m.Push(sum);
-
s.Push(inputStr[i]);
-
}
-
}
-
else
//(和)
-
{
-
if (inputStr[i].Equals(
'('))
-
{
-
s.Push(inputStr[i]);
-
}
-
else
if (inputStr[i].Equals(
')'))
-
{
-
while (!s.Peek().Equals(
'('))
-
{
-
double n1, n2;
-
char s1;
-
n2 = m.Pop();
-
n1 = m.Pop();
-
s1 = s.Pop();
-
double sum = Operat(n1, n2, s1);
-
m.Push(sum);
-
}
-
s.Pop();
-
-
}
-
}
-
}
-
}
-
public static double PopStack()
-
{
-
double sum =
0;
-
while (s.Count !=
0)
-
{
-
double n1, n2;
-
char s1;
-
n2 = m.Pop();
-
n1 = m.Pop();
-
s1 = s.Pop();
-
sum = Operat(n1, n2, s1);
-
m.Push(sum);
-
}
-
return sum;
-
}
-
public static bool IsOperator(char c) //是否是操作符
-
{
-
if (c.Equals(
'+') || c.Equals(
'-') || c.Equals(
'*') || c.Equals(
'/') || c.Equals(
'(') || c.Equals(
')'))
-
return
true;
-
return
false;
-
}
-
public static bool IsOper(char c) //是否是运算符符
-
{
-
if (c.Equals(
'+') || c.Equals(
'-') || c.Equals(
'*') || c.Equals(
'/'))
-
return
true;
-
return
false;
-
}
-
public static int OperatorPrecedence(char a) //操作符优先级
-
{
-
int i =
0;
-
switch (a)
-
{
-
case
'+': i =
3;
break;
-
case
'-': i =
3;
break;
-
case
'*': i =
4;
break;
-
case
'/': i =
4;
break;
-
}
-
return i;
-
}
-
public static double Operat(double n1, double n2, char s1)
-
{
-
double sum =
0;
-
switch (s1)
-
{
-
case
'+': sum = n1 + n2;
break;
-
case
'-': sum = n1 - n2;
break;
-
case
'*': sum = n1 * n2;
break;
-
case
'/': sum = n1 / n2;
break;
-
}
-
return sum;
-
}
-
public static string DataMain()
-
{
-
Read();
-
return PopStack().ToString();
-
}
-
}
-
}
程序源代码下载地址:https://wybing.lanzoui.com/is107ijyrha
【Bug修复】
感谢Xuuuton反馈的Bug,3*2-2*2+1出来的答案是1 。

20201119修改如下:
-
public static double PopStack()
-
{
-
/*
-
* 修复Bug 3*2-2*2+1结果为1
-
* 将两个栈逆序后再运算
-
*/
-
Stack<
double> tepM =
new Stack<
double>();
//数字栈
-
Stack<
char> tepS =
new Stack<
char>();
//符号栈
-
while (s.Count!=
0)
-
{
-
char temp;
-
temp = s.Pop();
-
tepS.Push(temp);
-
}
-
-
while (m.Count !=
0)
-
{
-
double temp;
-
temp = m.Pop();
-
tepM.Push(temp);
-
}
-
-
double sum =
0;
-
while (tepS.Count !=
0)
-
{
-
double n1, n2;
-
char s1;
-
n2 = tepM.Pop();
-
n1 = tepM.Pop();
-
s1 = tepS.Pop();
-
sum = Operat(n2, n1, s1);
-
tepM.Push(sum);
-
}
-
return sum;
-
}
关于非法表达式导致的程序异常,可以做异常处理,也可以简单判断数字栈和符号栈的Count,很显然,数字栈至少要两位以上数字,符号栈至少要一位以上,但前提要确保栈内操作数和操作符合法。
转载:https://blog.csdn.net/qq_41138935/article/details/82750974
查看评论