离散数学编程作业

一:真值表的打印
要求:输入任意主析取范式或者主合取范式打印出真值表

#include <iostream>
#include <stack>
#include <map>
#include <cstdio>
#include <algorithm>
using namespace std;
stack<int> num;
stack<int> fuhao;
int n;
map<char,int> mp;
string str;
int w[100];
char temp[100];

/**输入格式
p-(q-r)
r-(p-(p-q))
~p|~q

**/

void calu_num()
{
    int len = str.length();
    int flag[200] = {0};
    for(int i = 0; i < len; i++)
    {
        if(str[i] >= 'a' && str[i] <= 'z')
        {
            if(!flag[str[i]])
            {
                temp[n++] = str[i];
                flag[str[i]] = 1;
            }
        }
    }
    sort(temp,temp+n,greater<char>() );
    for(int i = 0; i < n; i++)  mp[temp[i]] = i + 1;
    mp[1] = n+1;
    mp[0] = n+2;

}
void  push()
{
    char ch1,ch2,ch3;
    ch1 = num.top();
    num.pop();
    ch2 = num.top();
    num.pop();
    ch3 = fuhao.top();
    fuhao.pop();
    if(ch3 == '&')
    {
        num.push( (ch2 >= 'A' && ch2 <= 'Z' ? !w[mp[ch2 + 32]] : w[mp[ch2]] ) &
                  (ch1 >= 'A' && ch1 <= 'Z' ? !w[mp[ch1+32]] : w[mp[ch1]]  ) );
    }
    else if(ch3 == '|')
    {
        num.push( (ch2 >= 'A' && ch2 <= 'Z' ? !w[mp[ch2 + 32]] : w[mp[ch2]] ) ||
                  (ch1 >= 'A' && ch1 <= 'Z' ? !w[mp[ch1+32]] : w[mp[ch1]]  ) );
    }
    else if(ch3 == '-')
    {
        num.push( (ch2 >= 'A' && ch2 <= 'Z' ? w[mp[ch2 + 32]] : !w[mp[ch2]] ) ||
                  (ch1 >= 'A' && ch1 <= 'Z' ? !w[mp[ch1 + 32]] : w[mp[ch1]]  ) );
    }
}

int solve1()
{
    int len = str.length();
    while(!num.empty()) num.pop();
    while(!fuhao.empty()) fuhao.pop();
    for(int i = 0; i < len; i++)
    {
        if(str[i] == '(' ) continue;
        if(str[i] == ')' && num.size() > 1 && fuhao.size() >= 1)
        {
            push();
            continue;
        }
        if(str[i] >= 'a' && str[i] <= 'z')
        {
            num.push(str[i]);
        }
        else
        {
            if(str[i] == '~')
            {
                i++;
                num.push(str[i] - 32);
            }
            else fuhao.push(str[i]);
        }

    }
    if(num.size() > 1 && fuhao.size() >= 1)
    {
        push();
    }
    return (int)num.top();
}

void solve()
{
    calu_num();
    for(int j = n-1; j >= 0; j--)   cout<<temp[j]<<"  ";
    for(int i = 0; i < str.length(); i++)
    {
        cout<<str[i];
        if(str[i] == '-') cout<<">";
    }
    cout<<" "<<endl;
    for(int i = 0; i <= (1 << n) - 1; i++)
    {
        for(int j = 1; j <= n; j++)  w[j] =  1 & (i >> (j - 1) ) ;
        w[n+1] = 1;
        w[n+2] = 0;
        int ans = solve1();
        for(int j = n; j >= 1; j--)  cout<<w[j]<<"  ";
        cout<<ans<<endl;
    }
}

int main()
{
#ifdef xxz
    freopen("in.txt","r",stdin);
#endif // xxz
    cout<<"请输入字符串,支持吸取(&),合取(|),蕴含(-),非(~):"<<endl<<endl;
    cin>>str;
    solve();
    return 0;
}

运行结果

二:用消解法判断公式是否是可满足的(默认已经是主合取范式)

#include <iostream>
#include <set>
#include <cstring>
#include <cstdio>
using namespace std;
set<string> s0;
set<string> s1;
set<string> s2;
string str,temp;

/**
输入格式,默认已经是合取范式
(~p|q)&(p|q)&(~q)
p&(p|q)&(p|~q)&(q|~r)&(p|r)
**/

void init()
{
    s0.clear();
    s1.clear();
    s2.clear();

    int p = 0;
    for(int i = 0; i < str.length(); i++)
    {
        if(i == 0 && str[i] != '(')
        {
            temp.clear();
            temp += str[i];
            s1.insert(temp);
            continue;
        }
        if(str[i] == '&' && str[i+1] != '(')
        {
            temp.clear();
            temp += str[i+1];
            s1.insert(temp);
            continue;
        }
        if(str[i] == '(') p = i;
        if(str[i] == ')')
        {
            temp.clear();
            for(int j = p+1; j < i; j++)
            {
                if(str[j] == '~')
                {
                    str[j+1] = str[j+1] - 32;
                    temp += str[j+1];
                    j++;
                }
                else if(str[j] != '|')
                {
                    temp += str[j];
                }

            }
            s1.insert(temp);
        }

    }

}

string Res(string A, string B)
{
    int Count[26] = {0};
    int id;

    for(int i = 0; i < A.size(); i++)
    {
        if(A[i] < 'a')
        {
            id = A[i] - 'A';
            Count[id]++;
        }
        else
        {
            id = A[i] - 'a';
            Count[id]--;
        }
    }
    for(int i = 0; i < B.size(); i++)
    {
        if(B[i] < 'a')
        {
            id = B[i] - 'A';
            Count[id]++;
        }
        else
        {
            id = B[i] - 'a';
            Count[id]--;
        }
    }

    string C;

    for(int i = 0; i < 26; i++)
    {
        if(Count[i] > 0) C += i + 'A';
        if(Count[i] < 0) C += i + 'a';
    }

    return C;
}

bool solve()
{
    set<string>::iterator it,iy;
    while(true)
    {

        //遍历s0,s1
        for(it = s0.begin(); it != s0.end(); it++)
            for(iy = s1.begin() ; iy != s1.end(); iy++)
            {
                string t1 = *it,t2 = *iy;
                string C = Res(t1,t2);
                if(C.empty()) return false;
                else if(s0.count(C) == 0 && s1.count(C) == 0)
                {
                    s2.insert(C);
                }
            }

        //遍历s1
        for(it = s1.begin(); it != s1.end(); it++)
        {
            for(iy = ++it,it--; iy != s1.end(); iy++)
            {
                string t1 = *it,t2 = *iy;
                string C = Res(t1,t2);
                if(C.empty()) return false;
                else if(s0.count(C) == 0 && s1.count(C) == 0)  s2.insert(C);

            }

        }

        if(s2.empty()) return true;
        else
        {
            s0 = s1;
            s1 = s2;
            s2.clear();
        }
    }
}

int main()
{
#ifdef xxz
    freopen("in.txt","r",stdin);
#endif // xxz
    while(cin>>str)
    {
        init();
        if(solve()) cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }


    return 0;
}
  • 7
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值