C++实现离散数学之真值表(试着自写头文件)

思路参考: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");
}

 

  • 5
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是一份实现已知命题公式真值表的 C 代码: ```c #include <stdio.h> #include <stdbool.h> #include <math.h> #define MAX_N 4 int n; char formula[100]; bool values[MAX_N]; int get_value(char c) { return c - 'A'; } bool calculate(bool a, bool b, char op) { switch (op) { case '+': return a || b; case '^': return a && b; case '>': return !a || b; case '-': return a == b; case '!': return !a; } return false; } bool evaluate(int pos, int end) { if (pos == end) { return values[get_value(formula[pos])]; } if (formula[pos] == '!') { return !evaluate(pos + 1, end); } int depth = 0; bool a, b; for (int i = pos; i <= end; i++) { if (formula[i] == '(') depth++; else if (formula[i] == ')') depth--; else if (depth == 0 && (formula[i] == '+' || formula[i] == '^' || formula[i] == '>' || formula[i] == '-')) { a = evaluate(pos, i - 1); b = evaluate(i + 1, end); return calculate(a, b, formula[i]); } } return evaluate(pos + 1, end - 1); } void print_table() { int rows = (int)pow(2, n); printf("|"); for (int i = 0; i < n; i++) { printf(" %c |", 'A' + i); } printf(" %s |\n", formula); for (int i = 0; i < rows; i++) { for (int j = 0; j < n; j++) { values[j] = (i >> (n - j - 1)) & 1; printf("| %c |", values[j] ? 'T' : 'F'); } printf(" %c |\n", evaluate(0, strlen(formula) - 1) ? 'T' : 'F'); } } int main() { scanf("%d", &n); scanf("%s", formula); print_table(); return 0; } ``` 该代码使用递归方法计算命题公式的真值。首先,根据公式中的每个命题符号,生成一个二进制数列,以列的形式输出真值表。然后,对于每一行,根据二进制数列设置命题符号的真值,并计算整个公式的真值,最后以行的形式输出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值