算术表达式求值器:基于栈的实现及优化
这段代码实现了一个简单的算术表达式求值器,采用了栈来实现运算符的处理和数字的存储。具体思路如下:
-
定义操作符优先级字典
OPE和关键字字典KW,分别用于判断运算符优先级和标识符类型。 -
定义一个
LAN字典,用于记录可以进行归约的表达式规则。 -
定义一个
VAL字典,用于存储变量的值。 -
定义一个
opeStack列表,用于存储操作符和数字。 -
输入一个算术表达式,逐个字符进行处理。
-
如果该字符是结束标记 '#',则将其入栈,并进行归约操作。
-
如果该字符是空格,则跳过。
-
如果该字符是运算符,则进行比较优先级的操作,并可能进行归约操作。
-
如果该字符是数字,则将其入栈。
-
如果该字符是字母,则进行标识符的处理。
-
最后进行最后一次归约操作,并输出结果。
整体来说,这段代码的设计思路比较清晰,主要是通过栈来实现运算符的优先级判断和数字的存储。同时,还考虑到了变量的处理和表达式的归约,使得求值器的功能更加完善。
OPE={'':
'+':{'+':'>','-':'>','*':'<','/':'<','(':'<',')':'>','#':'>'},
'-':{'+':'>','-':'>','*':'<','/':'<','(':'<',')':'>','#':'>'},
'*':{'+':'>','-':'>','*':'>','/':'>','(':'<',')':'>','#':'>'},
'/':{'+':'>','-':'>','*':'>','/':'>','(':'<',')':'>','#':'>'},
'(':{'+':'<','-':'<','*':'<','/':'<','(':'<',')':'=','#':'err'},
')':{'+':'>','-':'>','*':'>','/':'>','(':'err',')':'>','#':'>'},
'#':{'+':'<','-':'<','*':'<','/':'<','(':'<',')':'err','#':'='}
}
KW={'var':1,'int':2,'#':3,'=':4,'+':5,'-':6,'*':7,'/':8,'(':9,')':10}#var=>标识符 int=>数字 #=>结束标记
LAN={'E+E':'E','E-E':'E','E*E':'E','E/E':'E','(E)':'E'}
VAL={}
def calcul(n1,o,n2):
if(o=='+'):
return repr(int(n1)+int(n2))
elif(o=='-'):
return repr(int(n2)-int(n1))
elif(o=='*'):
return repr(int(n1)*int(n2))
elif(o=='/'):
return repr(int(int(n2)/int(n1)))
elif(n1==')' and n2=='('):
return o
opeStack=list()#栈列表
words=input('输入语句:')
index=0
while(index+1<len(words)):
ch=words[index]
if(ch=='#'):
if(index==0):
print('栈内元素:{} 当前符号:{} 剩余符号:{}'.format(''.join(opeStack),ch,words[index:]))
opeStack.append(ch)
index+=1
else:
print('栈内元素:{} 当前符号:{} 剩余符号:{}'.format(''.join(opeStack),ch,words[index:]))
index+=1
opeStack.append(ch)
Sl=len(opeStack)-1
while(opeStack[Sl] not in ['=','+','-','*','/','(',')','#']):
Sl-=1
while(OPE[opeStack[Sl]][ch]=='>'):
a1=opeStack.pop()
a2=opeStack.pop()
a3=opeStack.pop()
opeStack.append(calcul(a1,a2,a3))
print('栈内元素:{} 当前符号:{} 剩余符号:{} 归约'.format(''.join(opeStack),ch,words[index:]))
Sl=len(opeStack)-1
while(opeStack[Sl] not in ['=','+','-','*','/','(',')','#']):
Sl-=1
break
elif(ch==' '):
#该字符为空格
while(words[index+1]==' '):
index+=1
index+=1
elif(ch in ['=','+','-','*','/','(',')']):
#该字符为运算符
index+=1
print('栈内元素:{} 当前符号:{} 剩余符号:{}'.format(''.join(opeStack),ch,words[index:]))
Sl=len(opeStack)-1
while(opeStack[Sl] not in ['=','+','-','*','/','(',')','#']):
Sl-=1
if(OPE[opeStack[Sl]][ch]=='<'):
opeStack.append(ch)
elif(OPE[opeStack[Sl]][ch]=='>'):
a1=opeStack.pop()
a2=opeStack.pop()
a3=opeStack.pop()
opeStack.append(calcul(a1,a2,a3))
print('栈内元素:{} 当前符号:{} 剩余符号:{} 归约'.format(''.join(opeStack),ch,words[index:]))
Sl=len(opeStack)-1
while(opeStack[Sl] not in ['=','+','-','*','/','(',')','#'] and Sl>=0):
Sl-=1
while(OPE[opeStack[Sl]][ch]=='>'):
a1=opeStack.pop()
a2=opeStack.pop()
a3=opeStack.pop()
opeStack.append(calcul(a1,a2,a3))
print('栈内元素:{} 当前符号:{} 剩余符号:{} 归约'.format(''.join(opeStack),ch,words[index:]))
Sl=len(opeStack)-1
while(opeStack[Sl] not in ['=','+','-','*','/','(',')','#'] and Sl>=0):
Sl-=1
opeStack.append(ch)
elif(ch in ['0','1','2','3','4','5','6','7','8','9']):
#该字符为数字
num=ch
while(words[index+1] in ['0','1','2','3','4','5','6','7','8','9']):
num=num+words[index+1]
index+=1
index+=1
print('栈内元素:{} 当前符号:{} 剩余符号:{}'.format(''.join(opeStack),num,words[index:]))
opeStack.append(num)
if(index+1>=len(words)):
print('栈内元素:{} 当前符号:{} 剩余符号:{}'.format(''.join(opeStack),words[index],words[index:]))
ch='#'
Sl=len(opeStack)-1
while(opeStack[Sl] not in ['=','+','-','*','/','(',')','#']):
Sl-=1
while(OPE[opeStack[Sl]][ch]=='>'):
a1=opeStack.pop()
a2=opeStack.pop()
a3=opeStack.pop()
opeStack.append(calcul(a1,a2,a3))
print('栈内元素:{} 当前符号:{} 剩余符号:{} 归约'.format(''.join(opeStack),ch,words[index:]))
Sl=len(opeStack)-1
while(opeStack[Sl] not in ['=','+','-','*','/','(',')','#']):
Sl-=1
print('结果为:{}'.format(opeStack[1]))
原文地址: https://www.cveoy.top/t/topic/nAqE 著作权归作者所有。请勿转载和采集!