四则运算3.2

一、队友:http://home.cnblogs.com/u/surver/

二、设计思路

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+"
")
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

运行结果

1

2

3

4

5

6

7

 项目记录日志

  听课 编写程序 阅读相关书籍 网上查阅资料 总计
周一 2 0 0 0 2
周二 0 1 1 1 3
周三 0 2.5 1 0 3.5
周四 2 2.5 0 0 4.5
周五 0 5 0 0 1
周六 0 0 0 0 0
周日          
总计 4 11 2 1 18

时间记录日志

日期  开始时间 结束时间 中断时间 净时间 活动 备注
周一 14:00 15:50 10 100min 听课 上课+编程
周二 16:00;19:00 17:00;20:00 0 60 看书,编程 第一函数
周三 14:00;19:30 15:00;22:00 0 150 看书,编程 对计算做第一步完善
周四 19:00 21:30 0 150 编程 第二步完善
周五 15:00; 22:00 120 300 编程 系统进行修改完善
周六 0 0 0 0 0 0

缺陷记录

日期 类型 引入阶段 排除阶段 修复时间 修复的缺陷 编号
0315 输入 编译 复审 15 输入不能以分数结果直接输入 1
          是构建骨架,逐步完善的过程  
原文地址:https://www.cnblogs.com/Megau/p/5294858.html