利用Visual Studio(C++)实现简易计算器(三)

实现带有优先级的计算器

在原有代码基础上,稍加修改,利用堆栈实现四则运算
在.cpp文件中添加:

#include <stack>
using namespace std;

.h文件中定义:

public:
	CString str;    //用于存储编辑框中内容
	CString LastResult1;   
	CString LastResult2;
	CString TempStr;

.cpp文件中:

void CmyCalculatorDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Text(pDX, IDC_EDIT1, str);
	DDX_Text(pDX, IDC_EDIT2, LastResult1);
	DDX_Text(pDX, IDC_EDIT4, LastResult2);
}

设置运算符优先级:

int Lv(char m)
{
	switch (m)
	{
	case '+':
		return 1; break;
	case '-':
		return 1; break;
	case '*':
		return 2; break;
	case '/':
		return 2; break;
	case '%':
		return 2; break;
	case '(':
		return 0; break;
	case ')':
		return 0; break;
	case '!':
		return -1; break;
	default:break;
	}
}

对等号这个按键进行如下修改:

void CmyCalculatorDlg::OnBnClickedButton16()   //"="
{
	// TODO: 在此添加控件通知处理程序代码
	stack<double> X;                   //堆栈1用作存数
	stack<char> Y;                    //堆栈2用作存运算符
	CString str2;                     //str2用作拼接多位数字
	UpdateData(TRUE);                 //获取面板上的表达式
	TempStr = str;                  //用于存储历史记录
	LastResult2 = LastResult1;
	LastResult1 = TempStr;
	UpdateData(FALSE);
	str += "!?";                      //在表达式的末尾加上!?方便后面的操作
	int i = 0;                        //i从0开始,用来检索表达式
	int e = 0;                        //e用来记录表达式中左括号的数量
	int f = 0;                        //f用来记录表达式中右括号的数量
	double t;                         //t用来保存两个double运算后的结果         
	double q;                         //q用来保存string转换成double后的数
	bool adc = true;
	//开始对表达式进行入栈运算:
	while (str[i] != '?')
	{
		if (str[i] > 47 && str[i] < 58 || str[i] == '.')   //[0,9]和小数点
		{
			int F = 0;             //F用来记录小数点的个数
			for (i; str[i] > 47 && str[i] < 58 || str[i] == '.'; i++)
			{
				str2 += str[i];
				if (str[i] == '.')
				{
					F++;
				}
				if (F > 1)
				{
					//MessageBox("一个数的小数点多于一个!");
					SetDlgItemText(IDC_EDIT1, _T("一个数的小数点多于一个!"));
					return;
				}
			}
			q = _wtof(str2);
			str2 = "";
			X.push(q);
		}
		if (str[i] >= 40 && str[i] <= 47)   //包括:'('  ')' '+' '-' '*' '/' '.' ','
		{
			if (i == 0 && str[i] == '-' && adc)
			{
				i++;
				if (str[i] > 47 && str[i] < 58 || str[i] == '.')  //[0,9]和小数点
				{
					int F = 0;
					for (i; str[i] > 47 && str[i] < 58 || str[i] == '.'; i++)  //遍历
					{
						str2 += str[i];
						if (str[i] == '.')
						{
							F++;
						}
						if (F > 1)
						{
							//	MessageBox("一个数的小数点多于一个!");
							SetDlgItemText(IDC_EDIT1, _T("一个数的小数点多于一个!"));
							return;
						}
					}
					q = 0 - _wtof(str2);
					str2 = "";
					X.push(q);
					i--;
				}
				else if (str[i] == '(')  //‘(’ :40  ‘)’:41
				{
					adc = false;
					double Q = 0;
					X.push(Q);
					i = -1;
				}
			}
			else if (Y.empty() || str[i] == '(' || Lv(str[i]) > Lv(Y.top()))
			{
				Y.push(str[i]);
				if (str[i + 1] == '-')
				{
					i = i + 2;
					if (str[i] > 47 && str[i] < 58 || str[i] == '.')  //[0,9]和小数点
					{
						int F = 0;
						for (i; str[i] > 47 && str[i] < 58 || str[i] == '.'; i++)
						{
							str2 += str[i];
							if (str[i] == '.')
							{
								F++;
							}
							if (F > 1)
							{
								SetDlgItemText(IDC_EDIT1, _T("一个数的小数点多于一个!"));
								return;
							}
						}
						q = 0 - _wtof(str2);
						str2 = "";
						X.push(q);
					}
					i--;
				}

			}
			else
			{
				if (str[i] == ')')
				{
					for (; Y.top() != '('; Y.pop())
					{
						char f = Y.top();
						double a = X.top();
						if (a == 0 && f == '/' )
						{
							SetDlgItemText(IDC_EDIT1, _T("除数不能为0!"));
							return;
						}
						X.pop();
						double b = X.top();
						X.pop();
						switch (f)
						{
						case '+':t = b + a; break;
						case '-':t = b - a; break;
						case '*':t = b * a; break;
						case '/':t = b / a; break;
						default:break;
						}
						X.push(t);

					}
					Y.pop();
				}
				else
				{
					for (; !(Y.empty()) && Lv(str[i]) <= Lv(Y.top()); Y.pop())
					{
						char f = Y.top();
						double a = X.top();
						if (a == 0 && (f == '/' || f == '%'))
						{
							SetDlgItemText(IDC_EDIT1, _T("除数不能为0!"));
							return;
						}
						X.pop();
						double b = X.top();
						X.pop();
						switch (f)
						{
						case '+':t = b + a; break;
						case '-':t = b - a; break;
						case '*':t = b * a; break;
						case '/':t = b / a; break;
						default:break;
						}
						X.push(t);
					}
					Y.push(str[i]);
				}
			}
		}
		++i;
	}
	CString a;
	double I = X.top();
	X.pop();
	a.Format(_T("%lf"), I);
	SetDlgItemText(IDC_EDIT1, a);
}

成果:
在这里插入图片描述
本代码仍存在弊端,整个表达式必须要加括号才可以运算,否则运算括号里内容或输出最后输入的值,望大佬指点!

  • 2
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值