[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)
发布了88 篇原创文章 · 获赞 585 · 访问量 145万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览