离散数学·主范式python代码

利用python写主范式,这里觉得需要对几个函数进行学习,以及对逆波兰和正则法则有一定基础。 

   我们可以引入re库和easygui库,一个能提取字符串信息,一个能完成简单的用户界面,当然prettytable库也行,也能有比较不错的表格。

re:当我们在Python中使用正则表达式时,re模块内部会干两件事情:编译正则表达式,如果正则表达式的字符串本身不合法,会报错;用编译后的正则表达式去匹配字符串。那么如果一个正则表达式要重复使用几千次,出于效率的考虑,我们是不是应该先把这个正则先预编译好,接下来重复使用时就不再需要编译这个步骤了,直接匹配,提高我们的效率compile()函数的定义中,可以看出返回的是一个匹配对象,它单独使用就没有任何意义,需要和findall(), search(), match(搭配使用。(建议着重研究这个库,初学之后发现挺有意思的很实用)

  str.zfill(width)    width – 指定字符串的长度。原字符串右对齐,前面填充0

  逆波兰表示法Reverse Polish notationRPN,或逆波兰记法),是一种数学表达式方式,在逆波兰记法中,所有操作符置于操作数的后面,因此也被称为后缀表示法。逆波兰记法不需要括号来标识操作符的优先级。(摘自维基)

举个例子,数学表达式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))

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

醉蕤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值