利用真值表法求取主析取范式以及主合取范式的实现
离散数学14.主合取范式

例2 求((PQ)R)P的主合取范式. 解: 原式 ((P∨Q)∨R)∨P (P∨Q)∧(R∨P ) (合取范式) ((P∨Q)∨(R∧R ))∧((R∨P )∨(Q∧Q)) (P∨Q∨R)∧(P∨Q∨R)∧(P∨Q∨R)∧ (P∨Q∨R) (P∨Q∨R)∧(P∨Q∨R)∧(P∨Q∨R) (主合取范式)
⑶用“∧”联结上述大项,即可.
例1 求 PQ和PQ的主合取范式
P Q PQ PQ
FF T
T
FT T
F
TF F
F
TT T
T
PQ M2 P∨Q PQ M1∧M2
(P∨Q )∧(P∨Q)
方法2:用公式的等价变换 ⑴先写出给定公式的合取范式
A1∧A2∧...∧An . ⑵除去合取范式中的所有为永真的合取项. ⑶合并相同的析取项和相同的变元. (4)为使每个Ai变成大项,对缺少变元的析取式Ai补全变
主合取范式
主合取范式
1.定义:给定的命题公式,如果有一个等价公式, 它仅由大项的合取所组成,则该等价式称作原式的主 合取范式.
2.主合取范式的求法 方法1:列真值表 ⑴列出给定公式的真值表. ⑵找出真值表中每个“F”对应的大项.
如何根据一组指派写对应的为“F”的大项:如果变 元P被指派为F,P在大项中以P形式出现;如变元P被指 派为T,P在大项中以P形式出现(确保该大项为F).
利用真值表求主合取范式

利用真值表求主合取范式
1、把变量的各种可能取值与想对应的函数值,用表格的形式一一列举出来,这种表格就叫做真值表。
2、设一个变量均有0、1两种可能取值,n个变量共有2n种可能,将它们按顺序(一般按二进制数递增规律)排列起来,同时在相应位置上写上逻辑函数的值,便可得到该逻辑函数的真值表。
3、例如:逻辑函数的Y=AB+BC+CA的真值表如下:真值表以表格的形式表示逻辑函数,其优点是直观明了。
4、输入变量取值一旦确定,即可以从表中查出相应的函数值。
5、所以,在许多数字集成电路手册中,常常以不同形式的真值表,给出器件的逻辑功能。
6、另外,在把一个实际逻辑问题,抽象成为数学表达形式时,使用真值表是最方便的。
7、所以,在数字电路逻辑设计过程中,第一步就是要列出真值表;在分析数字电路逻辑功能时,最后也要列出真值表。
8、但是,真值表也有一些缺点:首先,难以对其使用逻辑代数的公式和定理进行运算和变换;其次,当变量比较多时,列真值表会十分繁琐。
析取范式与合取范式ppt

000
1
001
1
010
1
011
1
100
1
101
1
110
0
111
1
0
1
1
1
0
1
1
1
1
1
1
1
0
0
1
1
p(qr)与(pq)r等值, 但与(pq)r不等值
5
基本等值式
双重否定律 AA
幂等律
AAA, AAA
交换律
ABBA, ABBA
结合律
(AB)CA(BC)
(AB)CA(BC)
分配律
A(BC)(AB)(AC)
24
主析取范式与主合取范式
主析取范式:由极小项构成得析取范式 主合取范式:由极大项构成得合取范式
例如,n=3, 命题变项为p, q, r时, (pqr)(pqr) m1m3 就是主析取范式 (pqr)(pqr) M1M5 就是主合取范式
定理2、7 任何命题公式都存在着与之等值得主析取范式与 主合取范式, 并且就是惟一得、
同一律, 排中律
(pqr)(pqr)(pqr)(pqr)
m0 m2 m4 m6
分配律
得 (pq)r m0 m2 m4 m5 m6
可记作
(0,2,4,5,6)
28
实例(续)
(2) (pq)r (pr)(qr)
pr p0r
同一律
p(qq)r
矛盾律
(pqr)(pqr) 分配律
M1M3 qr (pp)qr
AB (AB)(BA) AB AB AB (AB) (AB) AB (AB) AB (A)B AB
16
利用真值表法求取主析取范式以及主合取范式的实现

#include <iostream>#include <cmath>#include <cassert>#include <cctype>using namespace std;char str[100]; //输入的命题公式int tv[20] = {0}; //真值指派的数组int length; //命题公式长度char expression[100]; //将命题公式中的命题变元变为真值后的数组int icp(const char c) //联结词的栈外优先级{int result = -1;switch(c){case '#': result = 0; break;case '(': result = 10; break;case '!': result = 9; break;case '&': result = 6; break;case '|': result = 4; break;case '>': result = 2; break;case ')': result = 1;}return result;}int isp(const char c) //联结词的栈内优先级{int result = -1;switch(c){case '#': result = 0; break;case '(': result = 1; break;case '!': result = 8; break;case '&': result = 7; break;case '|': result = 5; break;case '>': result = 3; break;case ')': result = 10;}return result;}void Plus(int a[],int q) //二进制加法指派真值{a[q]=a[q]+1;for (int i = q; a[i] == 2; i--){a[i]=0;a[i-1]=a[i-1]+1;}}template<class T>class Stack{public:virtual bool IsEmpty() const = 0;virtual bool IsFull() const = 0;virtual bool Top(T& x) const = 0;virtual bool Push(T x) = 0;virtual bool Pop() = 0;virtual void Clear() = 0;};template<class T>class SeqStack: public Stack<T> //顺序栈类{public:SeqStack(int mSize = 30);~SeqStack() { delete []s; }bool IsEmpty() const { return top == -1; }bool IsFull() const { return top == maxTop; } bool Top(T& x) const;bool Push(T x);bool Pop();void Clear() { top = -1; }private:int top;int maxTop;T* s;};template<class T>SeqStack<T>::SeqStack(int mSize){maxTop = mSize - 1;s = new T[mSize];top = -1;}template<class T>bool SeqStack<T>::Top(T& x) const{if (IsEmpty()){cout << "Empty" << endl;return false;}x = s[top];return true;}template<class T>bool SeqStack<T>::Push(T x){if (IsFull()){cout << "Overflow" << endl;return false;}s[++top]=x;return true;}template<class T>bool SeqStack<T>::Pop(){if(IsEmpty()){cout << "Underflow" << endl;}top--;return true;}class Calculator{public:Calculator(int maxSize):s(maxSize){}void Change();int Run();void Solve();void Clear() { s.Clear(); }private:SeqStack<bool> s; //运算栈void PushOperand(bool);bool GetOperands(bool &, bool &);void DoOperator(char);};void Calculator::PushOperand(bool op){s.Push(op);}bool Calculator::GetOperands(bool & op1, bool & op2) //获取栈顶两个元素{if (!s.Top(op1)){cerr << "Missing operand!" << endl;return false;}s.Pop();if (!s.Top(op2)){cerr << "Missing operand!" << endl;return false;}s.Pop();return true;}void Calculator::DoOperator(char oper) //联结词运算{bool left, right;bool result = GetOperands(left, right);if (result)switch(oper){case '!': s.Push(!left && right); break; //not运算case '&': s.Push(left && right); break; //and运算case '|': s.Push(left || right); break; //or运算case '>': s.Push(!right || left); break; //条件运算}elseClear();}void Calculator::Change() //将输入的字符串转化为可计算的表达式{int k = 0, t = 0;int flag = 1; //标记,防止相同的命题变元赋入不同的值int count = 0;for (int i = 0; i < pow(2,count); i++){k=1;for (int m = 0; m < length; m++){if (isalpha(str[m])) //将原来的命题变元修改为真值{if (flag == 1){if(tv[k] == 0)expression[m] = '0';elseexpression[m] = '1';k++;}elseexpression[m] = '0';flag = 1;for (t = m; t >= 0; t--)if ((str[m+1] == str[t]) && isalpha(str[m+1]) && isalpha(str[t]))flag = 0;}else{expression[m] = str[m]; //逻辑联结词不变for (t = m; t >= 0; t--)if ((str[m+1] == str[t]) && isalpha(str[m+1]) && isalpha(str[t]))flag = 0;}}for (int t = 0; t < length; t++)for (int j = t; j < length; j++)if (str[t] == str[j])expression[j] = expression[t]; //相同的命题变元复制赋值}}int Calculator::Run(){SeqStack<char> s1; //联结词栈char ch, y;char p[100];int i = 0;s1.Push('#');for (int temp=0; temp < length ; temp++){ch = expression[temp];if (isdigit(ch)){p[i++] = ch;}else if(ch == ')')for(s1.Top(y), s1.Pop(); y != '('; s1.Top(y), s1.Pop())p[i++] = y;else{if(ch == '!') p[i++] = '1'; //非运算,在!前加1,将!视作双目操作符for(s1.Top(y), s1.Pop(); icp(ch) <= isp(y); s1.Top(y), s1.Pop())p[i++] = y;s1.Push(y);s1.Push(ch);}}while(!s1.IsEmpty()){s1.Top(y);s1.Pop();if(y != '#')p[i++] = y;}p[i++] = '#';/* ------↑中缀表达式转化为后缀表达式-----------↓计算后缀表达式结果------------- */bool newop;for (i = 0; p[i] !='#'; i++){switch(p[i]){case '!':case '&':case '|':case '>': DoOperator(p[i]); break;default:cin.putback(p[i]);cin >> newop;PushOperand(newop);break;}}if (s.Top(newop)){cout << (int)newop << endl;return (int)newop; //输出并返回最终结果}}void Calculator::Solve(){cout << "***************************************" << endl;//标语cout << "** 欢迎进入逻辑运算软件**" << endl;cout << "** (可运算真值表,主范式,支持括号) **" << endl;cout << "** **" << endl;cout << "** 用!表示not 用&表示and **" << endl;cout << "** 用|表示or 用>表示蕴含**" << endl;cout << "** **" << endl;cout << "***************************************" << endl;cout << "请输入合法的命题公式(以#结尾): ";int flag = 1; //标记,防止重复添加命题变元int count = 0; //命题变元的数目cin >> str; //输入命题公式length = strlen(str) - 1;char index[10]; //命题变元数组for (int i = 0; i < length; i++) //逐次添加命题变元{if (isalpha(str[i]) && (flag == 1))index[count++] = str[i];flag=1;for (int k = 0; k < count; k++)if (index[k] == str[i+1])flag=0;}if (!count){cout << "无命题变元,重新输入!" << endl;system("pause");system("cls");Solve();}cout << "真值表:" << endl;for (int w = 0; w < count; w++)cout << index[w] << ' ';for (w = 0; w < length; w++)cout << str[w];cout << endl;int *truth = new int[pow(2,count)];int xx = 0, dx = 0; //小项,大项for (int r = 0; r < pow(2,count); r++) //输出真值表{for (int j = 1; j <= count; j++)cout << tv[j] << ' ';Change();truth[r] = Run();if (truth[r]) //记录小项和大项的个数xx++;elsedx++;Plus(tv,count);}if(xx > 1) //输出主析取范式{int flag_xx = 0;cout << "主析取范式为";for(r = 0; r < pow(2,count); r++){if (truth[r]){if (flag_xx) cout << " \\/ ";cout << "m" << r;flag_xx = 1;}}cout << endl;}elsecout << "没有主析取范式!" << endl;if(dx > 1) //输出主合取范式{int flag_dx = 0;cout << "主合取范式为";for(r = 0; r < pow(2,count); r++){if (!truth[r]){if (flag_dx) cout << " /\\ ";cout << "M" << r;flag_dx = 1;}}cout << endl;}elsecout << "没有主合取范式!" << endl;cout << "是否继续运算?(Y/N)" << endl;char goon;cin >> goon;if (goon=='y' || goon=='Y'){system("cls");Solve(); //递归调用Solve,重新计算}elseexit(0);}int main(){Calculator Cal(100);Cal.Solve();return 0;}。
离散数学总结

总结下就是任意可以改成存在,存在不能变成 任意所以先做存在。 任意(推出ห้องสมุดไป่ตู้则先用德摩根律把推出给换了, 在把量词放进去! 有限集合中元素的个数称为集合的基数 (cardinality). 集合A的基数表示为|A|(或card(A)=n). n card(P(A)=2 )幂集 设A, B为两个集合,A=B当且仅当AB且B A. 即A=B(AB) (B A)
个人. 则命题符号化为:
(x)(y)(F(x) F(y) H(x, y) L(x, y))
(8) 每个自然数都有后继数.
解: 引入特性谓词 F(x) : x是自然数.并设 H(x, y):y是x的后继数. 则命题符号化为: (x)(F(x) (y) (F(y) H(x, y))
证: 任取x,则
xA∩ (B∪C) xA xB∪C xA (xB x C) (xA xB) (xA xC) x A∩B x A∩C
x (A∩B)∪(A∩C)
推广
三、集合中元素的计数
|A∪B∪C |A||B|| |A∩B ||A∩C||B∩C| |A∩B∩C | C| |
(x)A(x) (x)B(x)
量词转化律
E20
三、谓词演算的等价式与蕴含式
(三) 谓词演算中常见的蕴含式: (1)(x)A(x)(x)B(x) (x)(A(x)B(x)) (2)(x)(A(x)B(x)) (x)A(x)(x)B(x) (1), (2)两式反过来均不成立. 反例 设个体域为自然数集合, A(x): x为奇数. B(x): x为偶数.则 (1)(x)(A(x)B(x))为真, 而(x)A(x)为假, (x)B(x)为假, 故(x)A(x)(x)B(x)为假, 所以(1)式反过来不成立; (2)(x)A(x)为真,(x)B(x)为真, 故(x)A(x)(x)B(x)为真, 但(x)(A(x)B(x))为假, 所以(2)式反过来也不成立.
主析取范式

主析取范式
求解主析取范式、主合取范式方法
1、真值表法
①在表中列出变元值的全部可能
②查表判断命题
命题结果真,变元值对应主析取范式
命题结果假,变元值对应主合取范式
2、等值演算法
①命题化简
蕴涵等值式:A→B↔¬A∨B(作用:去→)
矛盾律:A↔∧¬A(作用:补齐变元)
分配律:(A∧B)∨C↔(A∨C)∧(B∨C)、(A∨B)∧C↔(A∧C)∨(B∧C)
②判断命题
命题结果真,变元值对应主析取范式
命题结果假,变元值对应主合取范式。
例题
求公式(p→q)∧(q→r)的主析取范式和主合取范式、成真赋值。
解:
1、真值表法
查表可得
成真赋值:000、001、011、111
主析取范式:∑(0,1,3,7)
成假赋值:010、100、101、110
主合取范式:∏(2,4,5,6)
2、等值演算法
(p→q)∧(q→r)
=(¬p∨q)∧(¬q∨r)-----------------------------(蕴涵等值式:
化简→)
=((¬p∨q)∨(¬r∧r)))∧((¬q∨r)∨(¬p∧p))----(矛盾律:补齐变元)
=(¬p∨q∨¬r)∧(¬p∨q∨r)∧(¬p∨¬q∨r)∧(p∨¬q∨r)—(分配律:化简)
↔M5M4M6M2。
主析取范式的求法及其应用

主析取范式的求法及其应用杨菲〔天津市河西区职工大学,天津市300203〕摘要:本文综述了求主析取范式的三种主要方法,即推演法、真值表法、构造树法,并从经典例题入手分析了三种方法的应用技巧。
关键词:主析取范式 推演法 真值表法 构造树法命题公式的主析取范式在数理逻辑学中具有非常重要的意义,其求解的主要目的在于使命题公式标准化,从而有利于判断两个命题公式是否等值,并且还可以判断一个公式是重言式〔永真式〕还是矛盾式〔永假式〕。
鉴于主析取范式求解的重要意义,本文综述了求主析取范式的方法及各种方法的应用技巧。
1 相关概念 1.1 极小项为了说明主析取范式的概念,首先介绍一下极小项的相关理论内容。
定义:n 个命题变元组成的合取式,该式中要包含所有这n 个变元或它的否认,那么称这个合取式为关于这n 个命题变元的极小项。
性质:〔1〕对于n 个原子n P P P ,......,,21而言,其所有的极小项共有n 2个。
(2) 每个小项当其真值指派与编码一样时,其真值为T ,在其余12-n种指派情况下均为F 。
主析取范式定义:对于一个给定的命题公式,假设有一个由小项的析取组成的命题公式与其等价,那么称该等价式为给定命题公式的主析取范式。
定理1. 对于任何一个命题公式,其主析取范式存在且唯一。
〔证明略〕 2 主析取范式的求法解析 2.1 推演法对于给定命题公式的主析取范式可由推演法求出,其主要步骤归纳为: (1) 首先将公式化为析取范式。
(2) 除去析取范式中永假的析取项,并将析取式中重复出现的合取项和一样变元合并。
(3) 对于不是小项的合取式,补入没有出现的命题变元,即通过合取添加)(P P ⌝∨式,然后应用分配律展开公式。
例1. 求)()(R Q Q P ∧∨∧的主析取范式解 111110011011111110111)()()()())()(())()(()()(m m m m m m m P R Q P R Q R Q P R Q P P P R Q R R Q P R Q Q P ∨∨⇔∨∨∨⇔⌝∧∧∨∧∧∨⌝∧∧∨∧∧⇔⌝∨∧∧∨⌝∨∧∧⇔∧∨∧特点:初步将命题公式化为一般析取范式后,各合式公式中缺少一到两个命题变元即该形式已经接近主析取范式时,可以用该法较快得解。
利用真值表法求取主析取范式以及主合取范式的实现-副本.doc

1#include stdio.h #include stdlib.h #include string.h #include math.h #define N 50void pd(int b[N],int f);int H1 (char T1[N], char T2[N], int T3[N], int y); int H2 (char T1[N], char T2[N], int T3[N], int y); int main() {int i1,i2,d=1,T3[N],kh=0,jg,j=0,y; int w=0,hequ[N],h=0,x=0,xiqu[N]; charT1[N],T2[N],T10[N],s; hequ[0]=-1; xiqu[0]=-1;printf(#########################################\n); printf(##用!表示否定##\n); printf(## 用&表示合取##\n); printf(## 用|表示析取##\n); printf(##用^表示条件##\n); printf(## 用~表示双条件##\n); printf(#########################################\n\n);printf(请输入一个合法的命题公式:\n); gets(T1);strcpy(T10,T1);for(i1=0;i1<strlen(T1);i1++) {if(T1[i1]==')' || T1[i1]=='(') kh++;if(T1[i1]>='a' && T1[i1]<='z' || T1[i1]>='A' && T1[i1]<='Z') {for(i2=0;i2<j;i2++) if(T2[i2]==T1[i1]) d=0;if(d==1) {T2[j]=T1[i1]; j++; }d=1; } }2printf(\n输出真值表如下:\n \n); for(i1=0;i1<y;i1++)printf( %c ,T2[i1]); printf( ); puts(T1); printf(\n);for(i1=0;i1<j;i1++) T3[i1]=0;for(i2=0;i2<j;i2++)printf( %d ,T3[i2]); jg=H1(T1,T2,T3,y); if(jg==0)hequ[h++]=w; elsexiqu[x++]=w;printf( %d\n,jg); strcpy(T1,T10);for(i1=0;i1<(int)pow(2,j)-1;i1++) {++w;pd(T3,j-1);jg=H1(T1,T2,T3,y); if(jg==0)hequ[h++]=w; elsexiqu[x++]=w; strcpy(T1,T10); for(i2=0;i2<j;i2++)printf( %d ,T3[i2]); printf( %d\n,jg); }if(hequ[0]==-1)printf(\n该命题公式不存在主合取范式。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include <iostream>#include <cmath>#include <cassert>#include <cctype>using namespace std;char str[100]; //输入的命题公式int tv[20] = {0}; //真值指派的数组int length; //命题公式长度char expression[100]; //将命题公式中的命题变元变为真值后的数组int icp(const char c) //联结词的栈外优先级{int result = -1;switch(c){case '#': result = 0; break;case '(': result = 10; break;case '!': result = 9; break;case '&': result = 6; break;case '|': result = 4; break;case '>': result = 2; break;case ')': result = 1;}return result;}int isp(const char c) //联结词的栈内优先级{int result = -1;switch(c){case '#': result = 0; break;case '(': result = 1; break;case '!': result = 8; break;case '&': result = 7; break;case '|': result = 5; break;case '>': result = 3; break;case ')': result = 10;}return result;}void Plus(int a[],int q) //二进制加法指派真值{a[q]=a[q]+1;for (int i = q; a[i] == 2; i--){a[i]=0;a[i-1]=a[i-1]+1;}}template<class T>class Stack{public:virtual bool IsEmpty() const = 0;virtual bool IsFull() const = 0;virtual bool Top(T& x) const = 0;virtual bool Push(T x) = 0;virtual bool Pop() = 0;virtual void Clear() = 0;};template<class T>class SeqStack: public Stack<T> //顺序栈类{public:SeqStack(int mSize = 30);~SeqStack() { delete []s; }bool IsEmpty() const { return top == -1; }bool IsFull() const { return top == maxTop; } bool Top(T& x) const;bool Push(T x);bool Pop();void Clear() { top = -1; }private:int top;int maxTop;T* s;};template<class T>SeqStack<T>::SeqStack(int mSize){maxTop = mSize - 1;s = new T[mSize];top = -1;}template<class T>bool SeqStack<T>::Top(T& x) const{if (IsEmpty()){cout << "Empty" << endl;return false;}x = s[top];return true;}template<class T>bool SeqStack<T>::Push(T x){if (IsFull()){cout << "Overflow" << endl;return false;}s[++top]=x;return true;}template<class T>bool SeqStack<T>::Pop(){if(IsEmpty()){cout << "Underflow" << endl;}top--;return true;}class Calculator{public:Calculator(int maxSize):s(maxSize){}void Change();int Run();void Solve();void Clear() { s.Clear(); }private:SeqStack<bool> s; //运算栈void PushOperand(bool);bool GetOperands(bool &, bool &);void DoOperator(char);};void Calculator::PushOperand(bool op){s.Push(op);}bool Calculator::GetOperands(bool & op1, bool & op2) //获取栈顶两个元素{if (!s.Top(op1)){cerr << "Missing operand!" << endl;return false;}s.Pop();if (!s.Top(op2)){cerr << "Missing operand!" << endl;return false;}s.Pop();return true;}void Calculator::DoOperator(char oper) //联结词运算{bool left, right;bool result = GetOperands(left, right);if (result)switch(oper){case '!': s.Push(!left && right); break; //not运算case '&': s.Push(left && right); break; //and运算case '|': s.Push(left || right); break; //or运算case '>': s.Push(!right || left); break; //条件运算}elseClear();}void Calculator::Change() //将输入的字符串转化为可计算的表达式{int k = 0, t = 0;int flag = 1; //标记,防止相同的命题变元赋入不同的值int count = 0;for (int i = 0; i < pow(2,count); i++){k=1;for (int m = 0; m < length; m++){if (isalpha(str[m])) //将原来的命题变元修改为真值{if (flag == 1){if(tv[k] == 0)expression[m] = '0';elseexpression[m] = '1';k++;}elseexpression[m] = '0';flag = 1;for (t = m; t >= 0; t--)if ((str[m+1] == str[t]) && isalpha(str[m+1]) && isalpha(str[t]))flag = 0;}else{expression[m] = str[m]; //逻辑联结词不变for (t = m; t >= 0; t--)if ((str[m+1] == str[t]) && isalpha(str[m+1]) && isalpha(str[t]))flag = 0;}}for (int t = 0; t < length; t++)for (int j = t; j < length; j++)if (str[t] == str[j])expression[j] = expression[t]; //相同的命题变元复制赋值}}int Calculator::Run(){SeqStack<char> s1; //联结词栈char ch, y;char p[100];int i = 0;s1.Push('#');for (int temp=0; temp < length ; temp++){ch = expression[temp];if (isdigit(ch)){p[i++] = ch;}else if(ch == ')')for(s1.Top(y), s1.Pop(); y != '('; s1.Top(y), s1.Pop())p[i++] = y;else{if(ch == '!') p[i++] = '1'; //非运算,在!前加1,将!视作双目操作符for(s1.Top(y), s1.Pop(); icp(ch) <= isp(y); s1.Top(y), s1.Pop())p[i++] = y;s1.Push(y);s1.Push(ch);}}while(!s1.IsEmpty()){s1.Top(y);s1.Pop();if(y != '#')p[i++] = y;}p[i++] = '#';/* ------↑中缀表达式转化为后缀表达式-----------↓计算后缀表达式结果------------- */bool newop;for (i = 0; p[i] !='#'; i++){switch(p[i]){case '!':case '&':case '|':case '>': DoOperator(p[i]); break;default:cin.putback(p[i]);cin >> newop;PushOperand(newop);break;}}if (s.Top(newop)){cout << (int)newop << endl;return (int)newop; //输出并返回最终结果}}void Calculator::Solve(){cout << "***************************************" << endl;//标语cout << "** 欢迎进入逻辑运算软件**" << endl;cout << "** (可运算真值表,主范式,支持括号) **" << endl;cout << "** **" << endl;cout << "** 用!表示not 用&表示and **" << endl;cout << "** 用|表示or 用>表示蕴含**" << endl;cout << "** **" << endl;cout << "***************************************" << endl;cout << "请输入合法的命题公式(以#结尾): ";int flag = 1; //标记,防止重复添加命题变元int count = 0; //命题变元的数目cin >> str; //输入命题公式length = strlen(str) - 1;char index[10]; //命题变元数组for (int i = 0; i < length; i++) //逐次添加命题变元{if (isalpha(str[i]) && (flag == 1))index[count++] = str[i];flag=1;for (int k = 0; k < count; k++)if (index[k] == str[i+1])flag=0;}if (!count){cout << "无命题变元,重新输入!" << endl;system("pause");system("cls");Solve();}cout << "真值表:" << endl;for (int w = 0; w < count; w++)cout << index[w] << ' ';for (w = 0; w < length; w++)cout << str[w];cout << endl;int *truth = new int[pow(2,count)];int xx = 0, dx = 0; //小项,大项for (int r = 0; r < pow(2,count); r++) //输出真值表{for (int j = 1; j <= count; j++)cout << tv[j] << ' ';Change();truth[r] = Run();if (truth[r]) //记录小项和大项的个数xx++;elsedx++;Plus(tv,count);}if(xx > 1) //输出主析取范式{int flag_xx = 0;cout << "主析取范式为";for(r = 0; r < pow(2,count); r++){if (truth[r]){if (flag_xx) cout << " \\/ ";cout << "m" << r;flag_xx = 1;}}cout << endl;}elsecout << "没有主析取范式!" << endl;if(dx > 1) //输出主合取范式{int flag_dx = 0;cout << "主合取范式为";for(r = 0; r < pow(2,count); r++){if (!truth[r]){if (flag_dx) cout << " /\\ ";cout << "M" << r;flag_dx = 1;}}cout << endl;}elsecout << "没有主合取范式!" << endl;cout << "是否继续运算?(Y/N)" << endl;char goon;cin >> goon;if (goon=='y' || goon=='Y'){system("cls");Solve(); //递归调用Solve,重新计算}elseexit(0);}int main(){Calculator Cal(100);Cal.Solve();return 0;}。