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