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

#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;
}


你可能感兴趣的:(离散数学,实验)