离散数学中的命题表达式计算

Posted rwbyblake

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了离散数学中的命题表达式计算相关的知识,希望对你有一定的参考价值。

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

主要思路就是把式子转化成后缀表达式,然后再用后缀表达式求值的方法来计算,其中每个命题变元的情况是用没有剪枝的深搜枚举出来的
下面是代码

#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;

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] == '?'){
            bool A = b.top();
            b.pop();
            bool B = b.top();
            b.pop();
            b.push(!(!B && A));
        }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<<'	';
        cout<<(count_out()?"T":"F")<<endl;
        return;
    }else{
        for(int j = 0;j<2;j++){
            true_false[i] = tf[j];
            deep(i+1);
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    string s;

    cin>>s;
    stack<char> operation;
    q['#'] = -1;
    q['('] = 0;
    q['!'] = 5;
    q['&'] = 4;
    q['|'] = 3;
    q['?'] = 2;
    q['~'] = 1;
    string s_out;
    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+='#';
    //cout<<str<<endl;
    for(int i = 0;i<s_out.size();i++){
        cout<<s_out[i]<<' ';
    }
    cout<<s<<endl;
    deep(1);
    return 0;
}

以上是关于离散数学中的命题表达式计算的主要内容,如果未能解决你的问题,请参考以下文章

《离散数学》-命题逻辑-等值运算公式

南航计算机科学与技术专业复试科目541离散数学和编译原理

离散数学知识点整理

离散数学课程重点

离散数学基础(命题逻辑)

离散数学--2.4 命题逻辑推理理论