使用双栈实现输出逻辑表达式的真值表

来源:互联网 发布:ppp和hdlc对数据的 编辑:程序博客网 时间:2024/06/05 15:00

目的:读入一个逻辑表达式,包含多个变量及各种逻辑运算,输出该逻辑表达式的真值表;

思路:

1.与计算多项式的思路一致,利用双栈存储从左到右遍历;

栈具有LIFO的特点,利用栈可以储存离当前操作符最近的符号与数据,从左到右遍历,直到最终得出表达式的值;

2.两个栈一个存储符号,一个存储数据,设置栈内栈外符号位的优先级;

相同符号栈内优先级大于栈外优先级;

左括号栈内优先级最高,栈外优先级紧大于‘#’;

右括号与左括号相反;

将‘#’优先级设为最低,放入栈底,方便比较并判断终止条件;

3.每次读入一位,若为数据入数据栈;若为操作符,进行优先级比较

当栈内运算符优先级大于栈外运算符优先级,执行运算;

当栈内运算符优先级等于栈外运算符优先级,必为左右括号,弹出左括号;

当栈内运算符优先级小于栈外运算符优先级,将该符号入栈;

代码实现:

#include <iostream>#include <iomanip>#include <stdio.h>#include <stdlib.h>#include <cstring>#include <algorithm>#include <stack>#include <map>#include <cmath>using namespace std;int num[10];//按位存储生成的二进制码int letter_num;//全局变量存储表达式中变量数目map<char,int> m;//用map将字符与数字绑定,方便对应char letter[10];//储存所有字符变量char relation[256];//储存关系表达式int show[100];//记录变量是否出现int in[]={3,3,3,3,4,1,5,0};//栈内优先级int out[]={2,2,2,2,4,5,1,0};//栈外优先级char symbol[]={'^','V','>','<','~','(',')','#'};//储存操作符int get(char x);//返回操作符对应下标void get_num(int x);//更新按位二进制表示int get_letter_num(char *);//统计并储存变量char com(char x1,char x2);//比较优先级bool if_variable(char x);//判断当前字符是否为变量void print_truth_table(char *);//打印真值表int figure(int x1,int rel,int x2);//计算基本表达式值int main(){    cin>>relation;    print_truth_table(relation);    return 0;}void print_truth_table(char* top){    int sum;    char* y;    int x,x1,x2;    char rel;    stack<int> data;//存储数据    stack<int> ope;//存储操作符/*初始化*/    memset(show,0,sizeof(show));    memset(letter,0,sizeof(letter));    memset(num,0,sizeof(num));    ope.push(get('#'));    y=top;    x=get_letter_num(top);    x=(int)pow(2,x);//对应于2^x数的真值表/*打印表头*/    for(int i=0;i<=letter_num;i++)    {        if(i==letter_num)        {            printf("%-10s\n",relation);            for(int j=0;j<=letter_num;j++)                cout<<"----------";            cout<<endl;            continue;        }        printf("%-10c",letter[i]);    }    while(x--)    {        top=y;//保存头指针,每次遍历完需重置        get_num(x);//更新二进制表示        int index=ope.top();        while(*top||index!=7)        {            sum=0;            if(*top=='-')                top++;            if(*top=='~')//取非将4压入操作栈            {                ope.push(4);                top++;            }            if(*top=='<')//若为等价符另右移两位            {                ope.push(get(*top));                top+=3;            }            if(if_variable(*top))//压入变量值            {                sum=m[*top];                data.push(sum);                top++;            }            else//符号操作            {                switch(com(symbol[ope.top()], *top))                {                case 1://'>'                    if(ope.top()==4)//取反单独计算                    {                        x1=data.top();                        data.pop();                        x1=(x1+1)%2;                        data.push(x1);                        ope.pop();                        break;                    }                    x1=data.top();                    data.pop();                    x2=data.top();                    data.pop();                    rel=ope.top();                    ope.pop();                    data.push(figure(x1,rel,x2));                    break;                case 2://'<'                    ope.push(get(*top));                    if(*top)                        top++;                    break;                case 3://'='                    ope.pop();                    if(*top)                        top++;                    break;                }            }            index=ope.top();        }/*打印结果*/        for(int i=0;i<=letter_num;i++)        {            if(i==letter_num)            {                printf("%d\n",data.top());                data.pop();                continue;            }            printf("%-10d",num[i]);        }    }    return ;}void get_num(int x){    for(int i=letter_num-1;i>=0;i--)    {        num[i]=x%2;        m.erase(letter[i]);        m.insert(make_pair(letter[i],num[i]));        x/=2;    }    return ;}int get(char x){    switch(x)    {    case '^':        return 0;    case 'V':        return 1;    case '>':        return 2;    case '<':        return 3;    case '~':        return 4;    case '(':        return 5;    case ')':        return 6;    case '#':        return 7;    default:        return 7;    }}int get_letter_num(char *x){    letter_num=0;    while(*x)    {        switch(*x)        {        case '^':        case 'V':        case '>':        case '<':        case '(':        case ')':        case '#':        case '-':        case '~':            x++;            break;        default:            if(!show[(int)*x])            {                letter[letter_num]=*x;                letter_num++;                show[(int)*x]=1;            }            x++;            break;        }    }    return letter_num;}char com(char x1,char x2){    int i1=get(x1);    int i2=get(x2);    if(in[i1] > out[i2])        return 1;    else if(in[i1] < out[i2])        return 2;    else        return 3;}bool if_variable(char x){    switch(x)    {    case '^':    case 'V':    case '>':    case '<':    case '(':    case ')':    case '#':    case '\0':        return false;    default:        return true;    }}int figure(int x1,int rel,int x2){    switch(rel)    {    case 0:        return x1&&x2;//与    case 1:        return x1||x2;//或    case 2:        return x1||!x2;//蕴含    case 3:        return (!x1&&!x2)||(x1&&x2);//等价    }    return 0;}

0 0