#include <iostream>
#include <string>
using namespace std;
string org; //原式
string pcnf; //主合取范式
string pdnf; //主析取范式
int p, q, r, s, t, u; //变量 P、Q、R、S、T、U的值
int a, b, res; //a、b保存出栈的两个元素的值,res保存计算结果
int v = 0; //保存进栈的值,0或者1 。计算的时候是先识别变量,然后进栈的是变量的值,用v保存。
int choose;
class SeqStack
{
public:
SeqStack(int mSize);
~SeqStack();
bool Push(char x);
bool Pop();
char Top();
private:
int top;
char *st;
int maxtop;
};
SeqStack::SeqStack(int mSize)
{
maxtop = mSize - 1;
st = new char[mSize];
top = -1;
}
SeqStack::~SeqStack()
{
delete[]st;
}
bool SeqStack::Push(char x)
{
if(top == maxtop)
return false;
st[++top] = x;
return true;
}
bool SeqStack::Pop()
{
if(top == -1)
return false;
top--;
return true;
}
char SeqStack::Top()
{
return st[top];
}
void And(); //合取
void Or(); //析取
void Not(); //否定
void If(); //条件
void Iif(); //双条件
bool CanIn(char out); //判断能否进栈
void Suffix(); //求后缀表达式
void Calculate(); //计算公式的值
void Print(); //输出真值表和范式
SeqStack stack(200);
int main()
{
cout << "! 否定" << endl << "| 析取" << endl <<"& 合取" << endl << "-> 条件" << endl << "<-> 双条件" << endl << endl;
cout << "输入变元数量 (2 <= n <= 6)" << endl << endl;
cin >> choose;
switch(choose)
{
case 2:cout << endl << "变元请用P、Q表示" << endl << endl; break;
case 3:cout << endl << "变元请用P、Q、R表示" << endl << endl; break;
case 4:cout << endl << "变元请用P、Q、R、S表示" << endl << endl; break;
case 5:cout << endl << "变元请用P、Q、R、S、T表示" << endl << endl; break;
case 6:cout << endl << "变元请用P、Q、R、S、T、U表示" << endl << endl; break;
}
char str[100];
char ch[100];
cin >> str;
int cnt = 0;
for(int i = 0; i < strlen(str);)
{
if(str[i] == '-')
{
ch[cnt++] = '>';
i += 2;
}
else if(str[i] == '<')
{
ch[cnt++] = '~';
i += 3;
}
else
{
ch[cnt++] = str[i];
i++;
}
}
ch[cnt++] = '\0';
org = ch;
Suffix();
Print();
return 0;
}
void And() //合取
{
res = a * b;
stack.Push(res);
}
void Or() //析取
{
res = a + b;
res = res > 1 ? 1 : res;
stack.Push(res);
}
void Not() //否定
{
a = stack.Top();
stack.Pop();
res = a == 1 ? 0 : 1;
stack.Push(res);
}
void If() //条件,b->a
{
res = (b == 1 && a == 0) ? 0 : 1;
stack.Push(res);
}
void Iif() //双条件
{
res = (b == a) ? 1 : 0;
stack.Push(res);
}
bool CanIn(char out) //先计算优先级,然后判断能否进栈
{
char in = stack.Top();
int i, o; //分别表示栈内外运算符的优先级
switch(in)
{
case '#':i = 0; break;
case '(':i = 1; break;
case '~':i = 3; break;
case '>':i = 5; break;
case '|':i = 7; break;
case '&':i = 9; break;
case '!':i = 11; break;
case ')':i = 12; break;
}
switch(out)
{
case '#':o = 0; break;
case '(':o = 12; break;
case '~':o = 2; break;
case '>':o = 4; break;
case '|':o = 6; break;
case '&':o = 8; break;
case '!':o = 10; break;
case ')':o = 1; break;
}
if(i < o) //如果栈外的优先级比栈内的高,就可以进栈,因为离栈顶越近,就越先出栈
return true;
else
return false;
}
void Suffix() //转换为后缀表达式
{
string tmp = ""; //保存后缀表达式
stack.Push('#'); //栈底
for(int i = 0; (unsigned)i < org.length(); i++)
{
if(org[i] == 'P' || org[i] == 'Q' || org[i] == 'R' || org[i] == 'S' || org[i] == 'T' || org[i] == 'U') //如果是P、Q、R 就保存到字符串tmp中
{
tmp = tmp + org[i];
continue;
}
if(CanIn(org[i]))
stack.Push(org[i]);
else if(org[i] == ')')
{
while(stack.Top() != '(')
{
tmp = tmp + stack.Top();
stack.Pop();
}
stack.Pop();
}
else
{
do
{
tmp = tmp + stack.Top();
stack.Pop();
} while(!CanIn(org[i]));
stack.Push(org[i]);
}
}
while(stack.Top() != '#')
{
tmp = tmp + stack.Top();
stack.Pop();
}
stack.Pop(); // '#' 出栈
org = tmp;
}
void Calculate()
{
if(choose == 6)
{
for(int i = 0; (unsigned)i < org.length(); i++)
{
if(org[i] == 'P' || org[i] == 'Q' || org[i] == 'R' || org[i] == 'S' || org[i] == 'T' || org[i] == 'U')
{
v = org[i] == 'P' ? p : org[i] == 'Q' ? q : org[i] == 'S' ? r : org[i] == 'T' ? s : org[i] == 'U' ? t : u;
stack.Push(v);
continue;
}
if(org[i] != '!')
{
a = stack.Top();
stack.Pop();
b = stack.Top();
stack.Pop();
}
switch(org[i])
{
case '~':Iif(); break;
case '>':If(); break;
case '|':Or(); break;
case '&':And(); break;
case '!':Not(); break;
}
}
}
if(choose == 5)
{
for(int i = 0; (unsigned)i < org.length(); i++)
{
if(org[i] == 'P' || org[i] == 'Q' || org[i] == 'R' || org[i] == 'S' || org[i] == 'T')
{
v = org[i] == 'P' ? p : org[i] == 'Q' ? q : org[i] == 'S' ? r : org[i] == 'T' ? s : t;
stack.Push(v);
continue;
}
if(org[i] != '!')
{
a = stack.Top();
stack.Pop();
b = stack.Top();
stack.Pop();
}
switch(org[i])
{
case '~':Iif(); break;
case '>':If(); break;
case '|':Or(); break;
case '&':And(); break;
case '!':Not(); break;
}
}
}
if(choose == 4)
{
for(int i = 0; (unsigned)i < org.length(); i++)
{
if(org[i] == 'P' || org[i] == 'Q' || org[i] == 'R' || org[i] == 'S')
{
v = org[i] == 'P' ? p : org[i] == 'Q' ? q : org[i] == 'S' ? r : s;
stack.Push(v);
continue;
}
if(org[i] != '!')
{
a = stack.Top();
stack.Pop();
b = stack.Top();
stack.Pop();
}
switch(org[i])
{
case '~':Iif(); break;
case '>':If(); break;
case '|':Or(); break;
case '&':And(); break;
case '!':Not(); break;
}
}
}
if(choose == 3)
{
for(int i = 0; (unsigned)i < org.length(); i++)
{
if(org[i] == 'P' || org[i] == 'Q' || org[i] == 'R')
{
v = org[i] == 'P' ? p : org[i] == 'Q' ? q : r;
stack.Push(v);
continue;
}
if(org[i] != '!')
{
a = stack.Top();
stack.Pop();
b = stack.Top();
stack.Pop();
}
switch(org[i])
{
case '~':Iif(); break;
case '>':If(); break;
case '|':Or(); break;
case '&':And(); break;
case '!':Not(); break;
}
}
}
if(choose == 2)
{
for(int i = 0; (unsigned)i < org.length(); i++)
{
if(org[i] == 'P' || org[i] == 'Q')
{
v = org[i] == 'P' ? p : q;
stack.Push(v);
continue;
}
if(org[i] != '!')
{
a = stack.Top();
stack.Pop();
b = stack.Top();
stack.Pop();
}
switch(org[i])
{
case '~':Iif(); break;
case '>':If(); break;
case '|':Or(); break;
case '&':And(); break;
case '!':Not(); break;
}
}
}
}
void Print()
{
if(choose == 6)
{
cout << "P\t" << "Q\t" << "R\t" << "S\t" << "T\t" << "U\t" << "Z" << endl;
for(p = 1; p >= 0; p--)
{
for(q = 1; q >= 0; q--)
{
for(r = 1; r >= 0; r--)
{
for(s = 1; s >= 0; s--)
{
for(t = 1; t >= 0; t--)
{
for(u = 1; u >= 0; u--)
{
Calculate();
if(res == 1)
pdnf = pdnf + "(" + (p == 1 ? "P" : "!P") + "&" + (q == 1 ? "Q" : "!Q") + "&" + (r == 1 ? "R" : "!R")
+ "&" + (s == 1 ? "S" : "!S") + "&" + (t == 1 ? "T" : "!T") + "&" + (u == 1 ? "U" : "!U") + ")" + " | ";
else
pcnf = pcnf + "(" + (p == 0 ? "P" : "!P") + "|" + (q == 0 ? "Q" : "!Q") + "|" + (r == 0 ? "R" : "!R")
+ "|" + (s == 0 ? "S" : "!S") + "|" + (t == 0 ? "T" : "!T") + "|" + (u == 0 ? "U" : "!U") + ")" + " & ";
cout << p << "\t" << q << "\t" << r << "\t" << s << "\t" << t << "\t" << u << "\t" << res << endl;
}
}
}
}
}
}
}
if(choose == 5)
{
cout << "P\t" << "Q\t" << "R\t" << "S\t" << "T\t" << "Z" << endl;
for(p = 1; p >= 0; p--)
{
for(q = 1; q >= 0; q--)
{
for(r = 1; r >= 0; r--)
{
for(s = 1; s >= 0; s--)
{
for(t = 1; t >= 0; t--)
{
Calculate();
if(res == 1)
pdnf = pdnf + "(" + (p == 1 ? "P" : "!P") + "&" + (q == 1 ? "Q" : "!Q") + "&" +
(r == 1 ? "R" : "!R") + "&" + (s == 1 ? "S" : "!S") + "&" + (t == 1 ? "T" : "!T") + ")" + " | ";
else
pcnf = pcnf + "(" + (p == 0 ? "P" : "!P") + "|" + (q == 0 ? "Q" : "!Q") + "|" +
(r == 0 ? "R" : "!R") + "|" + (s == 0 ? "S" : "!S") + "|" + (t == 0 ? "T" : "!T") + ")" + " & ";
cout << p << "\t" << q << "\t" << r << "\t" << s << "\t" << t << "\t" << res << endl;
}
}
}
}
}
}
if(choose == 4)
{
cout << "P\t" << "Q\t" << "R\t" << "S\t" << "Z" << endl;
for(p = 1; p >= 0; p--)
{
for(q = 1; q >= 0; q--)
{
for(r = 1; r >= 0; r--)
{
for(s = 1; s >= 0; s--)
{
Calculate();
if(res == 1)
pdnf = pdnf + "(" + (p == 1 ? "P" : "!P") + "&" + (q == 1 ? "Q" : "!Q") + "&" + (r == 1 ? "R" : "!R")
+ "&" + (s == 1 ? "S" : "!S") + ")" + " | ";
else
pcnf = pcnf + "(" + (p == 0 ? "P" : "!P") + "|" + (q == 0 ? "Q" : "!Q") + "|" + (r == 0 ? "R" : "!R")
+ "|" + (s == 0 ? "S" : "!S") + ")" + " & ";
cout << p << "\t" << q << "\t" << r << "\t" << s << "\t" << res << endl;
}
}
}
}
}
if(choose == 3)
{
cout << "P\t" << "Q\t" << "R\t" << "Z" << endl;
for(p = 1; p >= 0; p--)
{
for(q = 1; q >= 0; q--)
{
for(r = 1; r >= 0; r--)
{
Calculate();
if(res == 1)
pdnf = pdnf + "(" + (p == 1 ? "P" : "!P") + "&" + (q == 1 ? "Q" : "!Q") + "&"
+ (r == 1 ? "R" : "!R") + ")" + " | ";
else
pcnf = pcnf + "(" + (p == 0 ? "P" : "!P") + "|" + (q == 0 ? "Q" : "!Q") + "|"
+ (r == 0 ? "R" : "!R") + ")" + " & ";
cout << p << "\t" << q << "\t" << r << "\t" << res << endl;
}
}
}
}
if(choose == 2)
{
cout << "P\t" << "Q\t" << "Z" << endl;
for(p = 1; p >= 0; p--)
{
for(q = 1; q >= 0; q--)
{
Calculate();
if(res == 1)
pdnf = pdnf + "(" + (p == 1 ? "P" : "!P") + "&" + (q == 1 ? "Q" : "!Q") + ")" + " | ";
else
pcnf = pcnf + "(" + (p == 0 ? "P" : "!P") + "|" + (q == 0 ? "Q" : "!Q") + ")" + " & ";
cout << p << "\t" << q << "\t" << res << endl;
}
}
}
cout << pdnf.length() << endl;
cout << pcnf.length() << endl;
//考虑永真和永假的情况
if(pdnf.length() != 0)
pdnf.erase(pdnf.length() - 2);
if(pcnf.length() != 0)
pcnf.erase(pcnf.length() - 2);
cout << "主析取范式:" << pdnf << endl << endl;
cout << "主合取范式:" << pcnf << endl << endl;
}