四则运算3
一、队友:http://home.cnblogs.com/u/Megau/
二、设计思路
1、在上一次的代码基础上叠加一个计算函数。
2、计算函数首先将产生的算式按顺序分成两个数组拆分,第一个数组存数字,第二个数组存运算符。
3、计算时使用c里面栈的思想计算。不过,这里是分各种情况讨论运算。第一个运算符先入数组,根据第二个运算符确定
4、当运算符出现*+或*-或/+或/-这些情况时,数字数组的前两个数字弹出数组,*或者/弹出运算符数组进行计算成一个数,然后将这个数存到刚才两个数的第一个数的位置,数组的长度减1。运算符的+或-代替前一个运算符,运算符数组长度减1.
5、当出现左括号时,运算符继续入数组,当遇到右括号时,数字数组弹出后两个数,将带右括号的三个运算符弹出,计算。运算结果放到弹出的两个数的第一个数的位置。数字数组长度减1,运算符数组长度减3.
6、当出现类似于+*+这种优先关系的运算符时,先弹出后两个数字进行*或/运算,结果入数组,长度减1,后一个运算符代替前一个运算符的位置,运算符数组长度减1,再判断下一个运算符。
7、当出现++或者+-或者-+或者--的情况,先弹出前两个数,和前一个运算符进行运算,结果再入数组,运算符数组长度减1,数字数组长度减1。
8、当出现=号时,如果数字只剩下两个数时,运算符数组只剩下一个运算符,那么两个数根据运算符运算。如果数字超过两个数时,先进行上面提到的运算分析。
9、运算结果可以是分数也可以是整数,也可以是分数。因此,定义输入字符串,当字符串里出现“/”时,将“/”号前后的字符串转成数字,再进行计算。
三、代码
1 #writher Megau Bing And Surver Devin 2 #edit date 20160317 3 4 from fractions import Fraction#分数 5 from random import randint#随机数 6 7 8 def replace(line): 9 line=line.replace('+',' + ') 10 line=line.replace('-',' - ') 11 line=line.replace('*',' * ') 12 line=line.replace('/',' / ') 13 line=line.replace('(',' ( ') 14 line=line.replace(')',' ) ') 15 line=line.replace(' ',' ') 16 line=line.replace('=',' = ') 17 return line 18 19 def calculate(operator_cal,operator_num1,operator_num2): 20 answer=0 21 if(operator_cal=="+"): 22 answer=operator_num1+operator_num2 23 if(operator_cal=="-"): 24 answer=operator_num1-operator_num2 25 if(operator_cal=="*"): 26 answer=operator_num1*operator_num2 27 if(operator_cal=="/"): 28 answer=operator_num1/operator_num2 29 #print"####结果",answer 30 return answer 31 32 33 def result_get(str1): 34 operator_anw=[""]*100#存取运算符的数组 35 operator_ord=0#指针,计算运算符位置,统计运算符的个数 36 37 figure_anw=[0]*100#存取运算数的数组 38 figure_ord=0#指针,计算运算数位置,统计运算数的个数 39 40 line=replace(str1) 41 #print line 42 line = line.split() 43 for word in line: 44 #print "word:",word 45 if(word=="+"): 46 operator_anw[operator_ord]="+" 47 operator_ord=operator_ord+1 48 elif(word=="-"): 49 operator_anw[operator_ord]="-" 50 operator_ord=operator_ord+1 51 elif(word=="*"): 52 operator_anw[operator_ord]="*" 53 operator_ord=operator_ord+1 54 elif(word=="/"): 55 operator_anw[operator_ord]="/" 56 operator_ord=operator_ord+1 57 elif(word=="("): 58 operator_anw[operator_ord]="(" 59 operator_ord=operator_ord+1 60 elif(word==")"): 61 operator_anw[operator_ord]=")" 62 operator_ord=operator_ord+1 63 elif(word=="="): 64 if(operator_ord==2):#如果出现运算符剩两个的情况,运算第二个运算符 65 figure_anw[1]=calculate(operator_anw[1],figure_anw[1],figure_anw[2]) 66 figure_anw[0]=calculate(operator_anw[0],figure_anw[0],figure_anw[1]) 67 #print figure_anw[0],"end" 68 return figure_anw[0] 69 70 else: 71 word=int(word) 72 word=Fraction(word,1) 73 figure_anw[figure_ord]=word 74 figure_ord=figure_ord+1 75 #print "已存入数字",word 76 #print "下一个数字位置",figure_ord 77 #print "下一个运算符位置",operator_ord 78 #print operator_anw 79 #print figure_anw 80 #判断并进行运算,进栈出栈 81 82 #优先级进行判断,是否入栈是否运算(+—同一类,*/同一类) 83 84 #*+问题 85 if((word=="+"or word=="-")and operator_ord>1 and (operator_anw[operator_ord-1]=="*" or operator_anw[operator_ord-1]=="/")): 86 figure_anw[figure_ord-2]=calculate(operator_anw[operator_ord-2],figure_anw[figure_ord-2],figure_anw[figure_ord-1]) 87 operator_anw[operator_ord-1]="" 88 figure_anw[figure_ord-1]=0 89 operator_ord=operator_ord-1 90 operator_anw[operator_ord-1]=word 91 figure_ord=figure_ord-1 92 #print operator_anw 93 #print figure_anw 94 95 96 if(word==")"):#1判断是否出现右括号 97 #运算函数 98 #if 如果出现+*两层运算问题,这个if解决第一层*/ 99 if(operator_anw[operator_ord-3]=="+" or operator_anw[operator_ord-3]=="-"): 100 figure_anw[figure_ord-2]=calculate(operator_anw[operator_ord-2],figure_anw[figure_ord-2],figure_anw[figure_ord-1]) 101 figure_anw[figure_ord-1]=0 102 operator_anw[operator_ord-1]="" 103 operator_anw[operator_ord-2]=")" 104 figure_anw[figure_ord-1]=0 105 operator_ord=operator_ord-1 106 figure_ord=figure_ord-1 107 108 #这段是将括号中残存的唯一运算符进行运算并消掉括号和运算符 109 figure_anw[figure_ord-2]=calculate(operator_anw[operator_ord-2],figure_anw[figure_ord-2],figure_anw[figure_ord-1]) 110 figure_anw[figure_ord-1]=0 111 operator_anw[operator_ord-3]="" 112 operator_anw[operator_ord-2]="" 113 operator_anw[operator_ord-1]="" 114 operator_ord=operator_ord-3 115 figure_ord=figure_ord-1 116 117 #+*+问题 解决 118 if((word=="+"or word=="-")and (operator_anw[operator_ord-2]=="*" or operator_anw[operator_ord-2]=="/")and operator_ord>1): 119 figure_anw[figure_ord-2]=calculate(operator_anw[operator_ord-2],figure_anw[figure_ord-2],figure_anw[figure_ord-1]) 120 operator_anw[operator_ord-2]=word 121 operator_anw[operator_ord-1]="" 122 figure_anw[figure_ord-1]=0 123 figure_ord=figure_ord-1 124 operator_ord=operator_ord-1 125 #print"*+" 126 127 #++问题 128 if((word=="+"or word=="-")and operator_ord>1): 129 #print "************************************************",operator_anw[operator_ord-2] 130 #print operator_anw[operator_ord-2] 131 if(operator_anw[operator_ord-2]=="+"or operator_anw[operator_ord-2]=="-"): 132 figure_anw[figure_ord-2]=calculate(operator_anw[operator_ord-2],figure_anw[figure_ord-2],figure_anw[figure_ord-1]) 133 operator_anw[operator_ord-1]="" 134 figure_anw[figure_ord-1]=0 135 operator_ord=operator_ord-1 136 operator_anw[operator_ord-1]=word 137 figure_ord=figure_ord-1 138 #print operator_anw 139 #print figure_anw 140 141 142 def layer(layer_accual2,operat_number2,brackets2,layer_amount2):#递归程序 143 if(layer_accual2>0):#对第一层开始计算,将形成3个以上的数字,层数暂时为设定的3。 144 #选择数字标号 145 #print"layer_accual2",layer_accual2 146 opreation_radom=randint(0,layer_accual2-1)#第一层加1,抽取号码,进行替换 147 find_operat_number=operat_number[opreation_radom] 148 #即两个数中选择一个数进行替换成为一个简单的四则二元运算 149 #print "operater_num",operater_num 150 #将选中的数字从第二层开始,用一个简单的二元运算式替换选中的数字,并插入数组 151 #插入时依据数字编号判断是否加入括号,依据此数字所在的周围是否有*\符号 152 #判断是否有添加括号 153 if((operator[opreation_radom]=="-")or operator[opreation_radom+1]=="-")or operator[opreation_radom]=="/"or(operator[opreation_radom]=="*")or(operator[opreation_radom+1]=="/")or(operator[opreation_radom+1]=="*"):#判断选中数字周围的符号 154 brackets[layer_accual2]=1 155 if(multiplication_and_division==2): 156 brackets[layer_accual2]=0 157 158 159 operater_num=randint(1,multiplication_and_division) #将运算符入数组 160 operator_one="?" 161 #operater_num=2 162 if(operater_num==1): 163 operator_one="+" 164 if(operater_num==2): 165 operator_one="-" 166 if(operater_num==3): 167 operator_one="*" 168 if(operater_num==4): 169 operator_one="/" 170 171 if(layer_accual2==0): 172 operator[1]=operator_one 173 else: 174 175 mov_amount=layer_accual2+2-opreation_radom 176 for i in range(0,mov_amount): 177 operator[layer_accual2+2-i]=operator[layer_accual2+2-i-1] 178 #print"i",i 179 operator[opreation_radom+1]=operator_one 180 181 zhen_zheng=randint(1,2) #是真分数或者整数,随机 182 if(fraction_exist==0): 183 zhen_zheng=1 184 if(zhen_zheng==1): #产生第一个数字 185 first_num=randint(1,number_range) 186 first_num=str(first_num) 187 else: 188 first_num1=2 189 first_num2=1 190 while (first_num1>=first_num2): 191 first_num1=randint(1,number_range) 192 first_num2=randint(1,number_range) 193 first_num=Fraction(first_num1,first_num2) 194 if(first_num!=0): 195 first_num="("+str(first_num)+")" 196 first_num=str(first_num) 197 zhen_zheng=randint(1,2) #是真分数或者整数,随机 198 if(fraction_exist==0): 199 zhen_zheng=1 200 if(zhen_zheng==1): #产生第二个数字 201 second_num=randint(1,10) 202 second_num=str(second_num) 203 else: 204 second_num1=2 205 second_num2=1 206 while (second_num1>=second_num2): 207 second_num1=randint(1,number_range) 208 second_num2=randint(1,number_range) 209 second_num=Fraction(second_num1,second_num2) 210 if(second_num!=0): 211 second_num="("+str(second_num)+")" 212 213 if(layer_accual2==0):#第0层,将最开始的两个数字存入数组 214 operat_number[0]=first_num 215 operat_number[1]=second_num 216 if(negative_exit==0):#(如果不存在负数) 217 if(second_num>first_num and operator_one==2): 218 while(second_num>=first_num): 219 second_num=randint(1,number_range) 220 221 if(remainder==0):#(如果不存在余数) 222 if(operator_one==4): 223 while(second_num%first_num!=0): 224 print"remainder" 225 second_num=randint(1,number_range) 226 227 228 #从第一层开始存入两个数字 229 if(layer_accual2>0): 230 mov_amount=layer_accual2+2-opreation_radom 231 for i in range(0,mov_amount): 232 operat_number[layer_accual2+1-i]=operat_number[layer_accual2+1-i-1] 233 operat_number[opreation_radom]=first_num 234 operat_number[opreation_radom+1]=second_num 235 236 237 #整理算式 238 if(layer_accual2<1): 239 expressions="" 240 241 242 if(layer_accual2==1): 243 tempperate1=str(operat_number[0]) 244 tempperate2=str(operat_number[1]) 245 expressions=operat_number[0]+operator[1]+operat_number[1] 246 247 if(layer_accual2>1): 248 #先找到替换数字,然后产生表达式2,用2替换表达式1 249 global expressions 250 kk=str(operat_number[opreation_radom]) 251 expressions2=first_num+operator_one+second_num 252 if ( brackets[layer_accual2]==1): 253 expressions2="("+first_num+operator_one+second_num+")" 254 255 256 #创建一个查找机制,寻找不同的数字将其替换? 257 #while(same_amount>0): 258 #print"上一层句子",expressions 259 #print"替换句子",expressions2 260 #print"用于替换的的数字",find_operat_number 261 expressions=expressions.replace(find_operat_number," "+find_operat_number+" ") 262 expressions3="" 263 recording_1=0 264 line=expressions.split() 265 for word2 in line: 266 if (word2==find_operat_number and recording_1==0): 267 268 word2=expressions2 269 recording_1=1 270 expressions3=expressions3+word2 271 expressions3=expressions3.replace(" ","") 272 expressions=expressions3 273 274 layer_accual2=layer_accual2+1 275 if(layer_accual2<layer_amount2+1): 276 layer(layer_accual2,operat_number2,brackets2,layer_amount2) 277 278 #if(layer_accual==layer_amount2): 279 #return expressions 280 281 282 283 ##############程序开始 284 expressions_amount=10#算式数量 285 layer_amount=3 #层数,即数的个数 286 number_range=20#整数数值的大小范围 287 fraction_exist=1#是否有分数 288 multiplication_and_division=4#是否有乘除,有则为4 289 negative_exit=0#负数是否存在,1存在 290 remainder=0#余数是否存在,1存在 291 pritenr=1#打印机模式 292 quit_num=1#退出的标志 293 #print "expressions_amount",expressions_amount 294 295 296 297 298 while(quit_num==1): 299 300 right_amount=0 301 print"打印方式,1为屏幕显示,2为导出为txt文件" 302 temp=input() 303 while(temp!=1 and temp!=2): 304 print"输入错误,请重新输入" 305 temp=input() 306 pritenr=temp 307 temp=1 308 309 print"数值范围,(至少大于等于10)" 310 temp=input() 311 while(temp<10): 312 print"输入错误,请重新输入" 313 temp=input() 314 number_range=temp 315 316 print"参数个数,(大于1小于10)" 317 temp=input() 318 while(temp<2): 319 print"输入错误,请重新输入" 320 temp=input() 321 layer_amount=temp-1 322 323 print"是否有括号,支持十个参数参与计算,0为无括号,1为有括号" 324 temp=input() 325 while(temp!=1 and temp!=0): 326 print"输入错误,请重新输入" 327 temp=input() 328 if(temp==1): 329 multiplication_and_division=4 330 if(temp==0): 331 multiplication_and_division=2 332 333 print"加减有无负数,0为无负数,1为有负数" 334 temp=input() 335 while(temp!=0 and temp!=1): 336 print"输入错误,请重新输入" 337 temp=input() 338 negative_exit=temp 339 340 341 print"加减有无分数,0为无分数,1为有分数" 342 temp=input() 343 while(temp!=0 and temp!=1): 344 print"输入错误,请重新输入" 345 temp=input() 346 fraction_exist=temp 347 348 print"除法有无余数,0为无余数,1为有余数" 349 temp=input() 350 while(temp!=1 and temp!=0): 351 print"输入错误,请重新输入" 352 temp=input() 353 remainder=temp 354 355 print"总数" 356 expressions_amount=input() 357 358 359 #答案记录 360 answer_matrix=[0]*expressions_amount 361 answer_matrix_human=[0]*expressions_amount 362 363 364 365 #print expressions_mul 366 print"请在等号后分别输入答案。形式为:分子,回车,分母,回车。如果答案为整数,分母请填1。" 367 print"start" 368 369 for counter1 in range(0,expressions_amount): 370 #准备部分,执行参数,运算层数,运算到的层数 371 layer_accual=0 372 operator=['k']*(layer_amount+3)#记录运算符的记录 373 operat_number=["?"]*(layer_amount+2)#记录运算数的记录器 374 brackets=[0]*(layer_amount+1)#记录括号的存在标志 375 operator[0]="?" 376 operator[2]="?" 377 layer(layer_accual,operat_number,brackets,layer_amount) 378 expressions=expressions+"=" 379 #expressions_mul[counter1]=expressions#查重功能 380 381 382 if(pritenr==1):#屏幕卷面显示 383 print "第",counter1+1,"题",expressions, 384 385 answer_matrix[counter1]=result_get(expressions) 386 387 answer_user=raw_input() 388 find_chu=0 389 for i in answer_user: 390 if(i=="/"): 391 find_chu=1 392 answer_user=answer_user.split("/") 393 answer_user_matrix_momentary=[0]*2 394 i=0 395 for answer_user_i in answer_user: 396 answer_user_matrix_momentary[i]=int(answer_user_i) 397 #print answer_user_i 398 i=i+1 399 answer_user=Fraction(answer_user_matrix_momentary[0],answer_user_matrix_momentary[1]) 400 if(find_chu==0): 401 answer_user=Fraction(int(answer_user),1) 402 403 404 answer_matrix_human[counter1]=answer_user#Fraction(fenzi,fenmu) 405 if(answer_matrix[counter1]==answer_matrix_human[counter1]): 406 print "√" 407 right_amount=right_amount+1 408 409 else: 410 print "× 正确答案:", 411 print answer_matrix[counter1] 412 #result_get(expressions) 413 else: 414 f = file('output.txt', 'a') 415 f.write(expressions+"\n") 416 #f.write(expressions) 417 418 print"题数:",expressions_amount 419 print"答对的题数:",right_amount 420 if(right_amount>0.7*expressions_amount): 421 print"你太棒了" 422 if(right_amount<0.6*expressions_amount): 423 print"错的有点多,继续努力哦" 424 print "参考答案:"#,answer_matrix 425 num=1 426 for i in answer_matrix: 427 print "第",num,"题:", 428 num=num+1 429 print i 430 431 print"退出?0为退出,1为继续" 432 temp=input() 433 while(temp!=0 and temp!=1): 434 print"请重新输入" 435 temp=input() 436 quit_num=temp 437
四、截图
1、
2、
3、
4、
5、
6、
7、
项目计划日志(单位:h)
听课 |
编写程序 |
阅读相关书籍 |
网上查找资料 |
日总计 |
|
周一 |
2 |
0 |
1 |
0 |
3 |
周二 |
0 |
1 |
1 |
0 |
2 |
周三 |
0 |
2.5 |
0 |
0 |
2.5 |
周四 |
2 |
2.5 |
1 |
0 |
3.5 |
周五 |
0 |
5 |
0 |
0 |
1 |
周六 |
0 |
0 |
0 |
0 |
0 |
周日 |
|
|
|
|
|
周总计 |
4 |
11 |
3 |
0 |
12 |
时间记录日志:(单位:min):
日期 |
开始时间 |
结束时间 |
中断时间 |
净时间 |
活动 |
备注 |
星期一 |
14:00 |
15:50 |
10 |
100 |
听课 |
软件工程 |
|
21:00 |
22:00 |
0 |
60 |
看书 |
构建之法 |
星期二 |
19:00 |
20:00 |
0 |
60 |
编程 |
Python |
星期三 |
19:30 |
22:00 |
0 |
150 |
编程 |
四则运算3 Python |
星期四 |
19:00 |
21:30 |
0 |
150 |
编程 |
四则运算3 Python |
21:30 |
22:30 |
0 |
60 |
看书 |
构建之法 |
|
星期五 |
15:00 |
21:00 |
60 |
300 |
编程 |
四则运算3 |
星期六 |
|
|
|
|
|
|
|
|
|
|
|
|
|
缺陷记录日志:
日期 | 编号 | 类型 | 引入阶段 | 排除阶段 | 修复时间 | 修复缺陷 |
3/15 | 1 | 输入 | 编译 | 复审 | 15 | 输入答案时一开始无法输入分数,后来可以了 |
描述:使用字符串扫描和强制转换 | ||||||