《面向對象程式設計》——寒假作業3
1.合作者
林燊 031602325 https://www.cnblogs.com/linshen/
盧澤明 031602328 http://www.cnblogs.com/luzeming/
github連結(https://github.com/Travaill/arithmetic.git)
2.設計思路

3.程式功能
- 能對0--10之間的整數進行四則運算(加減乘除)
- 能實作選擇中文和英文兩種語言
- 程式能接收使用者輸入的整數答案,并判斷對錯
- 程式結束時,統計出答對、答錯的題目數量
4.算法分析
- 類generate 實作随機算式的生成
- 類calculate 計算算式的結果
- 類control 控制題目生成的數量 控制生成符合要求的算式 控制程式的 退出 控制程式的語言
- 類printf 輸出算式、判斷結果、統計答題情況
5.代碼規範
- 函數的命名必須使用英文單詞,不使用拼音縮寫
- 函數的命名如果一個單詞的必須首字母大寫,如果多個單詞的用下劃線隔開
- 程式結構清析,簡單易懂,單個函數的程式行數不得超過100行。
- 要随意定義全局變量,盡量使用局部變量。
- 函數的旁邊必須注釋上本函數的功能
- 禁止GOTO語句。
6.代碼展示
代碼部分較長,是以僅截取程式最為核心的部分
随機生成表達式
#include "generate.h"
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <string>
#include <sstream>
#include <string.h>
using namespace std;
int Generate::generate_rand(int low,int high) //生成[low,high]随機數
{
return (rand()% (high - low+1) + low);
}
string Generate::generate_operator(void) //生成四則運算符
{
string ope;
switch(generate_rand(1,4))
{
case 1:ope='+'; break;
case 2:ope='-'; break;
case 3:ope='*'; break;
case 4:ope='/'; break;
}
return ope;
}
string Generate::generate_polynomial(void) //生成多項式
{
int a,b,c;
stringstream ss;
a=generate_rand(0,10);
b=generate_rand(0,10);
c=generate_rand(1,3);
if(c==1)
{
ss << '(' << a<<generate_operator()<<b<<')';
}
if(c==2)
{
ss<<a<< generate_operator()<<b;
}
if(c==3)
{
ss<<a;
}
string str = ss.str();
ss.str("");
return str;
}
string Generate::generate_formula(void) //生成算式
{
stringstream ss;
ss<<generate_polynomial();
for(int i=1;i<generate_rand(2,4);i++)
{
ss<<generate_operator()<<generate_polynomial();
}
string str = ss.str();
ss.str("");
return str;
}
計算表達式結果
#include "calculate.h"
#include "generate.h"
#include <iostream>
#include <stdlib.h>
#include <string>
#include <stack>
using namespace std;
stack<double> num_stk;
stack<char> ope_stk;
void Calculate::calculate_polynomial() //計算多項式結果
{
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 Calculate::Rank(char x) //計算優先級
{
if(x=='(')
return 0;
else if(x=='+')
return 1;
else if(x=='-')
return 2;
else if(x=='*')
return 3;
else if(x=='/')
return 4;
}
double Calculate::calculate_formula(string str) //計算算式
{
int x=0;
int num_flag=0;
for(int i=0;i<str.size();i++)
{
if((str[i]>='0')&&(str[i]<='9'))
{
x=x*10+str[i]-'0';
num_flag=1;
if(i==str.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(str[i]);
else if(str[i]=='(')
ope_stk.push(str[i]);
else if(str[i]==')')
{
while(ope_stk.top()!='(')
calculate_polynomial();
ope_stk.pop();
}
else if((Rank(str[i]))<=Rank(ope_stk.top()))
{
calculate_polynomial();
ope_stk.push(str[i]);
}
else
{
ope_stk.push(str[i]);
}
}
}
while(!ope_stk.empty())
calculate_polynomial();
double res=num_stk.top();
return res;
}
過濾不符合要求的表達式
string Control::judge_formula(void) //生成的算式是否合法
{
string str=Generate().generate_formula();
char ptr[35];
strcpy(ptr,str.c_str());
const char *substr1="/0";
const char *substr2="/(1-1)";
const char *substr3="/(2-2)";
const char *substr4="/(3-3)";
const char *substr5="/(4-4)";
const char *substr6="/(5-5)";
const char *substr7="/(6-6)";
const char *substr8="/(7-7)";
const char *substr9="/(8-8)";
const char *substr10="/(9-9)";
const char *substr11="/(10-10)";
const char *substr12="0*";
const char *substr13="0/";
char *s1 = strstr(ptr, substr1);
char *s2 = strstr(ptr, substr2);
char *s3 = strstr(ptr, substr3);
char *s4 = strstr(ptr, substr4);
char *s5 = strstr(ptr, substr5);
char *s6 = strstr(ptr, substr6);
char *s7 = strstr(ptr, substr7);
char *s8 = strstr(ptr, substr8);
char *s9 = strstr(ptr, substr9);
char *s10 = strstr(ptr, substr10);
char *s11 = strstr(ptr, substr11);
char *s12 = strstr(ptr, substr12);
char *s13 = strstr(ptr, substr13);
if(s1==NULL&&s2==NULL&&s3==NULL&&s4==NULL&&s5==NULL&&s6==NULL&&s7==NULL&&s8==NULL&&s9==NULL&&s10==NULL&&s11==NULL&&s12==NULL&&s13==NULL)
{
return str;
}
else
{
return judge_formula();
}
}
string Control::judge_result(void) //判斷結果是否為整數
{
string str=Control().judge_formula();
double res=Calculate().calculate_formula(str);
if((int)res==res)
{
return str;
}
else
{
return Control().judge_result();
}
}
7.合作證明
8.程式測試結果
9.代碼規範
- 函數的命名如果一個單詞的必須首字母大寫并且具有實際意義,如果多個單詞的用下劃線隔開
- 每一個重點步驟需要有注釋(預設為中文注釋)
10.個人體會
這一次作業對于初學c++的我來說确實是個挺大的挑戰,難怪之前老師叫我們看面向對象的教學視訊。我大概看了一些。然後開始和小夥伴思考該怎麼寫,小夥伴很贊,一下子想到了幾個重點(随機數生成,生成算式和計算結果).而我就負責算式計算的實作。中途遇到過很多不懂的地方,也由請教同學和百度得知(百度是個好東西)。在這裡也感謝林燊同學,因為我隻寫了一部分代碼,很多都是他做的,thank you!