首页 > 代码库 > 第一周作业——小学四则运算题
第一周作业——小学四则运算题
作业要求:
写一个能自动生成小学四则运算题目的命令行 “软件”, 分别满足下面的各种需求,这些需求都可以用命令行参数的形式来指定:
a) 支持整数、真分数的四则运算。例如: 1/6 + 1/8 = 7/24
b) 逐步扩展功能和可以支持的表达式类型,最后希望能支持下面类型的题目(最多 10 个运算符,括号的数量不限制)
25 - 3 * 4 - 2 / 2 + 89 = ?
1/2 + 1/3 - 1/4 = ?
( 5 - 4 ) * ( 3 +28 ) =?
设计思路:
采用使用栈将表达式中缀转后缀的做法,求解表达式的值
对于小数型,采取double型的栈存取,其余做法与一般方法一致
对于分数型,采取字符串的形式进行存取
对于分数型,重载了+,-,*的运算规则,使其满足分数加减乘法的要求。其函数中包含了大量的字符串分割,字符串转整型等操作,最后返回一个结果的字符串
已经实现功能:
- 随机生成整数数或者分数算式,整数算式结果为小数,分数算式结果为真分数
- 真分数的四则运算,结果为真分数
- 支持括号
1 #include <iostream> 2 #include <stdlib.h> 3 #include <time.h> 4 #include <stack> 5 #include <math.h> 6 #include <string.h> 7 #include <iomanip> 8 9 using namespace std; 10 11 char basic_op_de[4]={‘+‘,‘-‘,‘*‘,‘/‘}; 12 13 unsigned char Prior_de[8][8] ={ // 运算符优先级表 14 // ‘+‘ ‘-‘ ‘*‘ ‘/‘ ‘(‘ ‘)‘ ‘#‘ ‘^‘ 15 /*+*/‘>‘,‘>‘,‘<‘,‘<‘,‘<‘,‘>‘,‘>‘,‘<‘, 16 /*-*/‘>‘,‘>‘,‘<‘,‘<‘,‘<‘,‘>‘,‘>‘,‘<‘, 17 /***/‘>‘,‘>‘,‘>‘,‘>‘,‘<‘,‘>‘,‘>‘,‘<‘, 18 /*/*/‘>‘,‘>‘,‘>‘,‘>‘,‘<‘,‘>‘,‘>‘,‘<‘, 19 /*(*/‘<‘,‘<‘,‘<‘,‘<‘,‘<‘,‘=‘,‘ ‘,‘<‘, 20 /*)*/‘>‘,‘>‘,‘>‘,‘>‘,‘ ‘,‘>‘,‘>‘,‘>‘, 21 /*#*/‘<‘,‘<‘,‘<‘,‘<‘,‘<‘,‘ ‘,‘=‘,‘<‘, 22 /*^*/‘>‘,‘>‘,‘>‘,‘>‘,‘<‘,‘>‘,‘>‘,‘ ‘, 23 }; 24 25 char graph_de[8]={‘+‘,‘-‘,‘*‘,‘/‘,‘(‘,‘)‘,‘#‘,‘^‘}; 26 27 28 bool In_de(char a,char b[7]) { //判断是否为运算符 29 int i; 30 bool c=false; 31 for(i=0;i<=7;i++) 32 { 33 if(a==b[i]) 34 c=true; 35 } 36 return c; 37 } 38 39 char Precede_de(char a,char b) {//判断优先级 40 int i,j; 41 if(a==‘+‘) i=0; 42 if(a==‘-‘) i=1; 43 if(a==‘*‘) i=2; 44 if(a==‘/‘) i=3; 45 if(a==‘(‘) i=4; 46 if(a==‘)‘) i=5; 47 if(a==‘#‘) i=6; 48 if(a==‘^‘) i=7; 49 if(b==‘+‘) j=0; 50 if(b==‘-‘) j=1; 51 if(b==‘*‘) j=2; 52 if(b==‘/‘) j=3; 53 if(b==‘(‘) j=4; 54 if(b==‘)‘) j=5; 55 if(b==‘#‘) j=6; 56 if(b==‘^‘) j=7; 57 return Prior_de[i][j]; 58 } 59 60 double Operate_de(double Num1,char b,double Num2) {//进行运算 61 double result=1; 62 switch(b){ 63 case‘+‘:return Num1+Num2;break; 64 case‘-‘:return Num1-Num2;break; 65 case‘*‘:return Num1*Num2;break; 66 case‘/‘:return Num1/Num2;break; 67 } 68 } 69 70 double EvaluateExpression_de(char* string) //求表达式的值 71 { 72 int count=0; 73 stack<double> p1; //运算数 74 stack<char> p2; 75 stack<double> *S1; 76 stack<char> *S2; //运算符 77 S1=&p1; 78 S2=&p2; 79 char temp,y,x,c,cpre=‘(‘; //prec用与记录前一个字符 80 double Num1,Num2,num; 81 char str[50]; 82 str[0]=‘\0‘; 83 int i=0; 84 85 86 temp=‘#‘; 87 S2->push(temp); 88 89 c=string[count]; 90 count++; 91 92 while(c!=‘#‘||S2->top()!=‘#‘){ 93 if(!In_de(c,graph_de)||c==‘.‘) { //是运算数 (含小数点) 94 str[i]=c; 95 i++; 96 cpre=c; 97 c=string[count]; 98 count++; 99 if(In_de(c,graph_de)){ //不是运算数了,则把字符串转化为数字后压栈 100 str[i]=‘\0‘;101 num=atof(str);102 S1->push(num); 103 i=0; //字符串初始化 104 str[i]=‘\0‘;105 }106 }107 else{108 if(cpre==‘(‘&&c==‘-‘){109 S1->push(0); 110 }111 switch(Precede_de(S2->top(),c)){112 case‘<‘:113 S2->push(c); //进栈 114 cpre=c;115 c=string[count];116 count++;117 break;118 case‘=‘:119 x=S2->top();120 S2->pop();121 cpre=c;122 c=string[count];123 count++;124 break;125 case‘>‘:126 y=S2->top();127 S2->pop();128 Num2=S1->top();129 S1->pop();130 Num1=S1->top();131 S1->pop();132 S1->push(Operate_de(Num1,y,Num2));break; //进栈 133 } 134 }135 }136 Num1=S1->top();137 S1->pop();138 return Num1;139 }140 141 char basic_op[3]={‘+‘,‘-‘,‘*‘};142 143 144 unsigned char Prior[6][6] ={ // 运算符优先级表 145 // ‘+‘ ‘-‘ ‘*‘ ‘(‘ ‘)‘ ‘#‘ 146 /*+*/‘>‘,‘>‘,‘<‘,‘<‘,‘>‘,‘>‘,147 /*-*/‘>‘,‘>‘,‘<‘,‘<‘,‘>‘,‘>‘,148 /***/‘>‘,‘>‘,‘>‘,‘<‘,‘>‘,‘>‘,149 /*(*/‘<‘,‘<‘,‘<‘,‘<‘,‘=‘,‘ ‘,150 /*)*/‘>‘,‘>‘,‘>‘,‘>‘,‘>‘,‘>‘,151 /*#*/‘<‘,‘<‘,‘<‘,‘<‘,‘ ‘,‘=‘,152 };153 154 char graph[6]={‘+‘,‘-‘,‘*‘,‘(‘,‘)‘,‘#‘};155 156 bool In(char a,char b[6]) { //判断是否为运算符157 int i;158 bool c=false;159 for(i=0;i<=5;i++)160 {161 if(a==b[i])162 c=true;163 }164 return c;165 }166 167 char Precede(char a,char b) { //判断优先级168 int i,j;169 if(a==‘+‘) i=0;170 if(a==‘-‘) i=1;171 if(a==‘*‘) i=2;172 if(a==‘(‘) i=3;173 if(a==‘)‘) i=4;174 if(a==‘#‘) i=5;175 if(b==‘+‘) j=0;176 if(b==‘-‘) j=1;177 if(b==‘*‘) j=2;178 if(b==‘(‘) j=3;179 if(b==‘)‘) j=4;180 if(b==‘#‘) j=5;181 return Prior[i][j];182 }183 int HCF(int n,int m) {//最大公约数184 int p,r,temp;185 if (n<m) {186 temp=n;187 n=m;188 m=temp; //把大数放在n中, 小数放在m中189 }190 p=n*m; //先将n和m的乘积保存在p中, 以便求最小公倍数时用191 while (m!=0){ //求n和m的最大公约数192 r=n%m;193 n=m;194 m=r;195 }196 return n;197 }198 199 int LCD(int n,int m) { //最小公倍数 200 int p,r,temp;201 if (n<m){202 temp=n;203 n=m;204 m=temp; //把大数放在n中, 小数放在m中205 }206 p=n*m; //先将n和m的乘积保存在p中, 以便求最小公倍数时用207 while (m!=0) //求n和m的最大公约数208 {r=n%m;209 n=m;210 m=r;211 }212 return p/n;213 }214 char *yuefen(int l,int r) { //约分 215 char *left=(char*)malloc(sizeof(char)*200);216 char *right=(char*)malloc(sizeof(char)*200);217 char *temp_result2=(char*)malloc(sizeof(char)*1000);218 if(HCF(l,r)!=1){//不互质219 int k=HCF(l,r);220 l=l/k;221 r=r/k;222 }223 itoa(l,left,10);224 itoa(r,right,10);225 strcpy(temp_result2,left);226 strcat(temp_result2,"/");227 strcat(temp_result2,right);228 229 230 return temp_result2;231 } 232 233 char * Operate(char* Num1,char b,char* Num2){ //进行运算234 int num1_l,num1_r,num2_l,num2_r,num3_l,num3_r;235 char *Num1_left=(char*)malloc(sizeof(char)*200);236 char *Num1_right=(char*)malloc(sizeof(char)*200);237 char *Num2_left=(char*)malloc(sizeof(char)*200);238 char *Num2_right=(char*)malloc(sizeof(char)*200);239 char *temp_result1=(char*)malloc(sizeof(char)*1000);240 241 int i=0,j; //分割字符串为4个数 242 for(i=0;Num1[i]!=‘/‘;i++){243 Num1_left[i]=Num1[i];244 } 245 Num1_left[i]=‘\0‘;246 j=i;247 for(i=0;;i++){248 Num1_right[i]=Num1[i+j+1];249 if(Num1_right[i]==‘\0‘) 250 break;251 } 252 for(i=0;Num2[i]!=‘/‘;i++){253 Num2_left[i]=Num2[i];254 } 255 Num2_left[i]=‘\0‘;256 j=i;257 for(i=0;;i++){258 Num2_right[i]=Num2[i+j+1];259 if(Num2_right[i]==‘\0‘) 260 break;261 } 262 263 num1_l=atoi(Num1_left); //字符串转整型数字 264 num1_r=atoi(Num1_right);265 num2_l=atoi(Num2_left);266 num2_r=atoi(Num2_right);267 268 switch(b){269 case‘+‘: 270 if(num1_r==num2_r){ //同分母271 num1_l=num1_l+num2_l; 272 strcpy(temp_result1,yuefen(num1_l,num1_r));273 } 274 else{ //分母不同275 num3_r=LCD(num1_r,num2_r); //通分后的分母276 num1_l=num1_l*num3_r/num1_r;277 num2_l=num2_l*num3_r/num2_r;278 num3_l=num1_l+num2_l; //通分之后的分子279 strcpy(temp_result1,yuefen(num3_l,num3_r));280 } 281 break;282 283 case‘-‘:284 if(num1_r==num2_r){ //同分母285 num1_l=num1_l-num2_l;286 strcpy(temp_result1,yuefen(num1_l,num1_r));287 } 288 else{ //分母不同289 num3_r=LCD(num1_r,num2_r); //通分后的分母290 num1_l=num1_l*num3_r/num1_r;291 num2_l=num2_l*num3_r/num2_r;292 num3_l=num1_l-num2_l; //通分之后的分子293 strcpy(temp_result1,yuefen(num3_l,num3_r));294 } 295 break;296 case‘*‘:297 num3_r=num1_r*num2_r;298 num3_l=num1_l*num2_l;299 strcpy(temp_result1,yuefen(num3_l,num3_r)); 300 break;301 }302 303 return temp_result1;304 } 305 306 char* EvaluateExpression(char* string){ //求表达式的值 307 int str_counter;308 char **str= (char**)malloc(sizeof(char*)*20); //存储运算数的字符串载体 309 for(str_counter=0; str_counter<20; str_counter++) {310 str[str_counter] = (char*)malloc(sizeof(char)*200);311 str[str_counter][0]=‘\0‘; //初始化 312 } 313 str_counter=0;314 315 int temp_result_counter;316 char ** temp_result=(char**)malloc(sizeof(char)*20); //作为中间运算结果的载体 317 for(temp_result_counter=0; temp_result_counter<20; temp_result_counter++) {318 temp_result[temp_result_counter] = (char*)malloc(sizeof(char)*1000);319 temp_result[temp_result_counter][0]=‘\0‘; //初始化 320 } 321 temp_result_counter=0;322 323 int count=0;324 stack<char *> p1; //运算数 325 stack<char> p2;326 stack<char *> *S1; 327 stack<char> *S2; //运算符 328 S1=&p1;329 S2=&p2;330 char temp,y,x,c,cpre=‘(‘; //cpre用于记录前一个字符 331 char * Num1=(char*)malloc(sizeof(char)*200);332 char * Num2=(char*)malloc(sizeof(char)*200); 333 334 int i=0;335 336 temp=‘#‘;337 S2->push(temp);338 339 c=string[count];340 count++;341 342 while(c!=‘#‘||S2->top()!=‘#‘){343 if(!In(c,graph)) //是运算数 (含小数点)344 {345 str[str_counter][i]=c;346 i++;347 cpre=c;348 c=string[count];349 count++;350 if(In(c,graph)){ //不是运算数了,则把字符串转化为数字后压栈 351 str[str_counter][i]=‘\0‘;352 S1->push(str[str_counter]); //压栈的不是内容,是地址 353 str_counter++;354 i=0;355 }356 }357 else{ //运算符 358 359 switch(Precede(S2->top(),c)){360 case‘<‘:361 S2->push(c); //进栈 362 cpre=c;363 c=string[count];364 count++;365 break;366 case‘=‘:367 x=S2->top();368 S2->pop();369 cpre=c;370 c=string[count];371 count++;372 break;373 case‘>‘:374 y=S2->top();375 S2->pop();376 strcpy(Num2,S1->top());377 S1->pop();378 strcpy(Num1,S1->top());379 S1->pop();380 strcpy(temp_result[temp_result_counter],Operate(Num1,y,Num2)); //修改中间结果 381 S1->push(temp_result[temp_result_counter]);382 temp_result_counter++;383 break; 384 } 385 }386 }387 strcpy(Num1,S1->top());388 S1->pop();389 return Num1; 390 }391 392 393 int main()394 {395 int swi;396 cout<<"-----------欢迎使用小学生计算器---------\n"<<endl;397 cout<<"--------------输入1;小数计算---------\n"<<endl;398 cout<<"--------------输入2;分数计算---------\n"<<endl;399 cout<<"--------------输入0;退出---------\n"<<endl;400 401 cout<<"你的选择:";402 cin>>swi;403 if(swi==0) return 0; 404 else if(swi==1){405 int count ,left ,right ,op_num,LR,temp;406 double result;407 double stu_answer;408 409 char *op=(char *)malloc(sizeof(char)*3); 410 char *left_string=(char *)malloc(sizeof(char)*200);411 char *temp_string=(char *)malloc(sizeof(char)*1000);412 413 srand(time(0));414 temp=rand()%20+1;415 itoa(temp,temp_string,10);416 417 for(count=1;count<=5;count++){ 418 419 op_num=rand()%4;420 op[0]=basic_op_de[op_num];421 op[1]=‘\0‘;422 LR=rand()%2;423 if(LR==0){ //上一步的表达式在左侧424 425 left=rand()%20+1;426 itoa(left,left_string,10);427 strcat(temp_string,op);428 strcat(temp_string,left_string);429 } 430 else{ //上一步的表达式在右侧431 432 433 left=rand()%20+1;434 itoa(left,left_string,10);435 strcat(left_string,op);436 strcat(left_string,temp_string);437 strcpy(temp_string,left_string);438 }439 LR=rand()%5;440 if(LR<=1){ //加括号441 442 char zuokuohao[200]="(",youkuohao[4]=")";443 strcat(zuokuohao,temp_string);444 strcat(zuokuohao,youkuohao);445 strcpy(temp_string,zuokuohao) ;446 } 447 448 } 449 450 cout<<"题目是:"<<temp_string<<endl<<endl; 451 452 strcat(temp_string,"#");453 454 result=EvaluateExpression_de(temp_string);455 456 cout<<"请输入你的答案:(保留两位小数) ";457 cin>>stu_answer;458 cout<<endl<<"正确答案为: "<<setprecision(2) <<std::fixed<<result<<endl<<endl;459 if(result==stu_answer)460 cout<<"恭喜你,答对了"<<endl<<endl;461 else462 cout<<"答错了,没关系,这道题有点难"<<endl<<endl;463 464 465 } 466 if(swi==2){467 int count ,left ,right ,op_num,LR,temp;468 469 char *op=(char *)malloc(sizeof(char)*3); 470 char *left_string=(char *)malloc(sizeof(char)*200);471 char *right_string=(char *)malloc(sizeof(char)*200);472 char *temp_string=(char *)malloc(sizeof(char)*1000);473 char *temp_string_right=(char *)malloc(sizeof(char)*200);474 char *result=(char *)malloc(sizeof(char)*1000);475 476 char stu_answer[100];477 478 srand(time(0));479 temp=rand()%20+1;480 itoa(temp,temp_string,10);481 strcat(temp_string,"/");482 temp=rand()%50+1;483 itoa(temp,temp_string_right,10);484 strcat(temp_string,temp_string_right);485 486 for(count=1;count<=5;count++){487 488 489 op_num=rand()%3;490 op[0]=basic_op[op_num];491 op[1]=‘\0‘;492 LR=rand()%2;493 if(LR==0){ //上一步的表达式在左侧494 495 right=rand()%50+1;496 itoa(right,right_string,10);497 left=rand()%20+1;498 itoa(left,left_string,10);499 strcat(temp_string,op);500 strcat(temp_string,left_string);501 strcat(temp_string,"/");502 strcat(temp_string,right_string);503 } 504 else{ //上一步的表达式在右侧505 506 right=rand()%50+1;507 itoa(right,right_string,10);508 left=rand()%20+1;509 itoa(left,left_string,10);510 strcat(left_string,"/");511 strcat(left_string,right_string);512 strcat(left_string,op);513 strcat(left_string,temp_string);514 strcpy(temp_string,left_string);515 }516 LR=rand()%5;517 if(LR<=1){ //加括号518 519 char zuokuohao[200]="(",youkuohao[4]=")";520 strcat(zuokuohao,temp_string);521 strcat(zuokuohao,youkuohao);522 strcpy(temp_string,zuokuohao) ;523 } 524 525 } 526 cout<<"题目是:"<<temp_string<<endl<<endl; 527 528 strcat(temp_string,"#");529 530 strcpy(result,EvaluateExpression(temp_string));531 532 cout<<"请输入你的答案: ";533 cin>>stu_answer;534 cout<<endl<<"正确答案为: "<<result<<endl<<endl;535 if(strcmp(result,stu_answer)==0)536 cout<<"恭喜你,答对了"<<endl<<endl;537 else538 cout<<"答错了,没关系,这道题超纲了"<<endl<<endl;539 }540 541 }
运行截图:
结果为小数
结果为分数
第一周作业——小学四则运算题
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。