2017《面向对象程序设计》课程作业六
github连接:https://github.com/Travaill/arithmetic.git
题目描述
- 本次作业要求将四则运算的核心部分采取栈的知识进行解决。即表达式生成的合法性检验、表达式结果计算。
- 学习C++界面编程,可以学QT、MFC或者VS,选择其一即可,用博客记录学习到的知识以及心得体会。
作业要求
- 本次作业要求实现核心算法,请将表达式生成的代码及相关的检验、计算表达式结果的代码贴在博客中,并对代码进行必要的解释。
- 发表一篇博客,博客内容为:提供本次作业的github链接,本次程序运行的截图,对界面编程的探索。
计算表达式的代码展示
#pragma once
#include<string>
#include <stack>
#include"Control.h"
using namespace std;
class CExpression
{
public:
void InitExpression();
string GetExpression();
int GetResult();
friend bool CControl::JudgeExpression(string str);
friend bool CControl::JudgeResult(double res);
private:
string exp;
double res;
stack<double> num_stk;
stack<char> ope_stk;
int RandomNumber(int low, int high);
char RandomOperation();
void RandomExpression();
void CalculateResult();
void CalculatePolynomial();
int OpeRank(char x);
};
void CExpression::CalculateResult()
{
int x = 0;
int num_flag = 0;
for (int i = 0; i<exp.size(); i++)
{
if ((exp[i] >= '0') && (exp[i] <= '9'))
{
x = x * 10 + exp[i] - '0';
num_flag = 1;
if (i == exp.size() - 1)
num_stk.push(x);
}
else {
if (x)
{
num_stk.push(x);
x = 0;
num_flag = 0;
}
if (ope_stk.empty())
ope_stk.push(exp[i]);
else if (exp[i] == '(')
ope_stk.push(exp[i]);
else if (exp[i] == ')')
{
while (ope_stk.top() != '(')
CalculatePolynomial();
ope_stk.pop();
}
else if ((OpeRank(exp[i])) <= OpeRank(ope_stk.top()))
{
CalculatePolynomial();
ope_stk.push(exp[i]);
}
else
{
ope_stk.push(exp[i]);
}
}
}
while (!ope_stk.empty())
CalculatePolynomial();
res = num_stk.top();
}
void CExpression::CalculatePolynomial()
{
char ope = ope_stk.top();
double a, b, res;
b = num_stk.top();
num_stk.pop();
a = num_stk.top();
num_stk.pop();
switch (ope)
{
case '+':res = a + b; break;
case '-':res = a - b; break;
case '*':res = a*b; break;
case '/':res = a / b; break;
default: break;
}
num_stk.push(res);
ope_stk.pop();
}
int CExpression::OpeRank(char x)
{
switch (x)
{
case '*':
case '/': return 3;
case '-':
case '+': return 2;
case '(': return 1;
case ')': return -2;
default:return -1;
}
}
由于表达的生成部分是使用字符串流格式化生成,所以不存在,括号不匹配等问题,唯一需要检验的便是是否存在/0的情况。所以就使用字符串的查找来进行检验。没有使用栈,这里就不贴代码了。
目前还在进行代码的重构工作。
对于最为关键的Expression类又进行了完善
class CExpression
{
public:
void InitExpression(); //初始化
string GetExpression();
int GetResult();
friend bool CControl::JudgeExpression(string str); //判断表达式是否合法
friend bool CControl::JudgeResult(double res); //判断结果是否符合要求
private:
string exp; //表达式
double res; //结果
stack<double> num_stk; //数字栈
stack<char> ope_stk; //运算符栈
int RandomNumber(int low, int high); //随机生成数字
char RandomOperation(); //随机生成运算符
void RandomExpression(); //随机生生成表达式
void CalculateResult(); //计算表达式结果
void CalculatePolynomial();
int OpeRank(char x);
};