修改后的代码
例子:
$ ./isset "{{},{,,{{}},{},{}}},{{,}},},}}"
Set
{{},{,,{{}},{},{}}},{{,}},},}}
{{},{E,{E}},{E,{E}},{E,E},E,E}
#include <stdio.h>
#include <set>
using namespace std;
#define MAX_LEN 1000
class STATE{
private:
short numberLeft;
char s;
char the_char;
public:
STATE(short left, char state, char input):numberLeft(left),s(state),the_char(input){}
bool operator<(const STATE& s)const{
if(numberLeft<s.numberLeft)return true;
else if(numberLeft>s.numberLeft)return false;
if(this->s<s.s)return true;
else return false;
return false;
}
bool operator==(const STATE& s)const{
return numberLeft==s.numberLeft&&this->s==s.s;
}
char getState()const{return s;}
int getLeft()const{return numberLeft;}
void increaseLeft(){numberLeft++;}
char getInputChar()const{return the_char;}
STATE findPrevState(char c,int prev,bool last_pass)const;
};
typedef set<STATE> STATE_SET;
STATE_SET sets[MAX_LEN];
STATE STATE::findPrevState(char c,int prev,bool last_pass)const
{
STATE_SET::iterator it;
for(it=sets[prev].begin();it!=sets[prev].end();++it){
const STATE& s=*it;
switch(s.getState()){
case '{':
if(c=='{'){
STATE ns1(s.getLeft()+1,'{','{');
if(ns1==*this)return s;
STATE ns2(s.getLeft(),'E','E');
if(ns2==*this)return s;
}else if(c=='}'){
STATE ns1(s.getLeft(),'E','E');
if(ns1==*this)return s;
if(s.getLeft()>1||s.getLeft()==1&&last_pass){
STATE ns2(s.getLeft()-1,'E','}');
if(ns2==*this)return s;
}
}else{//c==','
STATE ns(s.getLeft(),'E','E');
if(ns==*this)return s;
}
break;
case ',':
if(c=='{'){
STATE ns1(s.getLeft()+1,'{','{');
if(ns1==*this)return s;
STATE ns2(s.getLeft(),'E','E');
if(ns2==*this)return s;
}else if(c=='}'){
STATE ns1(s.getLeft(),'E','E');
if(ns1==*this)return s;
}else{//c==','
STATE ns(s.getLeft(),'E','E');
if(ns==*this)return s;
}
break;
case 'E':
if(c=='{'){
}else if(c=='}'){
if(s.getLeft()>1||s.getLeft()==1&&last_pass){
STATE ns(s.getLeft()-1,'E','}');
if(ns==*this)return s;
}
}else{//c==','
STATE ns(s.getLeft(),',',',');
if(ns==*this)return s;
}
break;
}
}
}
void build_sets_i(int step, char c,bool last_pass)
{
STATE_SET::iterator it;
for(it=sets[step-1].begin();it!=sets[step-1].end();++it){
const STATE& s=*it;
switch(s.getState()){
case '{':
if(c=='{'){
sets[step].insert(STATE(s.getLeft()+1,'{','{'));
sets[step].insert(STATE(s.getLeft(),'E','E'));
}else if(c=='}'){
sets[step].insert(STATE(s.getLeft(),'E','E'));
if(s.getLeft()>1||s.getLeft()==1&&last_pass){
sets[step].insert(STATE(s.getLeft()-1,'E','}'));
}
}else{//c==','
sets[step].insert(STATE(s.getLeft(),'E','E'));
}
break;
case ',':
if(c=='{'){
sets[step].insert(STATE(s.getLeft()+1,'{','{'));
sets[step].insert(STATE(s.getLeft(),'E','E'));
}else if(c=='}'){
sets[step].insert(STATE(s.getLeft(),'E','E'));
}else{//c==','
sets[step].insert(STATE(s.getLeft(),'E','E'));
}
break;
case 'E':
if(c=='{'){
}else if(c=='}'){
if(s.getLeft()>1||s.getLeft()==1&&last_pass){
sets[step].insert(STATE(s.getLeft()-1,'E','}'));
}
}else{//c==','
sets[step].insert(STATE(s.getLeft(),',',','));
}
break;
}
}
}
int main(int argc, char *argv[]){
int i,len;
char *input;
char *trace;
if(argc!=2){
fprintf(stderr,"Usage: %s \"string of {},\"\n",argv[0]);
return -1;
}
input=argv[1];
for(i=0;input[i]!='\0';i++){
if(input[i]!='{'&&input[i]!='}'&&input[i]!=','){
fprintf(stderr,"Invalid input\n");
return -1;
}
}
if(i>MAX_LEN){
fprintf(stderr,"Too Long input\n");
return -1;
}
if(input[0]!='{'||input[i-1]!='}'){
printf("No Set\n");
return 0;
}
len = i;
sets[0].insert(STATE(1,'{','{'));
for(i=1;i<len;i++){
build_sets_i(i,input[i],i==len-1);
}
#if 0
for(i=0;i<len;i++){
fprintf(stderr,"TRACE %d:\n",i);
STATE_SET::iterator it;
for(it=sets[i].begin();it!=sets[i].end();++it){
fprintf(stderr,"\t%d,%c,%c\n",it->getLeft(),it->getState(),it->getInputChar());
}
}
#endif
STATE_SET::iterator it;
for(it=sets[len-1].begin();it!=sets[len-1].end();++it){
if(it->getLeft()==0){///find a solution for set
break;
}
}
if(it==sets[len-1].end()){
printf("No Set\n");
}else{
printf("Set\n");
///Next show how to treat the set;
printf("%s\n",input);
trace = new char[len+1];
trace[len]='\0';
STATE s=*it;
for(i=len-1;i>0;i--){
trace[i]=s.getInputChar();
s = s.findPrevState(input[i],i-1,i==len-1);
}
trace[0]=s.getInputChar();
printf("%s\n",trace);
delete []trace;
}
}