资源简介 (共20张PPT)栈的应用为了帮助小学生检查口算作业,设计了“口算批改”程序,根据识别出来的算式,逐一计算,检验算式的正确性,并显示计算结果是否正确。项目情境要设计“口算批改”项目,我们需要解决哪些问题:1.将口算图片转化为文本。2.处理每一个算式,计算算式的正确答案。3.输出判定结果。将正确答案与输入的答案进行比较。利用OCR识别技术,将图片识别为文本,并存入txt文件口算批改项目—项目任务要设计“口算批改”项目,我们需要解决哪些问题:1.将口算图片转化为文本。利用OCR识别技术,将图片识别为文本,并存入txt文件口算批改项目项目第一课时已经完成。思考1:如何提取算式例如:”6+(8-2)*2/3=10”以字符串读入,先找出等号,等号左边是算式,等号右边是输入的结果思考2:如何提取算式的数字与运算符例如:”6+(8-2)*2/3=10”分离算式中的数字和运算符。数字可能有多位,所以需要循环取出数字,运算符只有一位,只需逐位取出,取出后存入列表中。要设计“口算批改”项目,我们需要解决哪些问题:1.将口算图片转化为文本。口算批改项目要设计“口算批改”项目,我们需要解决哪些问题:1.将口算图片转化为文本。2.处理每一个算式,计算算式的正确答案。3.输出判定结果。将正确答案与输入的答案进行比较。利用OCR识别技术,将图片识别为文本,并存入txt文件口算批改项目思考3:计算机如何处理加、减、乘、除、括号等运算符的优先级问题?结合数学中的计算规律,加法和减法运算设置为同一级别,乘法和除法运算设置为同一级别,括号级别最高。可以用字典来定义每个运算符的优先级,或者通过分支语句实现。思考4:结合运算符的优先级,如何算得计算式的值?先将表达式转为逆波兰表达式,再求得逆波兰表达式的值口算批改项目-抽象建模开始读取等号左右两边表达式将表达式转为逆波兰表达式计算逆波兰表达式的值判断计算所得的值与等号右边结果是否相等读取文件获取每一行的算式输出是否正确的结果结束口算批改项目设计算法:如何将中缀表达式转为后缀表达式(有括号)1、初始化运算符栈S12、依次从数组中取出各个字符,根据字符做不同处理3、遇到操作数时,将其输出4、遇到运算符时,比较其与S1栈顶运算符的优先级:若S1为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈;否则,若优先级比栈顶运算符的高,也将运算符压入S1(注意必须是高,相同和低于都不行);否则,将S1栈顶的运算符弹出,再次转到4与S1中新的栈顶运算符相比较:5 、遇到括号时:如果是左括号“(”,则直接压入S1;如果是右括号“)”,则依次弹出S1栈顶的运算符,直到遇到左括号为止,此时将这一对括号丢弃;6、重复步骤2至5,直到表达式遍历结束7、将S1中剩余的运算符依次弹出;项目实施-设计算法ops=[""]*20top=-1snbl=[] #存储逆波兰表达式for i in a: #输出逆波兰表达式if i in ops_rule:while top>=-1:if top==-1: #运算符栈为空,则入运算符栈opstop+=1ops[top]=ibreakelse:if ops[top]=="(" or ops_rule[i]>ops_rule[ops[top]]:#若运算符栈不空,栈顶为左括号或者比栈顶元素优先级高,入栈top+=1ops[top]=ibreakelse:#优先级比栈顶优先级相等或小snbl.append(ops[top])top-=1项目实施-程序编写ops_rule={ #字典,定义优先级"+":1,"-":1,"*":2,"/":2}ops=[""]*20top=-1snbl=[] #存储逆波兰表达式for i in a: #输出逆波兰表达式if i in ops_rule:while top>=-1:if top==-1: #运算符栈为空,则入运算符栈opstop+=1ops[top]=ibreakelse:if ops[top]=="(" or ops_rule[i]>ops_rule[ops[top]]:#若运算符栈不空,栈顶为左括号或者比栈顶元素优先级高,入栈top+=1ops[top]=ibreakelse:#优先级比栈顶优先级相等或小snbl.append(ops[top])top-=1项目实施-程序编写ops_rule={ #字典,定义优先级"+":1,"-":1,"*":2,"/":2}elif i=="(":top+=1;ops[top]=ielif i==")":while top>=0: #运算符栈不空if ops[top]=="(": #栈顶元素为左括号,则抛弃左括号,top减一top-=1;breakelse:snbl.append(ops[top]) #栈顶元素不是左括号,则加入逆波兰表达式top-=1else:snbl.append(i)while top>=0:snbl.append(ops[top]);top-=1print("逆波兰表达式:")for i in range(len(snbl)-1):print(snbl[i],end=" ")print(snbl[-1])项目实施-程序编写elif i=="(":top+=1;ops[top]=ielif i==")":while top>=0: #运算符栈不空if ops[top]=="(": #栈顶元素为左括号,则抛弃左括号,top减一top-=1;breakelse:snbl.append(ops[top]) #栈顶元素不是左括号,则加入逆波兰表达式top-=1else:snbl.append(i)while top>=0:snbl.append(ops[top]);top-=1print("逆波兰表达式:")for i in range(len(snbl)-1):print(snbl[i],end=" ")print(snbl[-1])项目实施-程序编写设计算法:如何计算逆波兰表达式的值?项目实施-设计算法6 8 2 - 4 * 3 / +6+(8-2)*4/31、从左往右遍历逆波兰表达式①若取到数字进栈②若取到运算符则取出栈顶的两个数字进行运算,并将运算后将结果放入栈顶2、循环遍历到最后,栈顶的值即为结果3、根据逆波兰表达式计算得到等号左边算式的值,与等号右边的结果进行比较①若相等,则输出正确②若不相等,则输出错误def js(op,x,y):if op=="+":return x+yif op=="-":return x-yif op=="*":return x*yif op=="/":return x/ynbl=[""]*20 #用于计算逆波兰表达式的值ntop=-1for i in snbl:if i in ops_rule: #如果i是符号r=js(i,nbl[ntop-1],nbl[ntop])ntop=ntop-2;ntop=ntop+1nbl[ntop] = relse:ntop = ntop + 1nbl[ntop] = iprint("计算结果:",end=" ")if nbl[0]==int(s2):print("计算正确!")else:print("计算错误!正确结果为:",nbl[0])项目实施-程序编写def js(op,x,y):if op=="+":return x+yif op=="-":return x-yif op=="*":return x*yif op=="/":return x/ynbl=[""]*20 #用于计算逆波兰表达式的值ntop=-1for i in snbl:if i in ops_rule: #如果i是符号r=js(i,nbl[ntop-1],nbl[ntop])ntop=ntop-2;ntop=ntop+1nbl[ntop] = relse:ntop = ntop + 1nbl[ntop] = iprint("计算结果:",end=" ")if nbl[0]==int(s2):print("计算正确!")else:print("计算错误!正确结果为:",nbl[0])项目实施-程序编写是否有其他思路呢?6+(8-2)*4/3=14数字栈运算符栈6+(8-2*4/3624814项目实施课后作业:编程:使用双栈的方法计算数学表达式的值项目小结“口算批改”项目,我们主要研究:1.将口算图片转化为文本。2.处理每一个算式,计算算式的正确答案。3.输出判定结果。 展开更多...... 收起↑ 资源预览