利用python写主范式,这里觉得需要对几个函数进行学习,以及对逆波兰和正则法则有一定基础。
我们可以引入re库和easygui库,一个能提取字符串信息,一个能完成简单的用户界面,当然prettytable库也行,也能有比较不错的表格。
re:当我们在Python中使用正则表达式时,re模块内部会干两件事情:编译正则表达式,如果正则表达式的字符串本身不合法,会报错;用编译后的正则表达式去匹配字符串。那么如果一个正则表达式要重复使用几千次,出于效率的考虑,我们是不是应该先把这个正则先预编译好,接下来重复使用时就不再需要编译这个步骤了,直接匹配,提高我们的效率从compile()函数的定义中,可以看出返回的是一个匹配对象,它单独使用就没有任何意义,需要和findall(), search(), match()搭配使用。(建议着重研究这个库,初学之后发现挺有意思的很实用)
str.zfill(width) width – 指定字符串的长度。原字符串右对齐,前面填充0。
逆波兰表示法(Reverse Polish notation,RPN,或逆波兰记法),是一种数学表达式方式,在逆波兰记法中,所有操作符置于操作数的后面,因此也被称为后缀表示法。逆波兰记法不需要括号来标识操作符的优先级。(摘自维基)
举个例子,数学表达式a+b,是一种中缀表达式,写成后缀表达式就是ab+。中缀表达式(a+b)*c-(a+b)/e的逆波兰式是ab+c*ab+e/-。
详细的逆波兰学习建议看看这个,挺不错的 将表达式转换成逆波兰式_sunmenggmail的博客-CSDN博客_表达式转换成逆波兰式
逆波兰 - 上(中缀表达式 转 后缀表达式)_哔哩哔哩_bilibili
逆波兰 - 下(后缀表达式计算结果)_哔哩哔哩_bilibili
我们还可以用isalpha()方法:判断字符串是否只由字母组成,如果字符串中所有字符都是字母则返回True,否则返回False。
当然,.append()等肯定会用上
其他方面就慢慢捋清逻辑,清晰的分离符号和变量,然后做出真值表,就能更好的做出范式
做了五六次修修补补
import easygui as eg
import re
from prettytable import PrettyTable
msg="您可以选择复制下列标准逻辑运算符号进行输入:\n非:﹁\n合:∧\n析取:∨\n条件:→\n双条件:↔\n\
为了保证识别正确请按照标准符号格式输入。\n本页面仅提供提醒,\
建议进行复制(ctrl+c)后粘贴 "
'''eg.textbox(msg=)'''
print(msg)
def sift(string):
find=re.compile(r"[(]+(.*)")
#re.compile(pattern[,fiags])找相关符号,编译成正则表达式对象,方便后续调用及提高效率
f=find.findall(string)
return(f)
def judgment(string):#做真值表
patten=re.compile(r"[(](.*?)[)]")
fuhao=patten.findall(string)
for i in range(len(fuhao)): #对所有元素进行遍历过滤掉括号
if fuhao[i].startswith("("):#判断字符串是否以(开头
fuaho[i]=sift(fuaho[i])
a=re.compile("[a-zA-Z]")#匹配字符集,即提取变量
attain=a.findall(string)
l=attain+fuhao
ls=[]
for i in l:
if i not in ls:
ls.append(i)
ls.append(string)
ls.sort(key=len)
return([ls,attain])
def priority(operator):#根据符号判定运算优先级
p=-1
if operator=="(":
p=5
elif operator=="﹁":
p=4
elif operator=="∧":
p=3
elif operator=="∨":
p=2
elif operator=="→":
p=1
elif operator=="↔":
p=0
return(p)
def operation(a,operator,b):#运算的表达
if operator =="﹁":
bool= not a
elif operator =="∧":
bool= a and b
elif operator =="∨":
bool= a or b
elif operator =="→":
bool= (not b) or a
elif operator =="↔":
bool= ((not a) and (not b)) or (a and b)
else:
print("运算符不合法,请重新尝试。")
return(None)
if(bool):#真值表初步
return(1)
else:
return(0)
def compute(changeipt,m):
i=0#准备建立栈
digit_ls=[]
symbol_ls=[]
while i<len(changeipt) or len(symbol_ls)!=0:
if i<len(changeipt):
j=changeipt[i]
else:
j=""
if j.isalpha():#判断字符串是否只由字母组成,返回布尔值
digit_ls.append(m[j])
i=i+1
else:
if len(symbol_ls)==0 or(j!=")"and symbol_ls[-1]=="(")or priority(j)>=priority(symbol_ls[-1]):#判断之二
symbol_ls.append(j)
i=i+1
continue
if j==")" and symbol_ls[-1]=="(":
symbol_ls.pop()
i=i+1
continue
if (i>=len(changeipt)and len(symbol_ls)!=0)or(j==")"and symbol_ls[-1]!="(")or priority(j)<=priority(symbol_ls[-1]):
opt=symbol_ls.pop()
if opt!="﹁":
result=operation(digit_ls.pop(),opt,digit_ls.pop())
elif opt=="﹁":
result=operation(digit_ls.pop(),opt)
digit_ls.append(result)
return(digit_ls[0])#为范式基础
def makels(x):#初步做出真值表
number=len(x)
ls=[]
for i in range(2**number):
Set=bin(i)[2:].zfill(number)
downls=list(map(lambda j:int(j),list(Set)))
ls.append(dict(zip(x,downls)))
return(ls)
def Total(downls,top):#算出真值表的数据
Tot=[]#接收数据
for truelin in downls:
every=[]
for L in top:
truth=compute(L,truelin)
every.append(truth)
Tot.append(every)
return(Tot)
def Minimal(t):#极小项
if len(t)!=0:
return("("+"∧".join(t)+")")
else:
return("")
def bigger(t):#极大项
if len(t)!=0:
return("("+"∨".join(t)+")")
else:
return("")
def Or(y,x):
w=makels(x)
minterms=[]
alline=Total(w,y)
for liname in range(2**len(x)):
ls=[]
if alline[liname][-1]==1:#该行值使表达式为1
for t in w[liname]:
if w[liname][t]==1:
ls.append(t)
else:
ls.append('﹁'+t)
minterm=Minimal(ls) #表达式为1,加入极小项列表
if minterm!='':
minterms.append(minterm)
return("∨".join(minterms))
def adn(y,x):
w=makels(x)
maxsetpuls=[]
alline=Total(w,y)
for liname in range(2**len(x)):
ls=[]
if alline[liname][-1]==0:#该行值使表达式为0
for t in w[liname]:
if w[liname][t]==0:
ls.append(t)
else:
ls.append('﹁'+t)
maxset=bigger(ls) #表达式为1,加入极大项列表
if maxset!='':
maxsetpuls.append(maxset)
return("∧".join(maxsetpuls))
getin=input("请输入需要计算的式子\n:")
change=judgment(getin)[0]
q=judgment(getin)[1]
x=[]
for i in q:
if i not in x:
x.append(i)
w=makels(x)
alline=[]
for realine in w:
every=[]
for K in change:
truth=compute(K,realine)
every.append(truth)
alline.append(every)
form=PrettyTable(change)
for line in alline:
form.add_row(line)
print(form)
print("主析取范式为: "+Or(change,x))
print("主合取范式为: "+adn(change,x))