四则运算2
四则运算2
我这次程序是在上次的基础上修改而来,因为技术问题,我就暂时只考虑整数的四则运算,忽略了真分数的运算。
我的思路大体如下:
1、使用string数组记录比较避免重复,并用stringstream ss记录每一个一个算式。
2、选择个数的多少(修改N的值),选择输出方式(屏幕打印/输出到文本)
3、是否有乘除法,可以将分为加减和加减乘除两个方式
4、是否有括号,利用递归来实现
5、数值范围,通过修改基础算式里的min和max值来修改随机产生的值
6、加减有无负数,无负数,即不让出现小减大的情况,出现就交换位置。
7、除法有无余数,即第一个数对第二个数取余应该为0
//王文奇 四则运算2 #include<iostream> #include<fstream> #include<string> #include<iomanip> #include<sstream> #include <time.h> using namespace std; #define maxN 100 //设置最大缓冲区个数 int MulDlvIsExist; //是否有乘除法 int AddSubIsNeg;//加减是否有负数 int DlvIsRem;//除法是否有余数 int min; //最小数 int max; //最大数 int N;//输出题目的个数 int first, second; double result; stringstream ss; //设置一个算式的缓冲区 string buffer[maxN] ;//设置所有算式的缓冲区 int print; //打印方式 string oper(string op) { int c; c = 1 + rand() % 4; //产生1~4以内的随机整数 if (MulDlvIsExist == 1)//有乘除法 { c = 1 + rand() % 4; //产生1~4以内的随机整数 } else //默认无乘除法 { c = 1 + rand() % 2; //产生1~2以内的随机整数 } switch (c) { case 1:op = "+";break; case 2:op = "-"; break; case 3:op = "×"; break; case 4:op = "÷"; break; default: break; } return op; } void equation() //生成一个基础算式 { string op; int temp; first = min+rand() % (max-min+1); //产生第一个min~max以内的随机整数 second = min + rand() % (max - min +1); //产生第二个min~max以内的随机整数 op=oper(op); if (AddSubIsNeg == 0 && op == "-"&&first<second)//无负数,即不让出现小减大的情况 { temp = first; first = second; second = temp;//交换 } while (op == "÷"&&second == 0) //除数不能为0 { second = min + rand() % (max - min + 1); //产生第二个min~max以内的随机整数 } while (DlvIsRem == 0 && op == "÷"&&second == 0 && (first%second != 0)) //无余数,即第一个与第二个数取余必须为0 { first = min + rand() % (max - min + 1); //产生第一个min~max以内的随机整数 second = min + rand() % (max - min + 1); //产生第二个min~max以内的随机整数 } //cout << setw(3) << first << setw(3) <<op<< setw(3) << second << setw(3); ss << setw(3) << first << setw(3) << op << setw(3) << second << setw(3); } void equationN(int bracketNum) //递归实现加括号 { string op; if (bracketNum <= 0) { equation(); //cout << "=" << endl; ss << "=" << endl; } else if (bracketNum > 0) { //cout << "("; ss << "("; equation(); //cout << ")"; ss << ")"; op=oper(op); if (bracketNum >= 1) { //cout << op; ss << op; } bracketNum--; equationN(bracketNum); } } void equationNo(int bracketNum) //递归实现无括号 { string op; if (bracketNum <= 0) { equation(); //cout << "=" << endl; ss << "=" << endl; } else if (bracketNum > 0) { equation(); if (bracketNum >= 1) { //cout << oper(op); ss << oper(op); } bracketNum--; equationNo(bracketNum); } } bool repeat(string ss1, int i) //判断是否重复,重复返回true,不重复返回false { bool flag = true;//默认是重复的 int j; for (j = 0; j < i; j++) { if (ss1 == buffer[j]) { flag = true; break; } else { flag = false; } } return flag; } void main() { int bracket,bracketNum,Num; srand((unsigned)time(NULL)); //做一个时间种子 cout << "请输入是否有乘除法(0、无 1、有):" << endl; cin >> MulDlvIsExist; cout << "请输入是否有无括号(0、无 1、有):" << endl; cin >> bracket; cout << "请输入数值范围(请先输入最小数,再输入最大数,请保证两个数均为大于等于0的数!):" << endl; cin >> min>>max; cout << "请输入加减结果是否有负数(0、无 1、有):" << endl; cin >> AddSubIsNeg; if (MulDlvIsExist == 1) { cout << "请输入乘除结果是否有余数(0、无 1、有):" << endl; cin >> DlvIsRem; } cout << "请输入题目的个数:" << endl; cin >> N; cout << "请选择打印的方式(0、输出到文本 1、屏幕打印):" << endl; cin >> print; if (print == 1) { for (int i = 0; i < N; i++) { bracketNum = 1 + rand() % 4; //产生1~4以内的随机整数,作为括号个数 Num = 0 + rand() % 4; //产生0~4以内的随机整数,加1乘2作为操作数的个数 cout << "第" << setw(2) << i + 1 << "题:"; if (bracket == 1)//有括号 { equationN(bracketNum); while (repeat(ss.str(), i) && (i>0))//当他重复时且不是第一个时循环,直到不重复为止 { ss.str(""); equationN(bracketNum); } buffer[i] = ss.str(); cout << ss.str(); ss.str("");//清空ss的缓冲区 } else//默认无括号 { equationNo(Num); while (repeat(ss.str(), i) && (i>0))//当他重复时且不是第一个时循环,直到不重复为止 { ss.str(""); equationNo(Num); } buffer[i] = ss.str(); cout << ss.str(); ss.str("");//清空ss的缓冲区 } } } else if (print == 0) { string file; cout << "请输入输出文件格式:(如:D:\\print.txt)" << endl; cin >> file; ofstream outfile(file, ios::out); if (!outfile) { cerr << "创建失败!" << endl; exit(1); } for (int i = 0; i < N; i++) { bracketNum = 1 + rand() % 4; //产生1~4以内的随机整数,作为括号个数 Num = 0 + rand() % 4; //产生0~4以内的随机整数,加1乘2作为操作数的个数 outfile << "第" << setw(2) << i + 1 << "题:"; if (bracket == 1)//有括号 { equationN(bracketNum); while (repeat(ss.str(), i) && (i>0))//当他重复时且不是第一个时循环,直到不重复为止 { ss.str(""); equationN(bracketNum); } buffer[i] = ss.str(); outfile << ss.str(); ss.str("");//清空ss的缓冲区 } else//默认无括号 { equationNo(Num); while (repeat(ss.str(), i) && (i>0))//当他重复时且不是第一个时循环,直到不重复为止 { ss.str(""); equationNo(Num); } buffer[i] = ss.str(); outfile << ss.str(); ss.str("");//清空ss的缓冲区 } } outfile.close(); } }
以下是运行结果:
项目计划总结:
时间记录日志:
缺陷记录日志:
总结:我只是勉强大体上实现了基本功能,具体的加减有无负数在两个括号之间很难实现,除法有无余数虽然写了方法,但是似乎并不能完全实现功能。总之,我会在以后继续改进的。
PS:这是我周日后续修改的代码,解决了括号内能否整除的问题,但对括号外的还是无法判断。
1 //王文奇 四则运算2 2 #include<iostream> 3 #include<fstream> 4 #include<string> 5 #include<iomanip> 6 #include<sstream> 7 #include <time.h> 8 using namespace std; 9 #define maxN 100 //设置最大缓冲区个数 10 11 int MulDlvIsExist; //是否有乘除法 12 int AddSubIsNeg;//加减是否有负数 13 int DlvIsRem;//除法是否有余数 14 int min; //最小数 15 int max; //最大数 16 int N;//输出题目的个数 17 int first, second; 18 double result; 19 stringstream ss; //设置一个算式的缓冲区 20 string buffer[maxN] ;//设置所有算式的缓冲区 21 int print; //打印方式 22 23 string oper(string op) 24 { 25 int c; 26 c = 1 + rand() % 4; //产生1~4以内的随机整数 27 if (MulDlvIsExist == 1)//有乘除法 28 { 29 c = 1 + rand() % 4; //产生1~4以内的随机整数 30 } 31 else //默认无乘除法 32 { 33 c = 1 + rand() % 2; //产生1~2以内的随机整数 34 } 35 switch (c) 36 { 37 case 1:op = "+";break; 38 case 2:op = "-"; break; 39 case 3:op = "×"; break; 40 case 4:op = "÷"; break; 41 default: break; 42 } 43 44 return op; 45 } 46 47 void equation() //生成一个基础算式 48 { 49 string op; 50 51 int temp; 52 first = min+rand() % (max-min+1); //产生第一个min~max以内的随机整数 53 second = min + rand() % (max - min +1); //产生第二个min~max以内的随机整数 54 op=oper(op); 55 if (AddSubIsNeg == 0 && op == "-"&&first<second)//无负数,即不让出现小减大的情况 56 { 57 temp = first; 58 first = second; 59 second = temp;//交换 60 } 61 while (op == "÷"&&second == 0) //除数不能为0 62 { 63 second = min + rand() % (max - min + 1); //产生第二个min~max以内的随机整数 64 } 65 if (DlvIsRem == 0) 66 { 67 while (op == "÷" && (first%second != 0)) //无余数,即第一个与第二个数取余必须为0 68 { 69 first = min + rand() % (max - min + 1); //产生第一个min~max以内的随机整数 70 second = min + 1 + rand() % (max - min + 1); //产生第二个min+1~max以内的随机整数 71 } 72 } 73 //cout << setw(3) << first << setw(3) <<op<< setw(3) << second << setw(3); 74 ss << setw(3) << first << setw(3) << op << setw(3) << second << setw(3); 75 } 76 77 void equationN(int bracketNum) //递归实现加括号 78 { 79 string op; 80 if (bracketNum <= 0) 81 { 82 equation(); 83 //cout << "=" << endl; 84 ss << "=" << endl; 85 } 86 else if (bracketNum > 0) 87 { 88 //cout << "("; 89 ss << "("; 90 equation(); 91 //cout << ")"; 92 ss << ")"; 93 op=oper(op); 94 if (bracketNum >= 1) 95 { 96 //cout << op; 97 ss << op; 98 } 99 bracketNum--; 100 equationN(bracketNum); 101 } 102 } 103 104 void equationNo(int bracketNum) //递归实现无括号 105 { 106 string op; 107 if (bracketNum <= 0) 108 { 109 equation(); 110 //cout << "=" << endl; 111 ss << "=" << endl; 112 } 113 else if (bracketNum > 0) 114 { 115 equation(); 116 if (bracketNum >= 1) 117 { 118 //cout << oper(op); 119 ss << oper(op); 120 } 121 bracketNum--; 122 equationNo(bracketNum); 123 } 124 } 125 126 bool repeat(string ss1, int i) //判断是否重复,重复返回true,不重复返回false 127 { 128 bool flag = true;//默认是重复的 129 int j; 130 for (j = 0; j < i; j++) 131 { 132 if (ss1 == buffer[j]) 133 { 134 flag = true; 135 break; 136 } 137 else 138 { 139 flag = false; 140 } 141 } 142 return flag; 143 } 144 145 void main() 146 { 147 int bracket,bracketNum,Num; 148 srand((unsigned)time(NULL)); //做一个时间种子 149 cout << "请输入是否有乘除法(0、无 1、有):" << endl; 150 cin >> MulDlvIsExist; 151 cout << "请输入是否有无括号(0、无 1、有):" << endl; 152 cin >> bracket; 153 cout << "请输入数值范围(请先输入最小数,再输入最大数,请保证两个数均为大于等于0的数!):" << endl; 154 cin >> min>>max; 155 cout << "请输入加减结果是否有负数(0、无 1、有):" << endl; 156 cin >> AddSubIsNeg; 157 if (MulDlvIsExist == 1) 158 { 159 cout << "请输入乘除结果是否有余数(0、无 1、有):" << endl; 160 cin >> DlvIsRem; 161 } 162 163 cout << "请输入题目的个数:" << endl; 164 cin >> N; 165 cout << "请选择打印的方式(0、输出到文本 1、屏幕打印):" << endl; 166 cin >> print; 167 if (print == 1) 168 { 169 for (int i = 0; i < N; i++) 170 { 171 bracketNum = 1 + rand() % 4; //产生1~4以内的随机整数,作为括号个数 172 Num = 0 + rand() % 4; //产生0~4以内的随机整数,加1乘2作为操作数的个数 173 cout << "第" << setw(2) << i + 1 << "题:"; 174 if (bracket == 1)//有括号 175 { 176 equationN(bracketNum); 177 while (repeat(ss.str(), i) && (i>0))//当他重复时且不是第一个时循环,直到不重复为止 178 { 179 ss.str(""); 180 equationN(bracketNum); 181 } 182 buffer[i] = ss.str(); 183 cout << ss.str(); 184 ss.str("");//清空ss的缓冲区 185 } 186 else//默认无括号 187 { 188 equationNo(Num); 189 while (repeat(ss.str(), i) && (i>0))//当他重复时且不是第一个时循环,直到不重复为止 190 { 191 ss.str(""); 192 equationNo(Num); 193 } 194 buffer[i] = ss.str(); 195 cout << ss.str(); 196 ss.str("");//清空ss的缓冲区 197 } 198 199 } 200 201 } 202 else if (print == 0) 203 { 204 string file; 205 cout << "请输入输出文件格式:(如:D:\\print.txt)" << endl; 206 cin >> file; 207 ofstream outfile(file, ios::out); 208 if (!outfile) 209 { 210 cerr << "创建失败!" << endl; 211 exit(1); 212 } 213 214 for (int i = 0; i < N; i++) 215 { 216 bracketNum = 1 + rand() % 4; //产生1~4以内的随机整数,作为括号个数 217 Num = 0 + rand() % 4; //产生0~4以内的随机整数,加1乘2作为操作数的个数 218 outfile << "第" << setw(2) << i + 1 << "题:"; 219 if (bracket == 1)//有括号 220 { 221 equationN(bracketNum); 222 while (repeat(ss.str(), i) && (i>0))//当他重复时且不是第一个时循环,直到不重复为止 223 { 224 ss.str(""); 225 equationN(bracketNum); 226 } 227 buffer[i] = ss.str(); 228 outfile << ss.str(); 229 ss.str("");//清空ss的缓冲区 230 } 231 else//默认无括号 232 { 233 equationNo(Num); 234 while (repeat(ss.str(), i) && (i>0))//当他重复时且不是第一个时循环,直到不重复为止 235 { 236 ss.str(""); 237 equationNo(Num); 238 } 239 buffer[i] = ss.str(); 240 outfile << ss.str(); 241 ss.str("");//清空ss的缓冲区 242 } 243 } 244 245 outfile.close(); 246 247 } 248 249 }