c++解决问题给定合式公式,先输出其真值表,再利用真值表法求出主析取范式以及主合取范式给出主要函数的功能描述以及程序源代码

时间: 2024-03-17 18:46:37 浏览: 15
以下是一个用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函数即可。

相关推荐

用c++写 同学们都学习过《离散数学》这门课程,知道真值表是用于逻辑中的一类数学用表,用来计算逻辑表示式在每一个逻辑变量取值组合下的值。在这里我们给定一个逻辑表达式,要求生成对应的真值表。提示一下,数据结构教材中介绍了数学表达式的处理算法,可以将其改造以适用于我们的项目。 项目分为三个子项目,第一部分为词法分析,即将逻辑表达式分隔为多个词(token)。下面给出两个例子。 例一: 逻辑表达式p^q中有p、^和q共三个词; 例二: 逻辑表达式p^(q^r)中有p、^、(、q、^、r和)共七个词。 逻辑联结词有五个,见下表,这些符号和教材上的有所不同,主要是为了方便。 否定 合取 析取 蕴涵 等值 ! ^ || -> <-> 引入括号,规定基本逻辑联接词优先顺序从高到低依次是:( )、!、∧、||、->、<->。 同一优先级,从左到右顺序进行。 输入 输入由多行组成,每行都是一个正确的逻辑表达式。 逻辑表达式小于100个字符。 一个正确的逻辑表达式可以包含小写字母,空格和逻辑联结词(含括号)。单个小写字母表示一个逻辑变量,一个表达式中逻辑变量的个数不超过10。空格作为分隔符, 不是词,同一个词的字符之间不能有空格。 输出 每一个逻辑表达式产生如下的输出: 第一行按顺序输出表达式中的所有词。每个词之间用空格分开。 第二行按字母序输出表达式中的所有逻辑变量,用空格分开。 第三行开始输出逻辑变量值的所有组合情况。 具体见样例。 样例输入 Copy p p->q p||q 样例输出 Copy p p 1 0 p -> q p q 1 1 1 0 0 1 0 0 p || q p q 1 1 1 0 0 1 0 0

最新推荐

recommend-type

C++ Eigen库计算矩阵特征值及特征向量

主要为大家详细介绍了C++ Eigen库计算矩阵特征值及特征向量,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
recommend-type

c++获取sqlite3数据库表中所有字段的方法小结

本文给大家分享c++获取sqlite3数据库表中所有字段的三种常用方法,本文针对每一种方法给大家详细介绍,需要的的朋友通过本文一起学习吧
recommend-type

C++实现图形界面时钟表盘代码

主要介绍了C++实现图形界面时钟表盘代码,涉及坐标函数的应用及图形界面程序设计,需要的朋友可以参考下
recommend-type

C++双向链表实现简单通讯录

主要为大家详细介绍了C++双向链表实现简单通讯录,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
recommend-type

C++实现十六进制字符串转换成int整形值的示例

今天小编就为大家分享一篇关于C++实现十六进制字符串转换成int整形值的示例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

【实战演练】MATLAB用遗传算法改进粒子群GA-PSO算法

![MATLAB智能算法合集](https://static.fuxi.netease.com/fuxi-official/web/20221101/83f465753fd49c41536a5640367d4340.jpg) # 2.1 遗传算法的原理和实现 遗传算法(GA)是一种受生物进化过程启发的优化算法。它通过模拟自然选择和遗传机制来搜索最优解。 **2.1.1 遗传算法的编码和解码** 编码是将问题空间中的解表示为二进制字符串或其他数据结构的过程。解码是将编码的解转换为问题空间中的实际解的过程。常见的编码方法包括二进制编码、实数编码和树形编码。 **2.1.2 遗传算法的交叉和
recommend-type

openstack的20种接口有哪些

以下是OpenStack的20种API接口: 1. Identity (Keystone) API 2. Compute (Nova) API 3. Networking (Neutron) API 4. Block Storage (Cinder) API 5. Object Storage (Swift) API 6. Image (Glance) API 7. Telemetry (Ceilometer) API 8. Orchestration (Heat) API 9. Database (Trove) API 10. Bare Metal (Ironic) API 11. DNS
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。