南邮离散数学实验1 (栈版) 根据表达式求真值表和主范式

来源:互联网 发布:win10 windows to go 编辑:程序博客网 时间:2024/05/18 01:53
#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;}


0 0