C++实现基于二元真值(0 表示假、1 表示真)的三元命题逻辑运算系统
这是一款针对 p、q、r 三个变元的二元真值(0 假、1 真)命题逻辑工具,核心实现中缀公式转后缀、真值计算、真值表生成及主析取 / 合取式输出,下面从功能和应用两方面精简解析。
核心功能:中缀命题公式转后缀、生成真值表、输出主析取 / 合取式;
实现核心:栈结构处理表达式与真值计算,三层循环遍历变元真值组合;
核心应用:逻辑学习、离散数学实验、简单数字电路设计辅助。
一、核心功能实现
整体流程:输入中缀命题公式→转后缀表达式→真值计算与真值表生成→输出两种范式,各模块分工明确。
1. 前期准备
全局变量:Array_one/Array_two存储主析取 / 合取式对应的变元真值组合,Counter_one/Counter_two记录组合数量;Stack(操作符栈)、Num(真值栈)支撑表达式转换与计算;save存储后缀表达式,s存储输入的中缀公式。
函数分工:涵盖优先级比较、表达式转换、5 种逻辑运算、真值计算、范式输出,支撑全流程执行。
2. 中缀转后缀表达式(Transform函数)
将人类易输入的中缀公式(如p&!q>r)转为计算机易计算的后缀表达式(逆波兰式,如pq!&r>):
字母(p/q/r)直接存入save;
操作符 / 括号:栈空直接入栈,非右括号操作符直接入栈,右括号则弹出栈顶操作符至save,直到遇到左括号(最后弹出左括号不存入);
遍历结束后,将栈内剩余操作符全部弹出存入save,完成转换。
3. 操作符优先级比较(Amp函数)
为表达式转换提供优先级依据,从高到低:((5) > !(非,4) > &(与,3) > |(或,2) > >(条件,1) > $(双条件,0) > )(-1),符合命题逻辑运算规则。
4. 真值计算与真值表生成(Truenum函数)
三层循环遍历 p、q、r 的 8 种真值组合(2³=8);
遍历后缀表达式:字母对应变元真值压入Num栈,操作符调用对应运算函数;
输出当前变元真值与公式结果,生成真值表;
分类存储:公式结果为 1 存入Array_one(主析取式备用),为 0 存入Array_two(主合取式备用),最后清空真值栈。
5. 五种逻辑运算实现
非运算(fei):弹出栈顶真值取反,结果压栈;
与运算(yu):弹出两个真值执行逻辑与,结果压栈;
或运算(huo):弹出两个真值执行逻辑或,结果压栈;
条件运算(tiaojian):蕴含关系,仅前件 1、后件 0 时结果为 0,其余为 1;
双条件运算(Shuangtiaojian):等价关系,两真值相等时结果为 1,否则为 0。
6. 主析取 / 合取式输出
主析取式(Output_xiqu):所有使公式为真的极小项析取(|)组合,真值 1 保留原变元、0 取非,变元间用 & 连接,极小项间用 | 连接;
主合取式(Output_hequ):所有使公式为假的极大项合取(&)组合,真值 0 保留原变元、1 取非,变元间用 | 连接,极大项间用 & 连接。
7. 主函数调度
程序入口,依次完成:输出系统提示→接收用户输入→中缀转后缀→生成真值表→输出主合取式与主析取式→程序退出。
二、应用场景
逻辑学学习辅助:帮助初学者理解命题公式真值规律、表达式转换及范式含义,验证手动计算结果的正确性。
命题逻辑问题求解:验证命题公式等价性,判定公式类型(重言式、矛盾式、可满足式)。
数字电路设计辅助:对应门电路逻辑,生成真值表并简化逻辑表达式,辅助组合逻辑电路设计。
离散数学实验参考:直接完成真值表、范式转换类实验,也可作为栈、逻辑运算编程实现的参考案例。
三、注意事项
仅支持 p、q、r 三个变元,仅支持二元真值(0/1),非真正 “三元逻辑”;
中缀转后缀函数存在瑕疵,复杂表达式可能转换错误;
输入公式需符合语法规范,括号需成对,无非法字符。
#include<iostream>
#include<cctype>
#include<set>
#include<string>
#include<stack>
using namespace std;
#define Max 1000
int Array_one[Max][3] = { 0 }, Array_two[Max][3] = { 0 }, Counter_one = 0, Counter_two = 0; // 储存各个变元的真值,计数器
string s; // 储存命题公式
stack<char> Stack; // 操作符栈
stack<int> Num; // 真值栈
char save[Max], c; // 后缀表达式及临时字符
int follow = 0; // 计数器
int p, q, r; // 储存真值
int Amp(char a); // 操作符优先级比较函数
void Transform(); // 中缀表达式转后缀表达式
void fei(); // 非运算
void yu(); // 与运算
void huo(); // 或运算
void tiaojian(); // 条件运算
void Shuangtiaojian(); // 双条件运算
void Truenum(); // 真值运算
void Output_xiqu(); // 输出主析取式
void Output_hequ(); // 输出主合取式
int main() {
cout << "------------------------------------------------欢迎您进入三元逻辑运算系统---------------------------------------------" << endl;
cout << "变元为p,q,r" << endl;
cout << "! 非运算,& 与运算,| 或运算,> 条件运算,$ 双条件运算,( 左括号,) 右括号" << endl;
cout << "请输入命题公式!" << endl;
cin >> s;
Transform();
cout << "\t\t\t**真值表**" << endl;
cout << "p\t\t" << "q\t\t" << "r\t\t" << s << endl;
Truenum();
Output_hequ(); // 输出主合取式
Output_xiqu(); // 输出主析取式
cout << endl;
return 0;
}
int Amp(char a) {
switch (a) {
case '(': return 5; break;
case '!': return 4; break;
case '&': return 3; break;
case '|': return 2; break;
case '>': return 1; break;
case '$': return 0; break;
case ')': return -1; break;
}
}
void Transform() {
for (int i = 0; i < s.length(); i++) { // 遍历命题公式
c = s[i]; // 临时储存字符
if (isalpha(c)) // 如果为字母, 后缀表达式直接储存
save[follow++] = c;
if (c == '!' || c == '&' || c == '|' || c == '>' || c == '$' || c == '(' || c == ')') { // 操作符处理
if (Stack.empty()) Stack.push(c); // 栈为空,直接压入
else if (c != ')') Stack.push(c); // 遇到操作符直接入栈
else if (c == ')') { // 右括号处理
while (!Stack.empty() && Amp(Stack.top()) > Amp(c)) { // 优先级大于当前的操作符
if (Stack.top() == '(') break; // 如果是左括号,则退出
save[follow++] = Stack.top(); // 存储栈顶操作符
Stack.pop(); // 弹出栈顶操作符
}
if (Stack.top() == '(') Stack.pop(); // 弹出左括号
}
}
}
while (!Stack.empty()) { // 将剩余操作符处理完
save[follow++] = Stack.top();
Stack.pop();
}
}
void Truenum() {
for (p = 0; p <= 1; p++) {
for (q = 0; q <= 1; q++) {
for (r = 0; r <= 1; r++) {
cout << p << "\t\t" << q << "\t\t" << r << "\t\t";
for (int i = 0; i < follow; i++) {
c = save[i]; // 临时存储字符
if (isalpha(c)) { // 变元时处理真值
switch (c) {
case 'p': Num.push(p); break;
case 'q': Num.push(q); break;
case 'r': Num.push(r); break;
}
}
else if (c == '!') fei(); // 非运算
else if (c == '&') yu(); // 与运算
else if (c == '|') huo(); // 或运算
else if (c == '>') tiaojian(); // 条件运算
else if (c == '$') Shuangtiaojian(); // 双条件运算
}
cout << Num.top() << endl;
if (Num.top() == 1) { // 判断主析取式
Array_one[Counter_one][0] = p;
Array_one[Counter_one][1] = q;
Array_one[Counter_one++][2] = r;
}
else { // 判断主合取式
Array_two[Counter_two][0] = p;
Array_two[Counter_two][1] = q;
Array_two[Counter_two++][2] = r;
}
Num.pop();
}
}
}
}
void Output_xiqu() {
cout << "主析取式" << endl;
for (int i = 0; i < Counter_one; i++) {
cout << "(";
if (Array_one[i][0] == 0) cout << "(!p)";
else cout << "p";
if (Array_one[i][1] == 0) cout << "&(!q)";
else cout << "&q";
if (Array_one[i][2] == 0) cout << "&(!r)";
else cout << "&r";
if (i == Counter_one - 1) cout << ")";
else cout << ")|";
}
cout << endl;
}
void Output_hequ() {
cout << "主合取式" << endl;
for (int i = 0; i < Counter_two; i++) {
cout << "(";
if (Array_two[i][0] == 0) cout << "p";
else cout << "(!p)";
if (Array_two[i][1] == 0) cout << "|q";
else cout << "|(!q)";
if (Array_two[i][2] == 0) cout << "|r";
else cout << "|(!r)";
if (i == Counter_two - 1) cout << ")";
else cout << ")&";
}
cout << endl;
}
void fei() {
int True = !Num.top(); Num.pop(); // 弹出一个真值, 进行非运算
Num.push(True); // 操作结果压栈
}
void yu() {
int True_one = Num.top(); Num.pop();
int True_two = Num.top(); Num.pop();
int True = True_one && True_two;
Num.push(True); // 操作结果压栈
}
void huo() {
int True_one = Num.top(); Num.pop();
int True_two = Num.top(); Num.pop();
int True = True_one || True_two;
Num.push(True); // 操作结果压栈
}
void tiaojian() {
int True_one = Num.top(); Num.pop();
int True_two = Num.top(); Num.pop();
int True;
if (True_one == 0 && True_two == 1) True = 0;
else True = 1;
Num.push(True); // 操作结果压栈
}
void Shuangtiaojian() {
int True_one = Num.top(); Num.pop();
int True_two = Num.top(); Num.pop();
int True;
if (True_one == True_two) True = 1;
else True = 0;
Num.push(True);
}
更多推荐


所有评论(0)