2017《面向对象程序设计》课程作业六

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);
};
原文地址:https://www.cnblogs.com/linshen/p/6925662.html