c++解决问题给定合式公式,先输出其真值表,再利用真值表法求出主析取范式以及主合取范式给出主要函数的功能描述以及程序源代码
时间: 2024-03-17 08:46:37 浏览: 68
命题公式的真值表及主析取主合取范式
4星 · 用户满意度95%
以下是一个用C++实现的程序,可以根据给定的合式公式输出其真值表,并利用真值表法求出主析取范式和主合取范式。
程序源代码:
```c++
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
using namespace std;
// 命题变元结构体
struct PropVar {
string name; // 变元名称
bool val; // 变元取值
};
// 合式公式结构体
struct Formula {
string expr; // 公式表达式
vector<PropVar> vars; // 命题变元
};
// 判断命题公式的真值
bool calcFormula(Formula f) {
string expr = f.expr;
for (int i = 0; i < f.vars.size(); i++) {
while (true) {
int j = expr.find(f.vars[i].name);
if (j == string::npos) break;
expr.replace(j, f.vars[i].name.size(), (f.vars[i].val) ? "1" : "0");
}
}
while (true) {
int j = expr.find("~");
if (j == string::npos) break;
expr.replace(j, 1, "!");
}
for (int i = 0; i < expr.size(); i++) {
if (expr[i] == '!') {
int j = i + 1;
while (expr[j] == ' ') j++;
if (expr[j] == '0') expr.replace(i, j - i + 1, "1");
else if (expr[j] == '1') expr.replace(i, j - i + 1, "0");
else {
bool r = calcFormula(f);
if (r) expr.replace(i, j - i + 1, "0");
else expr.replace(i, j - i + 1, "1");
}
}
}
while (true) {
int j = expr.find("&&");
if (j == string::npos) break;
int k = j + 2;
while (expr[k] == ' ') k++;
int p = k + 1;
while (expr[p] == ' ') p++;
bool b1 = (expr[j - 1] == '1');
bool b2 = (expr[k] == '1');
bool r = b1 && b2;
string s = (r) ? "1" : "0";
expr.replace(j - 1, p - j + 1, s);
}
while (true) {
int j = expr.find("||");
if (j == string::npos) break;
int k = j + 2;
while (expr[k] == ' ') k++;
int p = k + 1;
while (expr[p] == ' ') p++;
bool b1 = (expr[j - 1] == '1');
bool b2 = (expr[k] == '1');
bool r = b1 || b2;
string s = (r) ? "1" : "0";
expr.replace(j - 1, p - j + 1, s);
}
return (expr == "1");
}
// 输出命题公式的真值表
void printTruthTable(Formula f) {
int n = f.vars.size();
for (int i = 0; i < n; i++) {
cout << f.vars[i].name << " ";
}
cout << "F" << endl;
for (int i = 0; i < pow(2, n); i++) {
for (int j = 0; j < n; j++) {
f.vars[j].val = ((i >> (n - j - 1)) & 1);
cout << ((f.vars[j].val) ? "1" : "0") << " ";
}
bool r = calcFormula(f);
cout << ((r) ? "1" : "0") << endl;
}
}
// 判断是否是主取范式项
bool isMinterm(Formula f, int i) {
int n = f.vars.size();
for (int j = 0; j < n; j++) {
int k = (i >> (n - j - 1)) & 1;
if (f.vars[j].val != k) return false;
}
return true;
}
// 判断是否是主合取范式项
bool isMaxterm(Formula f, int i) {
int n = f.vars.size();
for (int j = 0; j < n; j++) {
int k = (i >> (n - j - 1)) & 1;
if ((f.vars[j].val && k) || (!f.vars[j].val && !k)) return false;
}
return true;
}
// 输出主取范式
void printMinterms(Formula f) {
int n = f.vars.size();
for (int i = 0; i < pow(2, n); i++) {
if (isMinterm(f, i)) {
for (int j = 0; j < n; j++) {
int k = (i >> (n - j - 1)) & 1;
cout << ((k) ? f.vars[j].name : "~" + f.vars[j].name);
if (j < n - 1) cout << " && ";
}
cout << " || ";
}
}
cout << endl;
}
// 输出主合取范式
void printMaxterms(Formula f) {
int n = f.vars.size();
for (int i = 0; i < pow(2, n); i++) {
if (isMaxterm(f, i)) {
for (int j = 0; j < n; j++) {
int k = (i >> (n - j - 1)) & 1;
cout << ((!k) ? f.vars[j].name : "~" + f.vars[j].name);
if (j < n - 1) cout << " || ";
}
cout << " && ";
}
}
cout << endl;
}
int main() {
Formula f;
f.expr = "((A && B) || (!C && D)) && (E || F)";
PropVar pv;
pv.name = "A";
f.vars.push_back(pv);
pv.name = "B";
f.vars.push_back(pv);
pv.name = "C";
f.vars.push_back(pv);
pv.name = "D";
f.vars.push_back(pv);
pv.name = "E";
f.vars.push_back(pv);
pv.name = "F";
f.vars.push_back(pv);
printTruthTable(f);
printMinterms(f);
printMaxterms(f);
return 0;
}
```
程序使用时需要将合式公式和命题变元添加到Formula结构体中,然后调用printTruthTable、printMinterms和printMaxterms函数即可。
阅读全文