求命题公式的主范式(C++语言)

实现功能:输入命题公式的合式公式,求出公式的真值表,并输出该公式的主合取范式和主析取范式。

输入:命题公式的合式公式

输出:公式的主析取范式和主析取范式,输出形式为:“ mi ∨ mj ; Mi ∧ Mj” ,极小项和 ∨ 符号之间有一个空格,极大项和 ∧ 符号之间有一个空格;主析取范式和主合取范式之间用“ ; ”隔开,“ ; ”前后各有一个空格。 永真式的主合取范式为 1 ,永假式的主析取范式为 0 。

输入公式的符号说明:

! 非,相当于书面符号中的 “ ¬ ”

& 与,相当于书面符号中的 “ ∧ ”

| 或,相当于书面符号中的 “ ∨ ”

- 蕴含联结词,相当于书面符号中的 “ → ”

+ 等价联结词,相当于书面符号中的 “ ↔ ”

( 前括号

) 后括号


样例

输入(1)

a&b

输出(1)

m3 ; M0 ∧ M1 ∧ M2

输入(2)

a|b

输出(2)

m1 ∨ m2 ∨ m3 ; M0

代码

#include<iostream>
#include<cmath>
#include<string>
#include<cstring>
#include<algorithm>  // Added for the sort function
using namespace std;

int op_rank(char a) {
    switch (a) {
        case '(': return 0;
        case '+': return 1;
        case '-': return 2;
        case '&': return 3;
        case '|': return 4;
        case '!': return 5;
        case ')': return 6;
        default: return -1; // Handle unknown operators
    }
}

bool is_in(char a, string x) {
    for(unsigned int i = 0; i < x.size(); i++) {
        if (x[i] == a) return true;
    }
    return false;
}

string post_rpn(string &input) {
    string stack, output;
    for(unsigned int i = 0; i < input.size(); i++) {
        if (is_in(input[i], "()+-&|!")) {
            if (input[i] == ')') {
                while (!stack.empty() && stack.back() != '(') {
                    output += stack.back();
                    stack.pop_back();
                }
                if (!stack.empty()) {
                    stack.pop_back(); // Remove the '('
                }
            }
            else {
                while (!stack.empty() && op_rank(stack.back()) >= op_rank(input[i]) && input[i] != '(') {
                    output += stack.back();
                    stack.pop_back();
                }
                stack += input[i];
            }
        }
        else output += input[i];
    }
    while (!stack.empty()) {
        output += stack.back();
        stack.pop_back();
    }
    return output;
}

string how_many_elements(string a) {
    string b = "";
    for(unsigned int i = 0; i < a.size(); i++) {
        if (a[i] >= 'a' && a[i] <= 'z' && !is_in(a[i], b)) {
            b += a[i];
        }
    }
    sort(b.begin(), b.end());
    return b;
}

int cal(int a, int b, char c) {
    switch (c) {
        case '+':
            return (a == b) ? 1 : 0;
        case '-':
            return (a == 1 && b == 0) ? 0 : 1;
        case '|':
            return (a + b >= 1) ? 1 : 0;
        case '&':
            return a * b;
        case '!':
            return (a == 1) ? 0 : 1;
        default:
            return 0;
    }
}

int calculate(string a) {
    while (a.size() > 1) {
        for (unsigned int i = 0; i < a.size(); i++) {
            if (is_in(a[i], "+|&-!")) {
                if (a[i] != '!') {
                    a[i - 2] = char(cal(int(a[i - 2] - '0'), int(a[i - 1] - '0'), a[i]) + '0');
                    a.erase(i - 1, 2);
                    break;
                }
                else {
                    a[i - 1] = char(cal(int(a[i - 1] - '0'), 0, a[i]) + '0');
                    a.erase(i, 1);
                    break;
                }
            }
        }
    }
    return int(a[0] - '0');
}

bool is_in2(int a, int *x, int d) {
    for (int i = 0; i < d; i++) {
        if (x[i] == a) return true;
    }
    return false;
}

bool is_in3(int n, int i0, int *x, int d) {
    for (int i = i0 + 1; i < n; i++) {
        if (!is_in2(i, x, d)) return true;
    }
    return false;
}

void PRINT(int *n, string number, int d) {
    if (d == 0) {
        cout << "0 ; ";
    }
    for (int i = 0; i < d; i++) {
        if ((i != d - 1) && is_in2(n[i], n, d)) {
            cout << "m" << n[i] << " ∨ ";
        }
        else if (is_in2(n[i], n, d)) {
            cout << "m" << n[i] << " ; ";
        }
    }
    for (int i = 0; i < pow(2, number.size()); i++) {
        if (!is_in3(pow(2, number.size()), -1, n, d)) {
            cout << "1" << endl;
            break;
        }
        else {
            if (!is_in2(i, n, d) && is_in3(pow(2, number.size()), i, n, d)) {
                cout << "M" << i << " ∧ ";
            }
            else if (!is_in2(i, n, d)) {
                cout << "M" << i << endl;
            }
        }
    }
}

int where_is_element(string number0, char a) {
    for (unsigned int i = 0; i < number0.size(); i++) {
        if (number0[i] == a) return i;
    }
    return -1;
}

void traverse(string number, string output2) {
    string a = "", number0 = number;
    int c[500], d = 0;
    for (int i = 0; i < pow(2, number.size()); i++) {
        int p = i;
        a = "";
        while (p != 0) {
            a = char(p % 2 + '0') + a;
            p = p >> 1;
        }
        int b = 0;
        for (unsigned int j = 0; j < number.size(); j++) {
            if (a.size() < number.size() - j) number[j] = '0';
            else number[j] = a[b++];
        }
        string output = output2;
        for (unsigned int i = 0; i < output.size(); i++) {
            if (output[i] >= 'a' && output[i] <= 'z') {
                int index = where_is_element(number0, output[i]);
                if (index != -1) {
                    output[i] = number[index];
                }
            }
        }
        if (calculate(output) == 1) {
            c[d++] = i;
        }
    }
    PRINT(c, number, d);
}

int main(void) {
    string input;
    cin >> input;
    string elements = how_many_elements(post_rpn(input));
    traverse(elements, post_rpn(input));
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值