四则运算3(结对开发)
Posted 斗破2
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了四则运算3(结对开发)相关的知识,希望对你有一定的参考价值。
本次试验是由上次的基础上迭代开发而来,并且用结对开发的模式进行开发。
结对开发的伙伴:
博客名:Mr.缪
姓名:缪金敏
链接:http://www.cnblogs.com/miaojinmin799/
功能要求:
1、乘除可控
2、随机添加括号
3、输入结果判断正误
4、统计正确数量
5、正负,余数可控
6、去除连除误区
程序思想:
1、无乘除可用0,1表示,有乘除可再加2,3,共四种选择
2、用随机函数选择左括号放在哪个操作数前面,然后再用随机函数添加右括号,在使用循环判断去除左括号加在最左边右括号加在最右边的式子
3、使用栈的思想,把生成的公式压入栈中,根据优先关系再进行计算,得出的结果存在一个数组中,当用户输入时和数组中的数比较
4、通过使用栈算出结果便可以知道有无正负和余数,可使用循环重新生成式子
5、在生成式子时,记入上一个运算符,当出现第二个“/”号时自动重新生成式子
6、最简真分数表示:求出分子分母最大公约数,然后都除以这个数,从而得出最简真分数,真分数用“(XX/XX)”表示
所遇困难:
1、在遇到10或20等数时,会出现运算错误,经过调试发现在出栈提取第二个操作数时总是为0,后经过查看发现在读取操作数时每遇到0就会多压入一个操作数导致运算混乱
2、对于运算式子的计算优先级的判断不是很了解,后来参考了原先数据结构课本中的资料,在结合程序本身情况完成了对运算式计算的函数。
结对开发过程照片:
源代码:
1 #include<iostream> 2 #include<string> 3 #include<sstream> 4 #include<time.h> 5 #include<iomanip> 6 #include<fstream> 7 #define MAX 100 8 using namespace std; 9 10 stringstream formula; //当前算式 11 string buffer[MAX]; //缓冲区数组 12 int TopNumber; //上限 13 int BaseNumber; //下限 14 int IsMulDlvExist; //是否有乘除 15 int Amount; //操作数的个数 16 int BracketNum; //括号个数 17 int LBraket[2]; //左括号的位置 18 int RBraket[2]; //右括号的位置 19 int IsNeg; //是否有负数 20 int IsRem; //是否有余数 21 int IsBra; //是否有括号 22 int IsRep; //是否重复 23 float Result[MAX]; //正确结果数组 24 char lastOp; //记录上个运算符是否为除号 25 26 //优先级数组 27 char prior[7][7] = { 28 { \'>\', \'>\', \'<\', \'<\', \'<\', \'>\', \'>\' }, 29 { \'>\', \'>\', \'<\', \'<\', \'<\', \'>\', \'>\' }, 30 { \'>\', \'>\', \'>\', \'>\', \'<\', \'>\', \'>\' }, 31 { \'>\', \'>\', \'>\', \'>\', \'<\', \'>\', \'>\' }, 32 { \'<\', \'<\', \'<\', \'<\', \'<\', \'=\', \' \' }, 33 { \'>\', \'>\', \'>\', \'>\', \' \', \'>\', \'>\' }, 34 { \'<\', \'<\', \'<\', \'<\', \'<\', \' \', \'=\' } 35 }; 36 //操作符栈 37 typedef struct { 38 char *base; 39 char *top; 40 }OperChar; 41 //操作数栈 42 typedef struct{ 43 float *base; 44 float *top; 45 }NumberLink; 46 //初始化栈 47 void InitOperStack(OperChar &S) 48 { 49 S.base = new char[MAX]; 50 if (!S.base) 51 exit(1); 52 S.top = S.base; 53 } 54 void InitNumStack(NumberLink &S) 55 { 56 S.base = new float[MAX]; 57 if (!S.base) 58 exit(1); 59 S.top = S.base; 60 } 61 //进栈 62 void PushOper(OperChar &S, char e){ 63 if (S.top - S.base == MAX) 64 exit(1); 65 *S.top++ = e; 66 67 } 68 void PushNum(NumberLink &S, float e){ 69 if (S.top - S.base == MAX) 70 exit(1); 71 *S.top++ = e; 72 } 73 //出栈 74 void PopOper(OperChar &S, char &e) 75 { 76 if (S.top == S.base) 77 exit(1); 78 e = *--S.top; 79 } 80 void PopNum(NumberLink &S, float &e) 81 { 82 if (S.top == S.base) 83 exit(1); 84 e = *--S.top; 85 } 86 //取栈顶元素 87 char GetTopOper(OperChar S) 88 { 89 if (S.top == S.base) 90 { 91 exit(1); 92 93 } 94 return *(S.top - 1); 95 } 96 float GetTopNum(NumberLink S) 97 { 98 if (S.top == S.base) 99 { 100 exit(1); 101 102 } 103 return *(S.top - 1); 104 } 105 //将操作符转化为优先级数组的下标 106 int Change(char Oper) 107 { 108 switch (Oper) 109 { 110 case \'+\': return 0; break; 111 case \'-\': return 1; break; 112 case \'*\': return 2; break; 113 case \'/\': return 3; break; 114 case \'(\': return 4; break; 115 case \')\': return 5; break; 116 case \'=\': return 6; break; 117 default: return 6; break; 118 119 } 120 } 121 //返回优先级的大小 122 char Precede(char Oper, char ch) 123 { 124 return prior[Change(Oper)][Change(ch)]; 125 } 126 //计算两个数的结果 127 float Operate(float first, char oper1, float second) 128 { 129 switch (oper1) 130 { 131 case \'+\': 132 { 133 return (first + second); 134 break; 135 } 136 case \'-\': 137 { 138 return (first - second); 139 break; 140 } 141 case \'*\': 142 { 143 return (first * second); 144 break; 145 } 146 case \'/\': 147 { 148 if (second == 0) 149 { 150 IsRep = 1; 151 return 0; 152 } 153 return (first / second); 154 break; 155 156 } 157 default: return 0; break; 158 } 159 } 160 //数字的个数 161 void NumberAmount() 162 { 163 Amount = 2 + rand() % 5; 164 } 165 //加左括号 随机选择在第几个数字前面加括号 166 void AddLbracket(){ 167 for (int j = 0; j < 2; j++) 168 LBraket[j] = 0; 169 if (Amount == 2) 170 { 171 BracketNum = 0; 172 } 173 if (Amount == 3){ 174 BracketNum = rand() % 2; 175 } 176 if (Amount > 3) 177 { 178 BracketNum = rand() % 3; 179 } 180 for (int i = 0; i < BracketNum; i++){ 181 LBraket[i] = 1 + rand() % (Amount - 2); 182 } 183 } 184 //加右括号 185 void AddRbracket(){ 186 for (int j = 0; j < 2; j++) 187 RBraket[j] = 0; 188 int choose; 189 int trance; 190 if (BracketNum == 1){ 191 RBraket[0] = LBraket[0] + 1 + rand() % (Amount - LBraket[0]); 192 } 193 if (BracketNum == 2) 194 195 { 196 //把最左边的左括号放在第一个数组中 197 if (LBraket[0] < LBraket[1]) 198 { 199 trance = LBraket[0]; 200 LBraket[0] = LBraket[1]; 201 LBraket[1] = trance; 202 } 203 //当两个左括号之间相差有点远时有2中右括号添加方法 204 if (LBraket[0] - LBraket[1]>2){ 205 choose = rand() % 2; 206 if (choose == 0){ 207 RBraket[0] = LBraket[0] + 1 + rand() % (Amount - LBraket[0]); 208 RBraket[1] = LBraket[0] + 1 + rand() % (Amount - LBraket[0]); 209 } 210 if (choose == 1) 211 { 212 RBraket[0] = LBraket[0] + 1 + rand() % (Amount - LBraket[0]); 213 RBraket[1] = LBraket[1] + 1 + rand() % (LBraket[0] - 2); 214 } 215 } 216 else 217 { 218 RBraket[0] = LBraket[0] + 1 + rand() % (Amount - LBraket[0]); 219 RBraket[1] = LBraket[0] + 1 + rand() % (Amount - LBraket[0]); 220 if (LBraket[0] == LBraket[1] && RBraket[0] == RBraket[1]){ 221 LBraket[0] = LBraket[1] = 0; 222 RBraket[0] = RBraket[1] = 0; 223 BracketNum = 0; 224 225 } 226 if (LBraket[1] == 1 && (RBraket[0] == Amount || RBraket[1] == Amount)) 227 { 228 LBraket[0] = LBraket[1] = 0; 229 RBraket[0] = RBraket[1] = 0; 230 BracketNum = 0; 231 } 232 233 } 234 } 235 } 236 //随机产生最简真分数 237 void Score(){ 238 int Left, Right; 239 Left = BaseNumber + rand() % (TopNumber - BaseNumber + 1); 240 Right = BaseNumber + rand() % (TopNumber - BaseNumber + 1); 241 while (Left >= Right || Left == 0) 242 { 243 Left = BaseNumber + rand() % (TopNumber - BaseNumber + 1); 244 Right = BaseNumber + rand() % (TopNumber - BaseNumber + 1); 245 } 246 int max = 1; 247 //求最大公约数 248 for (int i = 2; i <= Left; i++) 249 { 250 if (Left%i == 0 && Right%i == 0) 251 { 252 max = i; 253 } 254 } 255 if (max > 1) 256 { 257 Left /= max; 258 Right /= max; 259 } 260 formula << \'(\' << Left << \'/\' << Right << \')\'; 261 } 262 //随机生成操作符 263 void Operater() 264 { 265 int choose; 266 char op; 267 if (IsMulDlvExist == 1) 268 choose = 1 + rand() % 4; 269 else 270 choose = 1 + rand() % 2; 271 272 switch (choose) 273 { 274 case 1:{op = \'+\'; lastOp = \'+\'; break; } 275 case 2:{op = \'-\'; lastOp = \'-\'; break; } 276 case 3:{op = \'*\'; lastOp = \'*\'; break; } 277 case 4: 278 { 279 //防止连续除法产生运算误区 280 op = \'/\'; 281 if (lastOp == \'/\') 282 IsRep = 1; 283 else 284 lastOp = \'/\'; 285 break; 286 } 287 } 288 formula << op; 289 } 290 //随机生成整数 291 void Integer(){ 292 int num; 293 num = BaseNumber + rand() % (TopNumber - BaseNumber + 1); 294 formula << num; 295 } 296 //创建算式 297 void CreateNumber(){ 298 for (int k = 1; k <= Amount; k++) 299 { 300 301 for (int i = 0; i < 2; i++){ 302 if (LBraket[i] == k) 303 formula << \'(\'; 304 } 305 306 int cho; 307 cho = rand() % 2; 308以上是关于四则运算3(结对开发)的主要内容,如果未能解决你的问题,请参考以下文章