[Python] 逻辑表达式的真值表以及卡诺图生成

最近帮老师改作业,发现同学们交上来的作业里,同一个表达式有好几种写法,被搞得不胜其烦,干脆花了点时间写了个程序来判断这些表达式究竟是不是同一个意思。
基本上按照四则运算的写法,使用了一个数字栈,一个运算符栈。括号和非运算则采用了递归的方式来计算括号内核非运算内的值。
逻辑表达式中有4中运算符,+,*,#和[] 分别表示或,与,异或,非运算。其中,异或运算不推荐与其他运算混合。如果一定要混合的话,需要放在括号内进行计算。

举个栗子,已知逻辑表达式为A+B,则其真值表为

[‘AB’, ‘Y’]
[‘00’, ‘0’]
[‘01’, ‘1’]
[‘10’, ‘1’]
[‘11’, ‘1’]

其对应的卡诺图为(有些变形)

|…|0 |1 |
|0 |0 |1 |
|1 |1 |1 |

举个复杂点的栗子,已知Y=ABCD+ABC[D]+AB[C]D+A[B]C[D]
得到其真值表为

[‘ABCD’, ‘Y’]
[‘0000’, ‘0’]
[‘0001’, ‘0’]
[‘0010’, ‘0’]
[‘0011’, ‘0’]
[‘0100’, ‘0’]
[‘0101’, ‘0’]
[‘0110’, ‘0’]
[‘0111’, ‘0’]
[‘1000’, ‘0’]
[‘1001’, ‘0’]
[‘1010’, ‘1’]
[‘1011’, ‘0’]
[‘1100’, ‘0’]
[‘1101’, ‘1’]
[‘1110’, ‘1’]
[‘1111’, ‘1’]
卡诺图为
|…..|00 |01 |11 |10 |
|00 |0 |0 |0 |0 |
|01 |0 |0 |0 |0 |
|11 |0 |1 |1 |1 |
|10 |0 |0 |0 |1 |

程序如下

__author__ = 'multiangle'

class LogicExpression():
    def __init__(self,expression):
        """
        :param expression:
        :return:
        规定几种运算符号:   或运算     +
                            与运算     *或者没有
                            非运算     []
                            异或运算   #
        ATTENTION:不区分大小写,统一按大写看待
        """
        self.variables=[]           #参数列表(输入值)
        self.truth_table=None      #真值表
        self.truth_table_short=None
        self.karnaugh_map=None     #卡诺图

        if expression=='':
            raise ValueError('void string!')
        expression=expression.replace(' ','')
        expression=list(expression)
        for i in range(0,expression.__len__()):
            char=expression[i]
            if ord(char)>=97 and ord(char)<=122:
                char=char.upper()
                expression[i]=char
                if char not in self.variables:
                    self.variables.append(char)
            elif ord(char)>=65 and ord(char)<=90:
                if char not in self.variables:
                    self.variables.append(char)
        self.variables.sort()
        self.expression=''.join(expression)

        self.Generate_Truth_Table()
        self.Generate_Karnaugh_Map()

    def Generate_Truth_Table(self):
        truth_table=[]
        truth_table.append(self.variables+['Y'])
        for i in range(0,2**self.variables.__len__()):
            local_expression=self.expression
            variable_value=list(bin(i))[2:]
            variable_value=['0']*(self.variables.__len__()-variable_value.__len__())+variable_value
            for x in range(0,self.variables.__len__()):
                local_expression=local_expression.replace(self.variables[x],variable_value[x])
            local_res=self.cal_expression(local_expression)
            truth_table.append(variable_value+[local_res])
        self.truth_table=truth_table
        self.truth_table_short=[[''.join(x[0:x.__len__()-1]),x[x.__len__()-1]] for x in self.truth_table]
        # self.Print_Truth_Table()       local_expression=local_expression.replace(self.variables[x],variable_value[x])

    def Print_Truth_Table(self):
        lines=self.truth_table.__len__()
        cols=self.truth_table[0].__len__()
        print(('|---')*cols+'|')
        for line in self.truth_table:
            output='|'
            for col in line:
                output+=str(col)+'\t'+'|'
            print(output)
            # print(('|---')*cols+'|')
        print(('|---')*cols+'|')

    def Generate_Karnaugh_Map(self):
        tag_list=[x[0] for x in self.truth_table_short]
        tag_value=[x[1] for x in self.truth_table_short]
        if self.variables.__len__()==1:
            label_1=['0','1']
            label_2=['']
        if self.variables.__len__()==2:
            label_1=['0','1']
            label_2=['0','1']
        if self.variables.__len__()==3:
            label_1=['0','1']
            label_2=['00','01','11','10']
        if self.variables.__len__()==4:
            label_1=['00','01','11','10']
            label_2=['00','01','11','10']
        map=[[0 for col in range(label_2.__len__())] for row in range(label_1.__len__())]
        for x in range(0,label_1.__len__()):
            for y in range(0,label_2.__len__()):
                tag=''.join([label_1[x],label_2[y]])
                map[x][y]=tag_value[tag_list.index(tag)]
        self.karnaugh_map={
            'value':map,
            'l1':label_1,
            'l2':label_2
        }

    def cal_expression(self,expression):
        init_stack=[]       #括号运算
        for x in expression:
            if x!=')':
                init_stack.append(x)
            else:
                sub_expression=[]
                while(True):
                    item=init_stack.pop()
                    if item=='(':
                        break
                    else:
                        sub_expression.insert(0,item)
                sub_value=self.cal_expression(''.join(sub_expression))
                init_stack.append(sub_value)

        expression=''.join(init_stack)
        init_stack=[]        #非运算
        for x in expression:
            if x!=']':
                init_stack.append(x)
            else:
                sub_expression=[]
                while(True):
                    item=init_stack.pop()
                    if item=='[':
                        break
                    else:
                        sub_expression.insert(0,item)
                sub_value=self.cal_expression(''.join(sub_expression))
                if sub_value==0 or sub_value=='0':
                    sub_value='1'
                elif sub_value==1 or sub_value=='1':
                    sub_value='0'
                init_stack.append(sub_value)
        expression=''.join(init_stack)

        # print(expression)
        num_stack=[]
        sig_stack=[]
        num_stack.append(expression[0])
        for i in range(1,expression.__len__()):
            if expression[i] in ['0','1']:
                if expression[i-1] in ['0','1']:
                    num_stack.append(expression[i])
                    sig_stack.append('*')
                else:
                    num_stack.append(expression[i])
            else:
                if expression[i]=='+' or expression=='#':
                    if sig_stack.__len__()==0:
                        sig_stack.append(expression[i])
                    else:
                        if sig_stack[sig_stack.__len__()-1]=='+' or sig_stack[sig_stack.__len__()-1]=='#':
                            sig_stack.append(expression[i])
                        else:
                            while True:
                                a=num_stack.pop()
                                b=num_stack.pop()
                                sig=sig_stack.pop()
                                res=self.logic_cal(a,b,sig)
                                num_stack.append(res)
                                if sig_stack.__len__()==0:
                                    sig_stack.append(expression[i])
                                    break
                                if sig_stack[sig_stack.__len__()-1]=='+' or sig_stack[sig_stack.__len__()-1]=='#' :
                                    sig_stack.append(expression[i])
                                    break
                else:
                    sig_stack.append(expression[i])

        while True:
            if sig_stack.__len__()==0:
                break
            a=num_stack.pop()
            b=num_stack.pop()
            sig=sig_stack.pop()
            res=self.logic_cal(a,b,sig)
            num_stack.append(res)
        return num_stack[0]

    def Plot_Karnaugh_Map(self):
        row_num=self.karnaugh_map['l1'].__len__()+1
        col_num=self.karnaugh_map['l2'].__len__()+1
        # print('|'+'---|'*col_num)       #第一行的上限
        content='|'+'\t'+'|'
        for x in self.karnaugh_map['l2']:
            content+=x+'\t'+'|'
        print(content)
        # print('|'+'---|'*col_num)
        for i in range(0,self.karnaugh_map['l1'].__len__()):
            content='|'+self.karnaugh_map['l1'][i]+'\t'+'|'
            for j in range(0,self.karnaugh_map['l2'].__len__()):
                content+=self.karnaugh_map['value'][i][j]+'\t'+'|'
            print(content)
            # print('|'+'---|'*col_num)

    def Equal_To(self,b_expression):
        cmp_obj=LogicExpression(b_expression)
        if self.karnaugh_map['value']==cmp_obj.karnaugh_map['value']:
            return True
        else:
            return False

    def logic_cal(self,in_1,in_2,sig):
        #sig='+','*','#'
        if isinstance(in_1,str) or isinstance(in_2,str):
            in_1=int(in_1)
            in_2=int(in_2)

        if sig=='+':
            if in_1==1 or in_2==1:
                return '1'
            else:
                return '0'
        elif sig=='*':
            if in_1==1 and in_2==1:
                return '1'
            else:
                return '0'
        elif sig=='#':
            if in_1==in_2:
                return '0'
            else:
                return '1'

if __name__=='__main__':
    x='a#b'
    a=LogicExpression(x)
    # print('|'+'---'+'|'+'---')
    # print('|'+'AB'+'\t'+'|')
    # print('-'+'---'+'-')
    # for x in a.truth_table_short:
    #     print(x)
    # print(a.truth_table_short)
    # a.Plot_Karnaugh_Map()
    # b=LogicExpression('a')
    a.Plot_Karnaugh_Map()
    for x in a.truth_table_short:
        print(x)
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值