离散数学中的命题表达式计算并生成真值表

虽然很简单吧,但是毕竟算是除了刷题外第一个自己写出来的有一点用的代码,所以还是打算水一篇博客

主要思路就是把式子转化成后缀表达式,然后再用后缀表达式求值的方法来计算,其中每个命题变元的情况是用没有剪枝的深搜枚举出来的
下面是代码
ps:第一版代码的条件语句计算出了点问题,已经改了,顺便加了个多组输入

#include<cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <string>
#include <stack>
#include <map>
using namespace std;
map<char,int> q;
map<char,int> a;
string str;
bool true_false[50];
bool tf[2] = {true, false};
int cnt = 0;
string course[105];
bool count_out(){
    stack<bool> b;
    for(int i = 0;i<str.size();i++){
        if(str[i]=='#'){
            break;
        }
        if(isalpha(str[i])){
            b.push(true_false[a[str[i]]]);
        }else if(str[i]=='!'){
            bool A = b.top();
            b.pop();
            b.push(!A);
        }else if(str[i] == '&'){
            bool A = b.top();
            b.pop();
            bool B = b.top();
            b.pop();
            b.push(A&&B);
        }else if(str[i] == '|'){
            bool A = b.top();
            b.pop();
            bool B = b.top();
            b.pop();
            b.push(A||B);
        }else if(str[i] == '-'||str[i]=='%'){
            bool A = b.top();
            b.pop();
            bool B = b.top();
            b.pop();
            b.push(!(!A&&B));
        }else if(str[i] == '='){
            bool A = b.top();
            b.pop();
            bool B = b.top();
            b.pop();
            b.push((A&&B)||(!A&&!B));
        }
    }
    return b.top();
}
void deep(int i){
    if(i==cnt+1){
        for(int j = 1;j<=cnt;j++){
            cout<<(true_false[j]?"T ":"F ");
        }
        cout<<'\t';
        cout<<(count_out()?"T":"F")<<endl;//计算后缀式的值
        return;
    }else{
        for(int j = 0;j<2;j++){
            true_false[i] = tf[j];
            deep(i+1);
        }
    }
}
void init(){
    q.clear();
    memset(true_false,0, sizeof(true_false));
    str.clear();
    a.clear();
    q['#'] = -1;
    q['('] = 0;
    q['!'] = 6;
    q['&'] = 5;
    q['|'] = 4;
    q['-'] = 3;
    q['='] = 2;
    q['%'] = 1;
    cnt = 0;
}
void output(string s,string s_out){
    for(int i = 0;i<s_out.size();i++){
        cout<<s_out[i]<<' ';
    }
    cout<<s<<endl;
}
string getRPN(string s){
    string s_out;
    stack<char> operation;
    for(int i = 0;i<s.size();i++){
        if(s[i]=='#')   break;
        if(isalpha(s[i])){
            str+=s[i];
            if(!a[s[i]]){
                s_out+=s[i];
                a[s[i]] = ++cnt;
            }
        }else{
            if(operation.empty())   operation.push(s[i]);
            else if(s[i]=='(')
                operation.push(s[i]);
            else if(s[i]==')'){
                while(operation.top()!='('){
                    str+=operation.top();
                    operation.pop();
                }
                operation.pop();
            }
            else if(q[s[i]]>q[operation.top()]){
                operation.push(s[i]);
            }else{
                str+=operation.top();
                operation.pop();
                operation.push(s[i]);
            }
        }
    }
    while(!operation.empty()){
        str+=operation.top();
        operation.pop();
    }
    str+='#';
    return s_out;
}
int main() {
    ios::sync_with_stdio(false);
    string s;
    while(cin>>s){
        init();  //初始化
        string s_out = getRPN(s);  //将命题表达式转为后缀式并输出表头
        output(s,s_out);
        deep(1);    //搜索找所有命题变元的TF情况
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/rwbyblake/article/details/106224656