zoukankan      html  css  js  c++  java
  • 离散数学真值表的计算

    大一菜鸡肝了近两个小时的成果,用于计算真值表;
    拿来水一篇博客(并不);
    代码中比较重要的两部分是原式向后缀式的转换,遍历所有原子命题的可能取值;
    具体的细节看代码吧,尽量添加了注释;

    #include<bits/stdc++.h>
    
    using namespace std;
    
    const int maxn = 105;
    const int maxstr = 1e5 + 10;
    char s[maxstr],str[maxstr],Vstr[maxn];//依次为原式,后缀式,存放原子命题的符号
    bool var[maxn];//不同原子命题的真值
    map<char,int>v;//储存原子命题对应的编号
    
    void Print_true(bool b){//打印bool对应的真值符号
        if(b) printf("T	");
        else printf("F	");
    }
    
    int Priority(char c){//返回运算符的优先级
        int p;
        switch (c) {
            case '!': p = 5; break;
            case '&': p = 4; break;
            case '|': p = 3; break;
            case '-': p = 2; break;
            case '=': p = 1; break;
            default : p = 0; break;
        }
        return p;
    }
    
    bool ToPostfix(){//原式转化为后缀表达式
        int cnt = 0;
        int len = strlen(s);
        stack<char>ope;
        for(int i=0; i<len; i++){
            if(s[i] == '('){
                ope.push(s[i]);
            }
            else if(s[i] == ')'){
                if(ope.empty()) return false;
                while(ope.top() != '('){
                    str[cnt++] = ope.top();
                    ope.pop();
                    if(ope.empty()) return false;
                }
                ope.pop();
            }
            else if(Priority(s[i]) == 0){
                str[cnt++] = s[i];
            }
            else {
                if(ope.empty()){
                    ope.push(s[i]);
                }
                else {
                    if(Priority(s[i]) > Priority(ope.top())){
                        ope.push(s[i]);
                    }
                    else{
    		    while(!ope.empty() && ope.top() != '(' && Priority(s[i]) <= Priority(ope.top())) {
                        str[cnt++] = ope.top();
                        ope.pop();
    		    }
                        ope.push(s[i]);
                    }
                }
            }
        }
        while(!ope.empty()){
            str[cnt++] = ope.top();
            ope.pop();
        }
        str[cnt] = 0;
        return true;
    }
    
    bool Calculate(bool a, bool b, char ope){//进行真值的运算
        bool ans;
        if(ope == '&'){
            if(a == true && b == true) ans = true;
            else ans = false;
        }
        else if(ope == '|'){
            if(a == true || b == true) ans = true;
            else ans = false;
        }
        else if(ope == '-'){
            if(a == true && b == false) ans = false;
            else ans = true;
        }
        else if(ope == '='){
            if(a == b) ans = true;
            else ans = false;
        }
        return ans;
    }
    void init_var(int n, int sum){//对var数组初始化
        while(sum>0){
            bool x = sum%2;
            var[n--] = x;
            sum /= 2;
        }
        do{
            var[n--] = false;
        }while(n > 0);
    }
    bool Result(){//对后缀式进行计算
        stack<bool>res;
        int len = strlen(str);
        for(int i=0; i<len; i++){
            if(str[i] == '!'){
                if(res.empty()){
                    printf("计算出现异常!
    ");
                }
                else {
                    bool f = res.top();
                    // printf("text = %d
    ",f);
                    res.pop();
                    res.push(!f);
                }
            }
            else if(Priority(str[i])){
                bool a,b;
                if(res.empty()) printf("计算出现异常!
    ");
                else {
                    b = res.top();
                    res.pop();
                }
                if(res.empty()) printf("计算出现异常!
    ");
                else {
                    a = res.top();
                    res.pop();
                }
                bool ans = Calculate(a, b, str[i]);
                res.push(ans);
            }
            else {
                res.push(var[v[str[i]]]);
            }
        }
        return res.top();
    }
    
    void Print_Out(){//打印提示语
        printf("您好,欢迎使用离散数学真值表计算V1.2版本。
    ");
        printf("使用说明:数据为多组输入,每组一行,直接输入命题公式即可。
    ");
        printf("注:命题变元必须使用小写或大写字母表示。
    ");
        printf("联结词说明(英文符号): 非:! 合取:& 析取:|(逻辑或) 条件:-(负号) 双条件:=
    ");
    }
    
    void NumOfVar(int &n){//提取命题公式中的变元
        int len = strlen(s);
        bool asi[200];
        memset(asi, false, sizeof(asi));
        for(int i=0; i<len; i++){
            asi[s[i]] = true;
        }
        n = 0;
        for(int i='A'; i<='Z'; i++){
            if(asi[i]){
                Vstr[++n] = i;
                v[i] = n;
            }
        }
        for(int i='a'; i<='z'; i++){
            if(asi[i]){
                Vstr[++n] = i;
                v[i] = n;
            }
        }
    }
    
    int main(){
        int n,cnt=0;
        Print_Out();
        printf("
    请输入第%d组:
    ",++cnt);
        while(~scanf("%s",s)){
            v.clear();
            NumOfVar(n);
            if(ToPostfix()==false){
                printf("您输入的原式错误
    ");
            }
            else {
                //标题栏的输出
                for(int i=1; i<=n; i++){
                    printf("%c	",Vstr[i]);
                }
                printf("%s
    ",s);
                //打印各部分真值
                int m = pow(2,n);
                for(int i=0; i<m; i++){
                    init_var(n, i);
                    for(int j=1; j<=n; j++){
                        Print_true(var[j]);
                    }
                    bool ans = Result();
                    Print_true(ans);
                    printf("
    ");
                }
                printf("
    ");
                printf("请输入第%d组:
    ",++cnt);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    redis性能优化、内存分析及优化
    代码质量审核和管理工具分析比较
    SpringBoot集成Nacos
    Navicat,Dbeaver,heidiSql,DataGrip数据库连接工具比较
    python报错:
    6.Python深入_内存管理
    Win7安装python第三方模块objgraph报错
    5.Python深入_装饰器
    4.Python深入_闭包
    1.Python深入_对象的属性
  • 原文地址:https://www.cnblogs.com/sdutzxr/p/12457310.html
Copyright © 2011-2022 走看看