POJ 3295 Tautology解题报告

http://poj.org/problem?id=3295

算法主要思路:
1. 获取所有的终结字符(小字符),组合所有的可能性(0或者1);
2. 然后带入到输入的字符串中进行计算
3. 如果所有组合的输出都是真(1),那么就是Tautology;否则是not

注意事项:
1. 两个难点,一个是组合的产生;另一个是计算。计算需要从字符串的最后开始朝开始”规约“,直到最后只有一个符号。需要有点编译原理的知识。
2. 数据集测试。这个很重要,否则,有些问题发现不了。

本代码中有测试数据。需要把TEST宏定义打开,就可以使用。

#include <iostream>
#include <string.h>
#include <assert.h>

using namespace std;

//#define TEST
#define LINE_SIZE 110
#define SYM_SIZE 5

char line[LINE_SIZE];
typedef bool(* opr_f_T)(bool,bool);
typedef struct{
    char s;  //opr symbols: KANCE
    opr_f_T f;
}opr_T;
typedef struct{
    char s;  //terminal symbols: pqrst
    bool b;         //有效位//枚举位
}term_T;

bool opr_K(bool w,bool x){
    if(w&&x)return true;
    return false;
}
bool opr_A(bool w,bool x){
    if(!w&&!x)return false;
    return true;
}
bool opr_N(bool w,bool x){
    return !w;
}
bool opr_C(bool w,bool x){
    if(w&&!x)return false;
    return true;
}
bool opr_E(bool w,bool x){
    if(w==x)return true;
    return false;
}

opr_T oprs[SYM_SIZE]={
    'K',opr_K,
    'A',opr_A,
    'N',opr_N,
    'C',opr_C,
    'E',opr_E};
term_T s[SYM_SIZE]={
    'p',false,
    'q',false,
    'r',false,
    's',false,
    't',false};
term_T vs[SYM_SIZE]={0};
int valid_sym;

bool init_terms(const char ch){
    for(int i=0;i<SYM_SIZE;i++){
        if(ch==s[i].s){
            s[i].b = true;
            return true;
        }
    }
    return false;
}
void erase_str(char *in, int len, int start, int consumed){
    for(int i=start;i<=(len-consumed);i++){
        in[i]=in[i+consumed];
    }
}
bool check_sym(char ch){
    for(int i=0;i<valid_sym;i++)
        if(ch==vs[i].s)
            return vs[i].b;

    cout <<"impossible"+ch<<endl;
    return false;
}
bool opr_symbol(char ch, bool n1, bool n2){
    for(int i=0;i<SYM_SIZE;i++){
        if(ch==oprs[i].s)
            return oprs[i].f(n1,n2);
    }
    cout <<"impossible"+ch<<endl;
    return false;
}
bool checkfinal(){
    int len;
    char in[LINE_SIZE];
    strcpy(in, line);

    len = strlen(in);
    //replace
    for(int i=0;i<len;i++){
        char ch;
        if(in[i]>='a' && in[i]<='z'){
            in[i] = check_sym(in[i]);
            ch = in[i]?'1':'0';
            //cout <<ch;
            }
        else
            ;//cout <<in[i];
    }

    //compute
    for(int i=len-1;i>=0;i--){
        int consumed;
        bool n1,n2;
        if(in[i]>='A' && in[i]<='Z'){
            if(in[i]=='N'){
                consumed = 1;
                n1=in[i+1];
                assert(i+1<len);
            }else{
                consumed = 2;
                n1=in[i+1];
                n2=in[i+2];
                assert(i+2<len);
            }

            in[i]=opr_symbol(in[i],n1,n2);
            erase_str(in,len,i+1,consumed);
            len -=consumed;
        }
    }

    if((len==1) && in[0]){
        //cout<<" 1"<<endl;
        return true;
        }
    else{
        //cout<<" 0"<<endl;
        return false;
        }
}
//i: 有几个true
bool combination(term_T *vs_p, int i){
    //int j=0;
    //(j=(&vs[valid_sym]-vs_p)/sizeof(term_T)) == i
    //一个组合
    if(i==0){
        return checkfinal();
    }else if((vs_p+i)==&vs[valid_sym]){
        for(int j=0;j<i;j++){
            vs_p[j].b=true;
        }
        return checkfinal();
    }else{
        vs_p[0].b=false;
        if(combination(vs_p+1,i)){
            vs_p[0].b=true;
            return (combination(vs_p+1,i-1));
        }else{
            return false;
        }
    }
}
bool compute(){
    for(int i=0;i<=valid_sym;i++){
        if(!combination(vs, i))
            return false;
    }
    return true;
}
bool check(){
    //各种排列,带入到line中进行计算
    valid_sym=0;

    for(int i=0;i<SYM_SIZE;i++){
            vs[i].s=0;
            vs[i].b=false;
        }

    for(int i=0;i<SYM_SIZE;i++){
        if(s[i].b){
            vs[valid_sym].s=s[i].s;
            vs[valid_sym++].b=false;
        }
    }
    return compute();
}

#if defined(TEST)
char* lines[]={
"p","not",
"q","not",
"r","not",
"s","not",
"t","not",
"Cpp","tautology",
"App","not",
"Kpp","not",
"Epp","tautology",
"NNNNNNNNNNNNNNNNNNNAKKKEEKEEKppppppppppp","not",
"NNNNNNNNNNNNNCAKKEEEAACKKKKKCEEEACKKEKCCEKAppqqqppppqqpqppppqqppppqqqppppp","not",
"NNNNNNNNNNNACKCAKEAAEKCAKECEKKKACAAEAKAKCKKrqqqprpppprpqprqprrppqrqqrqrqppqp","not",
"NNNNNNNNCAEACACKEEEKKAEEEEAKKEECACKACECCCEKAECEECCCACrrrrprrqssrprrqpsssrrpsqssqprrqpprrpqrppqqsqqs","not",
"NNNNNNNNNNNKAEEACEKKCCCKKAAECACAECAEKKECKAAAECCCKEAACArqpsrstpqsspsppssrpsprstsqspsspptrqrprptstps","not",
"NNNNNNNNNNNNEAAECEAEAECKCEAAAEEACAACCKEAKtqptstpttssrptqrtsstpptqtssppp","not",
"NNNNNNNNNNNNNNNNNNNCAAAKEEAEACCCACECCCCCCEKCKCAKCpqpssqsppprttrqprspsssttsrprtqq","not",
"NNNNNNNNNNNNEEKKCCCACACECEACCKCCAEKKKKCEKCEKEppsrrpqtqrrspqrqrpprtpqpqqrqqqtprp","not",
"NNNNCAAEAECKKEKKEAACEAECAEEECCCCEKAKCKKAAEKrrtssrrppprrpstsrqqrrqprqrsprsspsrpsspsq","not",
"NNNNNNNNNECCKAAACAKAAECCKAECKEAEKEACCKErstrqpqrtrtrqstqpptprttprtrrqtq","not",
"NNAKAKEAKEAEAKACCEECCKKAACECAACACrrtrqtsttstspqrstqrpspqttrpspqsp","not",
"NNNEECEACEECKAAKKKCEKECKAKKAAAAAKsrtpprtrqqtpsssrrprtsqtsrpssspt","not",
"NNNNNNCEECAKAACEKECAKCCAEECCCAEAEKKKrpqqqsqprqqsqtqstsrpqsqsqsrqsqs","not",
"NNNAEAEKEACEECECKCAEAKCEEEKEKEKKCECEqtpssqrptpsqppqpprsqpttqrsqqrqqtrq","not",
"CNNNEECEEEKECAAEACAsppsrqpptpspppqqNNNEECEEEKECAAEACAsppsrqpptpspppqq","tautology",
"ANNNEECEEEKECAAEACAsppsrqpptpspppqqNNNEECEEEKECAAEACAsppsrqpptpspppqq","not",
"KNNNEECEEEKECAAEACAsppsrqpptpspppqqNNNEECEEEKECAAEACAsppsrqpptpspppqq","not",
"ENNNEECEEEKECAAEACAsppsrqpptpspppqqNNNEECEEEKECAAEACAsppsrqpptpspppqq","tautology",
"CNNNEAKCEKCEAKACECKACCEKCqppppptrqqttptttqtpqssNNNEAKCEKCEAKACECKACCEKCqppppptrqqttptttqtpqss","tautology",
"ANNNEAKCEKCEAKACECKACCEKCqppppptrqqttptttqtpqssNNNEAKCEKCEAKACECKACCEKCqppppptrqqttptttqtpqss","not",
"KNNNEAKCEKCEAKACECKACCEKCqppppptrqqttptttqtpqssNNNEAKCEKCEAKACECKACCEKCqppppptrqqttptttqtpqss","not",
"ENNNEAKCEKCEAKACECKACCEKCqppppptrqqttptttqtpqssNNNEAKCEKCEAKACECKACCEKCqppppptrqqttptttqtpqss","tautology",
"NCNNNEAKCEKCEAKACECKACCEKCqppppptrqqttptttqtpqssNNNEAKCEKCEAKACECKACCEKCqppppptrqqttptttqtpqss","not",
"NANNNEAKCEKCEAKACECKACCEKCqppppptrqqttptttqtpqssNNNEAKCEKCEAKACECKACCEKCqppppptrqqttptttqtpqss","not",
"NKNNNEAKCEKCEAKACECKACCEKCqppppptrqqttptttqtpqssNNNEAKCEKCEAKACECKACCEKCqppppptrqqttptttqtpqss","not",
"NENNNEAKCEKCEAKACECKACCEKCqppppptrqqttptttqtpqssNNNEAKCEKCEAKACECKACCEKCqppppptrqqttptttqtpqss","not",
"NNNNEEEEEAAACKEKAAEEAqpptpsqsrqpprssptt","not",
"NNNKAKCEECACCEECACEKrtrrsstpqptpstsrsq","not",
"NNNNNNNNNCACCCEKEACEACpqrqpsststtpps","not",
"NNNNKKCACEACECCssqptqptrrtr","not",
"NNNAAAACKECCAKAKACprspqspspsttpttr","not",
"NNNECCCECCAAEpqstpspppss","not",
"NNNNNCEAECACCEKAEEEppsptpsppprpqrq","not",
"AEAAKKEEEKAEAKpqqtpppsssqrqsp","not",
"NNAKEKAAKprqrpqpt","not",
"NNNAKACAKEKCECKtqppqtpqsqspr","not",
"NCEKEEACCCppsstppprp","not",
"NNNAEKCEKAEEECEEKEtrqpppqqpppqstpp","not",
"NNNNCKEAACAKEKACECCEKstppprrptqqpqqpppp","tautology",
"NNEAKCECKACEEECKprrpqqsppppttqr","not",
"NNNNNCKAAAKKEKKKECKECppqrppttpsttrtqtq","not",
"NNEKKACCKKACEKErpprsptppppptq","not",
"NNNCKECCAEAECAEspqpqpprsptpr","not",
"NNNCKECKCEEECstrtppsrtrp","not",
"NNKCCKACKAACKprtttttpttpp","not",
"NNNNEACCKKEArqpptrppt","not",
"NKECKACAptrrrttt","not",
"NNAEEEKECAAptpspptqpp","not",
"NNNACKEEAAKAKKpsrttqtssrrt","not",
"NNKKAKAKEEECACEEtstqqrsptttrprp","not",
"CKAKECKKKtttppptptq","not",
"NNNCEEEKCECCtsptqqqptp","not",
"NAECCAKKCCttttpptpsr","not",
"NCEEKCCAErpptpsppt","not",
"NKKEEKtppttt","not",
"NCKCAECEpttqqttp","not",
"NNNNNEEKAAECqqpqpppt","not",
"NECAACAECCAACKtrpptpptqtpppp","not",
"NNKECKKACrttttrtp","not",
"AECAECrrtsptt","not",
};
char *lines1[]={"CKAKECKKKtttppptptq","not"};

int main(void){
    for(int i=0;i<sizeof(lines)/2;i++){
        strcpy(line,lines[i*2]);

        for(int i=0;i<SYM_SIZE;i++){
            s[i].b=false;
        }
        for(int i=0;i<strlen(line);i++){
            if(line[i]>='a' && line[i]<='z')
            if(!init_terms(line[i])){
                cout << "wrong input"+line[i] <<endl;
                break;
            }
        }
        if(check()){
            if(memcmp(lines[2*i+1],"tautology",strlen("tautology"))){
                cout << "expected="<< lines[2*i+1] << " lines["<< 2*i << "] " << lines[2*i]<<endl;
            }
        }else{
            if(memcmp(lines[2*i+1],"not",strlen("not"))){
                cout << "expected="<< lines[2*i+1] << " lines["<< 2*i << "] " << lines[2*i]<<endl;
            }
        }
        /*
            cout <<i<<" tautology" <<endl;
        else
            cout <<i<<" not" <<endl;*/
    }

    return 0;
}

#else
int main(void) {
    while(1){
        cin >> line;
        if('0'==line[0])
            break;  //exit while

        for(int i=0;i<SYM_SIZE;i++){
            s[i].b=false;
        }
        for(int i=0;i<strlen(line);i++){
            if(line[i]>='a' && line[i]<='z')
            if(!init_terms(line[i])){
                cout << "wrong input"+line[i] <<endl;
                break;
            }
        }
        if(check())
            cout <<"tautology" <<endl;
        else
            cout <<"not" <<endl;
    }

    return 0;
}
#endif // defined
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值