思路参考:https://blog.csdn.net/wjh2622075127/article/details/79843339 感谢作者。
试着写了一下头文件,并修改优化了。
头文件:
#ifndef TRUTH_TABLE_H
#define TRUTH_TABLE_H
#include<iostream>
#include<string>
#include<iomanip>
#include<cmath>
#include<algorithm>
using namespace std;
class TruthTable
{
friend void read(istream& is, TruthTable& formula); //读取输入
friend void print(TruthTable& formula); //计算并输出
public:
void GetVariable(string str, string& var, int& count); //获取命题变元
void fei(string& str); //非
void hequ(string& str); //合取
void xiqu(string& str); //析取
void tiaojian(string& str); //条件
void shuangtiaojian(string& str); //双条件
void ToValue(string& str, int val[]); //赋真值给 变元
void DelKuohao(string& str); //去除无用的括号(括号内只有一个变元的情况)
private:
string str, tmp, var;
int count = 0;
int val[30]{};
};
void TruthTable::GetVariable(string str, string& var, int& count)
{
int ch[30]{};
for (auto i = 0; i != str.size(); ++i)
if (isalpha(str[i]))
++ch[str[i] - 'A'];
for (auto i = 0; i < 26; ++i)
if (ch[i])
{
var.push_back(i + 65);
++count;
}
}
void TruthTable::fei(string& str)
{
for (auto i = 0;i!=str.size();++i)
{
if (i + 1 < str.size() && str[i] == '!' && str[i + 1] == '0')
str.replace(i, 2 , "1");
else if ( i + 1 < str.size() && str[i] == '!' && str[i + 1] == '1')
str.replace(i, 2, "0");
}
}
void TruthTable::hequ(string& str)
{
for (auto i = 0;i!=str.size();++i)
{
if (str[i] == '1' && i + 2 < str.size() && str[i + 2] == '1' && str[i + 1] == '&')
str.replace(i, 3 , "1");
else if (i + 2 < str.size() && str[i + 1] == '&' && ((str[i] == '1' && str[i + 2] == '0')
|| (str[i] == '0' && str[i + 2] == '1') || (str[i] == '0' && str[i + 2] == '0')))
str.replace(i, 3, "0");
}
}
void TruthTable::xiqu(string& str)
{
for (auto i = 0; i != str.size(); ++i)
{
if (str[i] == '0' && i + 2 < str.size() && str[i + 2] == '0' && str[i + 1] == '|')
str.replace(i, 3, "0");
else if (i + 2 < str.size() && str[i + 1] == '|' && ((str[i] == '1' && str[i + 2] == '0')
|| (str[i] == '0' && str[i + 2] == '1') || (str[i] == '1' && str[i + 2] == '1')))
str.replace(i, 3, "1");
}
}
void TruthTable::tiaojian(string& str)
{
for (auto i = 0; i != str.size(); ++i)
{
if (str[i + 1] == '>' && str[i] == '1' && str[i + 2] == '0')
str.replace(i, 3, "0");
else if (str[i + 1] == '>' && ((str[i] == '1' && str[i + 2] == '1')
|| str[i] == '0' && (str[i + 2] == '1' || str[i + 2] == '0')))
str.replace(i, 3, "1");
}
}
void TruthTable::shuangtiaojian(string& str)
{
for (auto i = 0; i != str.size(); ++i)
{
if (str[i + 1] == '-' && ((str[i] == '1' && str[i + 2] == '1') || (str[i] == '0' && str[i + 2] == '0')))
str.replace(i, 3, "1");
else if (str[i + 1] == '-' && ((str[i] == '1' && str[i + 2] == '0') || (str[i] == '0' && str[i + 2] == '1')))
str.replace(i, 3, "0");
}
}
void TruthTable::ToValue(string& str, int val[])
{
for (auto i = 0; i != str.size(); ++i)
{
if (isalpha(str[i]))
str.replace(i, 1, val[str[i] - 'A'] ? "1" : "0");
}
}
void TruthTable::DelKuohao(string& str)
{
for (auto i = 0; i != str.size(); ++i)
{
if (str[i] == '(' && i + 2 < str.size() && str[i + 2] == ')')
{
string s;
s += str[i + 1];
str.replace(i, 3, s);
}
}
}
void read(istream& is, TruthTable& formula)
{
is >> formula.str;
transform(formula.str.begin(), formula.str.end(), formula.str.begin(), ::toupper);
formula.tmp = formula.str;
formula.GetVariable(formula.str, formula.var, formula.count);
}
void print(TruthTable& formula)
{
for (auto i : formula.var) //输出真值表格式第一行
cout << i << " ";
cout << formula.str << endl;
for (int i = 0; i != pow(2, formula.count); ++i) //二进制枚举法
{
for (int j = 0; j != formula.count; ++j)
formula.val[formula.var[j] - 'A'] = (1 & (i >> (formula.count - 1 - j))); //位运算赋值
for (int j = 0; j != formula.count; ++j)
cout << formula.val[formula.var[j] - 'A'] << " ";
formula.ToValue(formula.str, formula.val);
while (formula.str.size() != 1)
{
formula.DelKuohao(formula.str);
formula.fei(formula.str);
formula.hequ(formula.str);
formula.xiqu(formula.str);
formula.tiaojian(formula.str);
formula.shuangtiaojian(formula.str);
}
cout << setw(formula.tmp.size() / 2 + 1) << formula.str << endl;
formula.str = formula.tmp;
}
}
#endif // !TRUTH_TABLE
C++文件:
//定义: !为非 &为合取 |为析取 >为条件 -为双条件
#include"TrueTable.h"
int main()
{
TruthTable formula;
cout << "请输入命题公式(命题变元是大写字母)" << endl;
cout << "注:定义:!为非 &为合取 |为析取 >为条件 -为双条件" << endl;
read(cin, formula);
print(formula);
system("pause");
}