利用真值表法求取主析取範式以及主合取範式的實現

本程序可以實現任意輸入表達式,變元數最多可爲3個,即可輸出主析取式和主合取式。

規定符號:

! 否定   | 析取    & 合取

-> 條件     <->雙條件


#include<iostream>

#include<string.h>

usingnamespace std;

 

stringorg;       //原式

stringpcnf;    //主合取範式

stringpdnf;    //主析取範式

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保存。

intchoose;

 

classSeqStack

{

public:

    SeqStack(int mSize);

   ~SeqStack();

    bool Push(char x); 

    bool Pop();

    char Top();

private:

    int top;

    char *st;

    int maxtop;

};

 

SeqStack::SeqStack(intmSize)

{

    maxtop = mSize - 1;

    st = new char[mSize];

    top = -1;

}

 

SeqStack::~SeqStack()

{

    delete[]st;

}

 

boolSeqStack::Push(char x)

{

    if(top == maxtop)

        return false;

    st[++top] = x;

    return true;

}

 

boolSeqStack::Pop()    

{

    if(top == -1)

        return false;

    top--;

    return true;

}

 

charSeqStack::Top()        

{

    return st[top];

}

 

voidAnd();     //合取

voidOr();      //析取

voidNot();     //否定

voidIf();      //條件

voidIif(); //雙條件

boolCanIn(char out);       //判斷能否進棧

voidInfixToPostfix();              //求後綴表達式

voidCalculate();           //計算公式的值

void Print();               //輸出真值表和範式

 

SeqStackstack(200);       

 

intmain()

{

    cout << "! 否定" << endl << "| 析取" << endl <<"& 合取" << endl << "-> 條件" << endl << "<-> 雙條件" << endl << endl;

    cout << "輸入變元數量 (2 <= n <= 3)" << 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;

    }

    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;

    InfixToPostfix();  

    Print();  

    return 0;

}

 

voidAnd()      //合取

{

    res = a * b;

    stack.Push(res);

}

 

voidOr()       //析取

{

    res = a + b;

    res = res > 1 ? 1 : res;

    stack.Push(res);

}

 

voidNot()      //否定

{

    a = stack.Top();

    stack.Pop();

    res = a == 1 ? 0 : 1;

    stack.Push(res);

}

 

voidIf()       //條件,b->a

{

    res = (b == 1 && a == 0) ? 0 : 1;

    stack.Push(res);

}

 

voidIif()  //雙條件

{

    res = (b == a) ? 1 : 0;

    stack.Push(res);

}

 

boolCanIn(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;

}

 

voidInfixToPostfix()   //轉換爲後綴表達式

{

    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;                     

}

 

voidCalculate()             

{

   

    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;

            }

        }

    }

}

 

voidPrint()                 

{

    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;

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章