实现功能:输入命题公式的合式公式,求出公式的真值表,并输出该公式的主合取范式和主析取范式。
输入:命题公式的合式公式
输出:公式的主析取范式和主析取范式,输出形式为:“ 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;
}