题目要求:
1.程序可以判断用户的输入答案是否正确,如果错误,给出正确答案,如果正确,给出提示。
2.程序可以处理四种运算的混合算式。
3.要求两人合作分析,合作编程,单独撰写博客。
团队成员:张绍佳、杜文星(博客:http://www.cnblogs.com/duwenxing/p/5294508.html)
设计思路:
代码分写于不同的文件中;
① head.h:在头文件head.h中,将其他.cpp文件中所需要的头文件、全局变量的声明、函数的声明都写在此文件中。
② fraction.cpp:此文件中主要定义了一些与分数有关的函数,如分数的生成化简、加减乘除、分数的输出、分数转字符串等。
③ stack.cpp:此文件的主要功能是将所给的运算式的结果计算出来,主要思路是利用栈先将运算式转化为后缀式,然后再利用栈将后缀式的结果求出,重难点是转化后缀式时如何将真分数当做一个整体,我们的解决方法是通过识别 “(” 和 “)” 来识别;同时在计算时即使是整数我们也将其转化为分数处理,故调用了fraction中的一些方法来进行加减乘除。
④yunsuan.cpp:这个文件的主要功能是实现运算式的生成,并判断使用者输入的结果和题目的答案是否相同来判断对错,并输出正确数与错误数。
⑤main.cpp:主函数所在的头文件,主要功能是和用户进行交互。
工作照:
代码:
head.h
1 #pragma once 2 #include<iostream> 3 #include<ctime> 4 #include<strstream> 5 #include<stdlib.h> 6 #include<vector> 7 #include<string> 8 #include<cstdio> 9 #include<cmath> 10 #define random(l,h) (rand()%(h-l+1)+l)//宏定义 11 #define maxsize 1000 12 using namespace std; 13 extern int flag; 14 /*stack.cpp*/ 15 struct Fraction 16 { 17 int up, down; 18 string high, low; 19 }; 20 void trans(string exp, char postexp[]); 21 Fraction compvalue(char postexp[]);//计算后缀表达式的值 22 /*fraction.cpp*/ 23 int gcd(int a, int b);//求a,b的最大公约数 24 int max(int a, int b); 25 int min(int a, int b); 26 Fraction fraction(int up, int down);//生成分数 27 Fraction fra(int d, int u);//生成真分数; 28 Fraction reduction(Fraction result);//分数的化简 29 Fraction add(Fraction f1, Fraction f2);//分数的加法 30 Fraction minus1(Fraction f1, Fraction f2);//分数的减法 31 Fraction multi(Fraction f1, Fraction f2);//分数的乘法 32 Fraction divide(Fraction f1, Fraction f2);//分数的除法 33 void ShowResult(Fraction f);//输出分数 34 string FraToString(Fraction f);//将分数转换为string类型 35 /*yunsuan.cpp*/ 36 int suiji(int down, int up);//随机生成1至n的整数 37 bool is_unique(string str, vector <string> s);//判断生成的运算式是否重复 38 void yunsuan(int time, int low, int high, int fl1, int fl2, int fl3);
fraction.cpp
1 #include"head.h" 2 int gcd(int a, int b)//求a,b的最大公约数 3 { 4 if (b == 0) return a; 5 else return gcd(b, a%b); 6 } 7 8 int max(int a, int b)//返回两个整数中较大的整数 9 { 10 int h = a >= b ? a : b; 11 return h; 12 } 13 int min(int a, int b)//返回两个整数中较小的整数 14 { 15 int l = a <= b ? a : b; 16 return l; 17 } 18 Fraction fraction(int up, int down)//生成分数 19 { 20 Fraction result; 21 result.up = up; 22 result.down = down; 23 strstream ss, kk; 24 ss << result.up; ss >> result.high; 25 kk << result.down; kk >> result.low; 26 return result; 27 } 28 Fraction fra(int d,int u)//生成真分数 29 { 30 Fraction result; 31 int temp1 = suiji(d, u);//调用function函数随机生成两个随机整数 32 int temp2 = suiji(d, u); 33 result.up = min(temp1, temp2); 34 result.down = max(temp1, temp2); 35 strstream s1, s2; 36 s1 << result.up; s1 >> result.high; 37 s2 << result.down; s2 >> result.low; 38 return result; 39 } 40 Fraction reduction(Fraction result)//分数的化简 41 { 42 if (result.down < 0) 43 { 44 result.up = -result.up; 45 result.down = -result.down; 46 } 47 if (result.up == 0) 48 { 49 result.down = 1; 50 } 51 else 52 { 53 int d = gcd(abs(result.up), abs(result.down)); 54 result.up /= d; 55 result.down /= d; 56 } 57 strstream s3, s4; 58 s3 << result.up; s3 >> result.high; 59 s4 << result.down; s4 >> result.low; 60 return result; 61 } 62 Fraction add(Fraction f1, Fraction f2)//分数的加法 63 { 64 Fraction result; 65 result.up = f1.up*f2.down + f1.down * f2.up; 66 result.down = f1.down*f2.down; 67 return reduction(result); 68 } 69 Fraction minus1(Fraction f1, Fraction f2)//分数的减法 70 { 71 Fraction result; 72 result.up = f1.up*f2.down - f1.down*f2.up; 73 result.down = f1.down*f2.down; 74 return reduction(result); 75 } 76 Fraction multi(Fraction f1, Fraction f2)//分数的乘法 77 { 78 Fraction result; 79 result.up = f1.up*f2.up; 80 result.down = f1.down*f2.down; 81 return reduction(result); 82 } 83 Fraction divide(Fraction f1, Fraction f2)//分数的除法 84 { 85 Fraction result; 86 result.up = f1.up*f2.down; 87 result.down = f1.down*f2.up; 88 return reduction(result); 89 } 90 void ShowResult(Fraction f)//输出分数 91 { 92 f = reduction(f); 93 if (f.down == 1) cout << f.up; 94 else cout << f.up << "\\" << f.down; 95 } 96 string FraToString(Fraction f)//将分数转换为string类型 97 { 98 string result; 99 if (f.down == 1) result = f.high; 100 else result = f.high + "\\" + f.low; 101 return result; 102 }
stack.cpp
1 #include"head.h" 2 struct 3 { 4 char data[maxsize];//存放运算符 5 int top;//栈顶指针 6 }op;//定义运算符栈 7 void trans(string exp, char postexp[])//exp[]为算数表达式,postexp[]为后缀表达式 8 { 9 char ch; 10 int i = 0, j = 0;//i作为exp的下标,j作为postexp的小标 11 op.top = -1; 12 ch = exp[i]; 13 i++; 14 while (ch != ‘\0‘)//exp表达式未扫描完时循环 15 { 16 switch (ch) 17 { 18 case‘[‘://判定为左括号 19 { 20 op.top++; 21 op.data[op.top] = ch; 22 }break; 23 case‘]‘://判定为右括号,此时将’[‘之前的运算符依次出栈并存放到postexp中 24 { 25 while (op.data[op.top] != ‘[‘) 26 { 27 postexp[j] = op.data[op.top]; 28 j++; 29 op.top--; 30 } 31 op.top--;//将’[‘删除 32 }break; 33 case‘+‘://为’+‘或’-‘时,其优先级不大于栈顶的任何运算符,直到’]‘为止 34 case‘-‘: 35 { 36 while (op.top != -1 && op.data[op.top] != ‘[‘) 37 { 38 postexp[j] = op.data[op.top]; 39 j++; 40 op.top--; 41 } 42 op.top++; 43 op.data[op.top] = ch; 44 }break; 45 case‘*‘://为’*‘或’/’时,其优先级不大于栈顶为‘*’或‘/‘的优先级,直到’[‘ 46 case‘/‘: 47 { 48 while (op.top != -1 && op.data[op.top] != ‘[‘ && (op.data[op.top] == ‘*‘ || op.data[op.top] == ‘/‘)) 49 { 50 postexp[j] = op.data[op.top]; 51 j++; 52 op.top--; 53 } 54 op.top++; 55 op.data[op.top] = ch; 56 }break; 57 case‘ ‘:break;//过滤掉空格 58 case‘(‘://将分数当成一个整体放到postexp中 59 { 60 while (ch != ‘)‘) 61 { 62 postexp[j]=ch; 63 j++; 64 ch = exp[i]; 65 i++; 66 } 67 postexp[j]=ch; j++;//将‘)‘放到postexp中 68 }break; 69 default: 70 { 71 while (ch >= ‘0‘&&ch <= ‘9‘)//判定为数字 72 { 73 postexp[j] = ch; 74 j++; 75 ch = exp[i]; 76 i++; 77 } 78 i--; 79 postexp[j] = ‘#‘;//用#标示一个数值的结束 80 j++; 81 } 82 } 83 ch = exp[i]; 84 i++; 85 } 86 while (op.top != -1)//此时exp扫描完毕,栈不空时出栈并存放到postexp中 87 { 88 postexp[j] = op.data[op.top]; 89 j++; 90 op.top--; 91 } 92 postexp[j] = ‘\0‘;//给postexp表达式添加结束标识 93 } 94 struct 95 { 96 Fraction data[maxsize];//存放数值 97 int top;//栈顶指针 98 }st; 99 Fraction compvalue(char postexp[])//计算后缀表达式的值 100 { 101 double d; 102 char ch; 103 int i = 0;//postexp的下标 104 st.top = -1; 105 ch = postexp[i]; 106 i++; 107 while (ch != ‘\0‘)//postexp字符串未扫描完事完成循环 108 { 109 switch (ch) 110 { 111 case‘+‘: 112 { 113 st.data[st.top - 1] = add(st.data[st.top - 1], st.data[st.top]); 114 st.top--; 115 }break; 116 case‘-‘: 117 { 118 st.data[st.top - 1] = minus1(st.data[st.top - 1], st.data[st.top]); 119 st.top--; 120 }break; 121 case‘*‘: 122 { 123 st.data[st.top - 1] = multi(st.data[st.top - 1], st.data[st.top]); 124 st.top--; 125 }break; 126 case‘/‘: 127 { 128 st.data[st.top - 1] = divide(st.data[st.top - 1], st.data[st.top]); 129 st.top--; 130 }break; 131 case‘(‘: 132 { 133 double high = 0, low = 0; 134 ch = postexp[i]; i++;//删除‘(‘ 135 while (ch != ‘\\‘) 136 { 137 high = 10 * high + ch - ‘0‘; 138 ch = postexp[i]; 139 i++; 140 } 141 ch = postexp[i]; i++;//删除’\’ 142 while (ch != ‘)‘) 143 { 144 low = 10 * low + ch - ‘0‘; 145 ch = postexp[i]; 146 i++; 147 } 148 st.top++; 149 Fraction re = fraction(high, low); 150 st.data[st.top] = re; 151 }break; 152 default: 153 { 154 d = 0; 155 while (ch >= ‘0‘&&ch <= ‘9‘)//将数字字符转化为对应的数值存放到d中 156 { 157 d = 10 * d + ch - ‘0‘; 158 ch = postexp[i]; 159 i++; 160 } 161 st.top++; 162 Fraction re = fraction(d, 1); 163 st.data[st.top] = re; 164 } 165 } 166 ch = postexp[i]; 167 i++; 168 } 169 return st.data[st.top]; 170 }
yunsuan.cpp
1 #include"head.h" 2 int flag = 1; 3 int suiji(int down, int up)//随机生成1至n的整数 4 { 5 int low = down, high = up; 6 if (flag) 7 { 8 flag = 0; 9 srand((unsigned)time(NULL));//种子 10 } 11 int result = random(down, up); 12 return result; 13 14 } 15 bool is_unique(string str, vector <string> s)//判断生成的运算式是否重复 16 { 17 int count = 0; 18 for (int i = 0; i < s.size(); i++) 19 { 20 if (str!=s[i]) 21 { 22 count++; 23 } 24 else break; 25 } 26 bool flag0 = count == s.size() ? true : false; 27 return flag0; 28 } 29 void yunsuan(int time, int low, int high, int fl1, int fl2, int fl3)//根据参数要求生成四则运算式 30 { 31 int integer1, integer2; 32 int ch1, ch2, ch3, ch4;//switch语句的选项 33 char sign;//运算符号 34 int times = time;//题目数 35 vector <string> str;//str用来保存生成的题目 36 int right = 0, wrong = 0; 37 for (int i = 1; i <= times;) 38 { 39 int flag4 = 1;//flag4用来标记运算式是否是刚开始生成 40 string first, second, cal;//四则运算的第一个运算数和第二个运算数 41 int number = suiji(1, 9);//number为参与运算的参数个数 42 for (int j = 1; j <= number;) 43 { 44 //------------------------------------------------------------------------------------- 45 if (fl1 == 1)//允许乘除发参与运算的情况 46 { 47 ch1 = suiji(1, 4);//随机生成运算符号 48 switch (ch1) 49 { 50 case 1:sign = ‘+‘; break; 51 case 2:sign = ‘-‘; break; 52 case 3:sign = ‘*‘; break; 53 case 4:sign = ‘/‘; break; 54 default:cout << "有错误!" << endl; break; 55 } 56 } 57 else//不允许乘除法参与运算的情况 58 { 59 ch1 = suiji(1, 2);//随机生成运算符号 60 switch (ch1) 61 { 62 case 1:sign = ‘+‘; break; 63 case 2:sign = ‘-‘; break; 64 default:cout << "有错误!" << endl; break; 65 } 66 } 67 //------------------------------------------------------------------------------------- 68 if (fl3 == 1)//允许真分数参与运算 69 { 70 ch2 = suiji(1, 3);//四则运算题目的三种情况 71 switch (ch2) 72 { 73 case 1://整数和整数 74 { 75 strstream si, so; 76 integer1 = suiji(low, high); 77 si << integer1; si >> first; 78 integer2 = suiji(low, high); 79 so << integer2; so >> second; 80 }break; 81 case 2://整数和真分数 82 { 83 strstream ss; 84 integer1 = suiji(low, high); 85 ss << integer1; ss >> first; 86 Fraction f = reduction(fra(low, high)); 87 second = "(" + f.high + "\\" + f.low + ")"; 88 }break; 89 case 3://真分数和真分数 90 { 91 Fraction f1 = reduction(fra(low, high)); 92 Fraction f2 = reduction(fra(low, high)); 93 first = "(" + f1.high + "\\" + f1.low + ")"; 94 second = "(" + f2.high + "\\" + f2.low + ")"; 95 }break; 96 default:cout << "有错误!" << endl; break; 97 } 98 } 99 else//不允许真分数参与运算 100 { 101 strstream si, so; 102 integer1 = suiji(low, high); 103 si << integer1; si >> first; 104 integer2 = suiji(low, high); 105 so << integer2; so >> second; 106 } 107 //------------------------------------------------------------------------------------- 108 if (fl2 == 1)//允许括号(【】)参与运算 109 { 110 ch4 = suiji(1, 4); 111 switch (ch4) 112 { 113 case 1: 114 { 115 if (flag4 == 1)//flag4为1表示运算式还未生成前两个运算数 116 { 117 cal = first + sign + second; 118 flag4 = 0; 119 } 120 else 121 { 122 cal = cal + sign + first;//将以生成的运算式个新生成的运算数连接起来 123 } 124 }break; 125 case 2: 126 { 127 if (flag4 == 1) 128 { 129 cal = second + sign + first; 130 flag4 = 0; 131 } 132 else 133 { 134 cal = second + sign + cal; 135 } 136 }break; 137 case 3: 138 { 139 if (flag4 == 1) 140 { 141 cal = "[" + first + sign + second + "]";//添加括号【】的情况 142 flag4 = 0; 143 } 144 else 145 { 146 cal = "[" + cal + sign + first + "]"; 147 } 148 }break; 149 case 4: 150 { 151 if (flag4 == 1) 152 { 153 cal = "[" + second + sign + first + "]"; 154 flag4 = 0; 155 } 156 else 157 { 158 cal = "[" + second + sign + cal + "]"; 159 } 160 }break; 161 default:cout << "有错误!" << endl; break; 162 } 163 } 164 else//不允许括号(【】)参与运算 165 { 166 ch4 = suiji(1, 2);//输出的两种情况 167 switch (ch4) 168 { 169 case 1: 170 { 171 if (flag4 == 1) 172 { 173 cal = first + sign + second; 174 flag4 = 0; 175 } 176 else 177 { 178 cal = cal + sign + first; 179 } 180 }break; 181 case 2: 182 { 183 if (flag4 == 1) 184 { 185 cal = second + sign + first; 186 flag4 = 0; 187 } 188 else 189 { 190 cal = second + sign + cal; 191 } 192 }break; 193 default:cout << "有错误!" << endl; break; 194 } 195 } 196 j++; 197 } 198 //------------------------------------------------------------------------------ 199 if (str.empty())//若sr为空,则将第一个生成的运算式添加到vector中 200 { 201 str.push_back(cal); 202 cout << "(" << i << ")." << cal << "="; 203 204 string answer; 205 cin >> answer; 206 char postexp[maxsize]; 207 trans(cal, postexp); 208 Fraction re = compvalue(postexp); 209 string result = FraToString(re); 210 if (answer == result) 211 { 212 cout << "正确!" << endl; 213 right++; 214 } 215 else 216 { 217 cout << "错误!,正确答案为:" << result << endl; 218 wrong++; 219 } 220 i++; 221 } 222 if (is_unique(cal, str))//判断生成的运算式和之前已经生成的运算式是否重复 223 { 224 str.push_back(cal);//将生成的运算式添加到str中 225 cout << "(" << i << ")." << cal << "="; 226 string answer; 227 cin >> answer; 228 char postexp[maxsize]; 229 trans(cal, postexp); 230 Fraction re = compvalue(postexp); 231 string result = FraToString(re); 232 if (answer == result) 233 { 234 cout << "正确!" << endl; 235 right++; 236 237 } 238 else 239 { 240 cout << "错误!,正确答案为:" << result << endl; 241 wrong++; 242 } 243 i++; 244 } 245 else {} 246 } 247 cout << "**********************************************************************************" << endl; 248 cout << "你做对了" << right << "道题,做错了" << wrong << "道题" << endl; 249 }
main.cpp
1 #include"head.h" 2 int main() 3 { 4 cout << "请输入题目数(1~100):"; 5 int times, down, up, flag1, flag2, flag3, flag4; 6 cin >> times;//times至题目数 7 cout << "请输入数值绝对值范围:"; 8 cin >> down >> up;//[down,up]为运算数范围 9 cout << "是否允许乘除发参与运算(y/n):"; 10 char yn1; 11 cin >> yn1; 12 yn1 == ‘y‘ || yn1 == ‘Y‘ ? flag1 = 1 : flag1 = 0; 13 cout << "是否允许括号([])参与运算(y/n):"; 14 char yn2; 15 cin >> yn2; 16 yn2 == ‘y‘ || yn2 == ‘Y‘ ? flag2 = 1 : flag2 = 0;//flag2判断是否允许括号参与运算 17 cout << "是否允许真分数参与运算(y/n):"; 18 char yn3; 19 cin >> yn3; 20 yn3 == ‘y‘ || yn3 == ‘Y‘ ? flag3 = 1 : flag3 = 0;//flag3判断是否允许真分数参与运算 21 cout << "**********************************************************************************" << endl; 22 yunsuan(times, down, up, flag1, flag2, flag3); 23 system("pause"); 24 return 0; 25 }
截图:
时间: 2024-10-19 02:02:01