2020.10.28小记

bytectf被打自闭了(安卓做nm,没学过)。。就会一个qiao。拿了个三血,该开始重新学习了,最近学校离散数学上课讲了代数结构,感觉比较重要,要记一笔,以及今天做了离散数学实验一
(化主析取感觉怪怪的。。。)
*是定义在集合a上的二元运算

交换律y*x==x*y
结合律(x*y)*z==(y*z)*x
* $为a上的两个二元运算
分配率x*(y$z)==(x*y)$(x*z)
吸收律 *$可交换 x*(y$x)==x
              x$(y*x)==x
等幂律 x*x==x

e*x==x e左幺元
x*e==x e右幺元
e*x==x*e==x e幺元
er==el==e 幺元唯一
q*x==q 左零元
x*q==q 右零元

第一次离散实验主要参照wxy大神…orz 中缀转后缀(主要是)
还有stl原来有这么多东西。。。记了

#include <iostream>
#include<cmath>
#include<set>
#include<vector>
#include<string>
#include<stack>

using namespace std;
bool c2b(char input)
{
    return input =='1';
}

char b2c(bool input)
{
    return input ? 1:0;
}

string b2s(bool input)
{
    return input? "1":"0";
}
void al_num(string& input, vector<string> &inputal)//来计算命题中的字母数量
{
    string canzhao ="!()&|=>";
    set<string>result;
    string tmp="";
    for(string::iterator c= input.begin(); c != input.end();c++)
    {
        if(canzhao.find(*c) == string::npos)//找到了数字
        {
            tmp += *c;
        }
        else//找到了符号
        {
            if(tmp.length() !=0)
            {
                result.insert(tmp);
                tmp = "";

            }
        }
        
    }
    if( tmp.length() !=0 )
    {
        result.insert(tmp);
        tmp = "";
    }
    for(set<string>:: iterator i = result.begin(); i != result.end(); ++i )
    {
        inputal.push_back(*i);
    }//得到哪些数字


}
void replaceal(string &expr,const string &al,const string &tf)
{
    string::size_type pos = 0;
    while((pos = expr.find(al,pos)) != string::npos)
    {
        expr.replace(pos,al.size(),tf);
        pos += tf.size();
    }
}
string i2s(string & expr)//中序转后序
{
    string output ="";
    stack<char> tmp;
    for(string::iterator c = expr.begin(); c != expr.end(); ++c)
    {
        switch(*c)
        {
        case '0':
        case '1':
            output +=*c;
            break;
        case '(':
            tmp.push(*c);
            break;
        case ')':
            while(!tmp.empty())
            {
                if(tmp.top() =='(')
                {
                    tmp.pop();
                    break;


                }
                output +=tmp.top();
                tmp.pop();
            }
        case '!':
            tmp.push(*c);
            break;
        case '&':
        case '|':
            while(!tmp.empty() && tmp.top()!='=' && tmp.top() !='>' && tmp.top() !='(')
            {
                output += tmp.top();
                tmp.pop();
                
            }
            tmp.push(*c);
            break;
        case '>':
        case '=':
            while(!tmp.empty() && tmp.top()!= '(')
            {
                output += tmp.top();
                tmp.pop();
            }
            tmp.push(*c);
            break;

            



        }

    }
    while(!tmp.empty())
    {
       output += tmp.top();
       tmp.pop();
    }
    return output;
}
bool cal(string &input)
{
    stack<bool>tmp;
    for(string::iterator c =input.begin(); c != input.end(); ++c )
    {
        if(*c=='0' || *c=='1')
        {
            tmp.push(c2b(*c));

        }
       
        else if(*c == '!')
        {
            bool x = tmp.top();
            tmp.pop();
            tmp.push(!x);

        }
        else
        {
            bool x = tmp.top();
            tmp.pop();
            bool y = tmp.top();
            tmp.pop();
            switch(*c)
            {
            case '&':
                tmp.push(x & y);
                break;
            case '|':
                tmp.push(x |y);
                break;
            case '=':
                tmp.push(x==y);
                break;
            case '>':
                tmp.push(!x|y);
                break;
            
                
            }
        }
    }
    return tmp.top();
}
int main()
{
    cout<<"请使用() & | ! => 来表达命题:";
    string input;
    cin >> input;
    vector<string>inputal;
    al_num(input,inputal);
   /* for(vector<string>::iterator i = inputal.begin(); i != inputal.end();++i)
    {
        cout<<*i<<endl;
    }检验函数是否准确*/
    int varnum = inputal.size();
    int tablenum = (int)pow(2,varnum);
    bool real_table[tablenum][varnum+1];//定义真值表
    for(int i = 0 ; i < tablenum ; ++i)
    {
        int num = i;
        for(int j = 0 ; j < varnum ; ++j)
        {
            real_table[i][j] = num%2;
            num /=2;
        }
    }
    cout<<"real_table" <<endl;
    for(int i = 0 ; i < varnum ; ++i)
    {
        cout<<inputal[i] <<'\t';

    }
    cout<<input<<endl;
    for(int i = 0 ; i < varnum + 1; ++i)
    {
        cout<<"-\t";
    }
    cout<<endl;


    for(int i = 0 ; i < tablenum ; ++i)
    {
        string expr = input;
        for(int j = 0 ; j < varnum ; ++j)
        {
            replaceal(expr,inputal[j],b2s(real_table[i][j]));//将字母换成1 或0
            cout<<b2s(real_table[i][j])<<"\t";
        }
        string suffixexpr = i2s(expr);//运算优先级 中缀转后续
        real_table[i][varnum] = cal(suffixexpr);
        cout << b2s(real_table[i][varnum])<<endl;


    }
    cout <<"主析取范式"<<endl;
    bool first = true;
    for(int i = 0 ; i < tablenum; ++i)
    {
        if(real_table[i][varnum]==false)
            continue;
        if(first)
            first = false;
        else
        {
            cout <<'|';
        }
        cout<<'(';
        for(int j = 0 ; j < varnum ; ++j)
        {
            if(real_table[i][j]==false)
                cout<<'!';
            cout<<inputal[j];
            if(j !=varnum-1)
                cout<<'&';
        }
       cout<<')'; 

    }
    cout<<endl;
    cout<<"主合取范式"<<endl;
    first = true;
    for(int i = 0 ; i < tablenum ; ++i)
    {
        if(real_table[i][varnum])
            continue;
        if(first)
        first = false;
        else
            cout<<'&';

        cout<<'(';
        for(int j = 0 ; j < varnum ; ++j)
        {
            if(real_table[i][j])
                cout<<'!';
            cout<<inputal[j];
            if(j!=varnum-1)
            cout<<'|';


        }
        cout<<')';


   }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值