博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于“计算题”程序的分析和总结
阅读量:6568 次
发布时间:2019-06-24

本文共 9132 字,大约阅读时间需要 30 分钟。

这次计算题程序已收官完成,再次进行分析和总结。

 

一、设计思路

1. 从txt读取算式。

2. 将算式由中缀转后缀。

3. 计算后缀算式并与用户输入答案进行比较,答案正确提示正确,答案错误提示错误并输出正确的答案。与此同时,统计用户正确与错误的次数以及题目的总数量。

4. 重复,直到算式全部计算完成,输出统计的正确错误数和题目的总数量。

 

二、具体实现

本程序运用了面向对象的设计思路。经过资料搜索,我发现有很多参考的程序。它们已经实现了中缀转后缀并输出正确结果并统计正误的功能,但无法计算分数。因此,我在此基础上进行了改进,增加了一个Fraction类。其把所有的整数都转换成了分数形式,并且重载了所有的运算符。之后,在重用的程序中把所有的定义的变量都定义为Fraction类型的就可以了。

以下是新增的Fraction类。

#pragma once#include 
using namespace std;class Fraction{public: Fraction(); Fraction(int n); Fraction(int n, int d); ~Fraction(); int numerator; int denominator; Fraction operator + (Fraction f); Fraction operator - (Fraction f); Fraction operator * (Fraction f); Fraction operator / (Fraction f); bool operator == (Fraction f); friend istream &operator >> (istream &in, Fraction &f); friend ostream &operator << (ostream &out, Fraction &f); void reduction(); int get_gcd(int a, int b);};

 

#include "stdafx.h"#include "Fraction.h"Fraction::Fraction(){}Fraction::Fraction(int n) :numerator(n), denominator(1){}Fraction::Fraction(int n, int d) : numerator(n), denominator(d){}Fraction::~Fraction(){}Fraction Fraction::operator + (Fraction f) {    return Fraction(numerator * f.denominator + denominator * f.numerator, denominator * f.denominator);}Fraction Fraction::operator - (Fraction f) {    return Fraction(numerator * f.denominator - denominator * f.numerator, denominator * f.denominator);}Fraction Fraction::operator * (Fraction f) {    return Fraction(numerator * f.numerator, denominator * f.denominator);}Fraction Fraction::operator / (Fraction f) {    return Fraction(numerator * f.denominator, denominator * f.numerator);}bool Fraction::operator == (Fraction f) {    return numerator == f.numerator && denominator == f.denominator;}istream& operator >> (istream &in, Fraction &f) {    in >> f.numerator;    f.denominator = 1;    char c;    in.get(c);    if (c != '\n')    {        in >> f.denominator;    }    return in;}ostream& operator << (ostream &out, Fraction &f) {    f.reduction();    if (f.denominator == 1)        out << f.numerator;    else        out << f.numerator << "/" << f.denominator;    return out;}void Fraction::reduction() {    int gcd = get_gcd(numerator, denominator);    numerator = numerator / gcd;    denominator = denominator / gcd;    if (denominator < 0)    {        numerator = -numerator;        denominator = -denominator;    }}int Fraction::get_gcd(int a, int b){    if (b == 0)        return a;    return get_gcd(b, a%b);}

 

以下是网上参考的只能进行整数运算的程序的改进。

#pragma once#include "Fraction.h"class Expression{public:    Fraction    Operand;                char        Operator  = NULL;            };#include "stdafx.h"#include "Expression.h"/#pragma once#include "Expression.h"#include 
#include
class Calculator{private: stack
is; stack
ps; Expression InfixExp[100]; Expression PostfixExp[100]; int il; int pl; bool GetInfixExp(); bool Transform(); bool GetTwoOperands(Fraction &opd1, Fraction &opd2); bool Compute(char op); ifstream ifs, ifs_line;public: Calculator(); ~Calculator(); void Run();};#include "stdafx.h"#include "Calculator.h"Calculator::Calculator(){ Run();}Calculator::~Calculator(){}bool Calculator::GetInfixExp() { char c; int newOperand; bool lastExpIsNum = false; bool nextNumAddMinus = false; char printExp[128]; ifs_line.getline(printExp, 128); cout << printExp << " "; while (ifs >> c, c != '=') { switch (c) { case '-': if (lastExpIsNum) { InfixExp[il].Operator = c; } else { nextNumAddMinus = true; il--; } lastExpIsNum = false; break; case '+': case '*': case '/': case '(': InfixExp[il].Operator = c; lastExpIsNum = false; break; case ')': InfixExp[il].Operator = c; lastExpIsNum = true; break; default: if (c >= '0' && c <= '9') { ifs.putback(c); ifs >> newOperand; newOperand = nextNumAddMinus ? -newOperand : newOperand; nextNumAddMinus = false; InfixExp[il].Operand = Fraction(newOperand); } else { return false; } lastExpIsNum = true; break; } il++; } return true;}bool Calculator::Transform() { bool flag; for (int i = 0; i < il; i++) { if (InfixExp[i].Operator == NULL) { PostfixExp[pl].Operand = InfixExp[i].Operand; pl++; } else if (InfixExp[i].Operator == '(') { is.push('('); } else if (InfixExp[i].Operator == ')') { if (is.empty()) { return false; } else { flag = false; while (!is.empty()) { if (is.top() != '(') { PostfixExp[pl].Operator = is.top(); is.pop(); pl++; } else { flag = true; is.pop(); break; } } if (is.empty() && !flag) { return false; } } } else { while ( !is.empty() && is.top() != '(' && !((is.top() == '+' || is.top() == '-') && (InfixExp[i].Operator == '*' || InfixExp[i].Operator == '/')) ) { PostfixExp[pl].Operator = is.top(); is.pop(); pl++; } is.push(InfixExp[i].Operator); } } while (!is.empty()) { if (is.top() == '(') { return false; } else { PostfixExp[pl].Operator = is.top(); is.pop(); pl++; } } return true;}bool Calculator::GetTwoOperands(Fraction& opd1, Fraction& opd2) { if (ps.empty()) return false; opd1 = ps.top(); ps.pop(); if (ps.empty()) return false; opd2 = ps.top(); ps.pop(); return true;}bool Calculator::Compute(char op) { bool result; Fraction operand1, operand2; result = GetTwoOperands(operand1, operand2); if (result) { switch (op) { case '+': ps.push(operand2 + operand1); break; case '-': ps.push(operand2 - operand1); break; case '*': ps.push(operand2 * operand1); break; case '/': if (operand1.numerator == 0) { cout << "除数存在0,错误!" << endl; return false; } else { ps.push(operand2 / operand1); } break; } } return true;}void Calculator::Run() { ifs = ifstream("Expressions.txt"); ifs_line = ifstream("Expressions.txt"); Fraction correct_answer, user_answer; int correct_num = 0, wrong_num = 0; // 输入中缀表达式 cout << "请计算下列算式:" << endl; while (!ifs_line.eof()) { il = 0; pl = 0; while (!is.empty()) is.pop(); while (!ps.empty()) ps.pop(); for (int i = 0; i < 100; i++) { InfixExp[i] = PostfixExp[i] = Expression(); } if (GetInfixExp() && Transform()) { for (int i = 0; i < pl; i++) { if (PostfixExp[i].Operator == NULL) ps.push(PostfixExp[i].Operand); else { if (!Compute(PostfixExp[i].Operator)) return; } } correct_answer = ps.top(); } else { cout << "算式格式错误" << endl; return; } cin >> user_answer; user_answer.reduction(), correct_answer.reduction(); if (user_answer == correct_answer) { correct_num++; cout << "正确" << endl; } else { wrong_num++; cout << "错误,正确答案是" << correct_answer << endl; } } cout << "--------------------------" << endl; cout << "共" << correct_num + wrong_num << "题,"; cout << "正确" << correct_num << "道,错误" << wrong_num << "道" << endl;}

 

三、项目总结

这次项目,对我改进程序的能力有了提升。每个程序并不是一定要从零开始。我们可以利用他人的的思路和成果,再次基础上进行改进。同时,我们也应多和他人进行交流,因为这样可以更方便地获取新鲜高端的思路,对项目的完成有所广益。

转载于:https://www.cnblogs.com/xDan/p/5295773.html

你可能感兴趣的文章
linux 常用find命令
查看>>
C#使用sqlite的遇到的问题
查看>>
Unix环境高级编程(二十一)数据库函数库
查看>>
Javascript获取最近若干个月
查看>>
fcitx输入法在wps、wineqq中失灵问题的解决
查看>>
集合元素顺序的实现
查看>>
webpack热更新实现
查看>>
如何在Window下安装node\npm\cnpm,并安装vue.js,创建项目
查看>>
两个像素,
查看>>
有损,无损,
查看>>
tableview 展开
查看>>
谎言,
查看>>
redis缓存存在的隐患及其解决方案
查看>>
table中嵌套table,如何用jquery来控制奇偶行颜色
查看>>
转:Comparable vs Comparator in Java
查看>>
十一:外观模式详解(Service,action与dao)
查看>>
iOS 模仿微信的照片选择器
查看>>
SDUSTOJ 1801 LIS2(最长上升子序列不同值的数量)
查看>>
菱形开合的实现 IOS
查看>>
app.listen(3000)与app是不一样的
查看>>