我的double array trie

 最近在看aoe的datrie结构,想实现一个,由于才疏学浅,花了几天时间的代码时间复杂度却是指数级(网上有nlogn),太让我伤心了。希望各位有研究的高手能够不吝赐教。下面是代码(写的比较傻瓜):

  
  
  
  
  1. #include "DASTrie.h" 
  2.  
  3. dastrie::dastrie():MemUse(BC_INIT_SIZE+TAIL_INIT_SIZE+TEMP_INIT_SIZE), 
  4.                    BC((int*)malloc(sizeof(int)*BC_INIT_SIZE)), 
  5.                    TAIL((char*)malloc(sizeof(char)*TAIL_INIT_SIZE)), 
  6.                    TEMP((char*)malloc(sizeof(char)*TEMP_INIT_SIZE)), 
  7.                    BC_pos(1), 
  8.                    TAIL_pos(2), 
  9.                    BC_max(BC_INIT_SIZE/2-1), 
  10.                    TAIL_max(TAIL_INIT_SIZE-1) 
  11.  
  12.      
  13.  
  14.     for(int i=0;i<BC_INIT_SIZE;i++) 
  15.     BC[i]=0; 
  16.     setbase(1,1); 
  17.  
  18.     memset(TAIL,0,TAIL_INIT_SIZE); 
  19.     memset(TEMP,0,TEMP_INIT_SIZE); 
  20. /*  TAIL[0]=TAIL[1]=TAIL_ENDUP_SIGN;*/ 
  21.  
  22.     } 
  23.  
  24.  
  25. dastrie::~dastrie(){ 
  26.     free(BC); 
  27.     free(TAIL); 
  28.     free(TEMP); 
  29.  
  30. void dastrie::setbase(int pos,int baseval){ 
  31.     while(pos>=BC_max) 
  32.         realloc_BC(); 
  33.     if(pos>BC_pos) 
  34.         BC_pos=pos; 
  35.     BC[2*pos]=baseval; 
  36.  
  37. void dastrie::setcheck(int pos,int checkval){ 
  38.  
  39.     while(pos>=BC_max) 
  40.         realloc_BC(); 
  41.  
  42.     if(pos>BC_pos) 
  43.         BC_pos=pos; 
  44.     BC[2*pos+1]=checkval; 
  45.  
  46. //#define getbase(y) (y>this->BC_pos ? 0:this->BC[2*y]) 
  47. int dastrie::getbase(int pos){ 
  48.      
  49.     //if (pos<0){printf("getbase()can not recive a negitive operator!!!%d" ,pos),exit(0);} 
  50.     if(pos>BC_pos) 
  51.         return(0); 
  52.     else return(BC[2*pos]); 
  53.  
  54.  
  55.  
  56. int dastrie::getcheck(int pos){ 
  57.     //if (pos<0){printf("getcheck()can not recive a negitive operator!!!%d",pos),exit(0);} 
  58.     if(pos>BC_pos) 
  59.         return(0); 
  60.     else return(BC[2*pos+1]); 
  61.  
  62. void dastrie::TAIL_insert(char* remain,int pos){ 
  63.      
  64.     int i=0; 
  65.     int len=strlen(remain); 
  66.     while((pos+len)>=TAIL_max-1){ 
  67.         /*printf("%s:need=%d max=%d\n",__FUNCTION__,pos+strlen(remain),TAIL_max);*/ 
  68.         /*while_num++;*/ 
  69.         realloc_TAIL(); 
  70.     } 
  71.     memcpy(TAIL+pos,remain,len); 
  72. //  while(*(remain+i)!='\0') 
  73. //      TAIL[pos++]=*(remain+i++); 
  74.      
  75.     if(pos+len>TAIL_pos) 
  76.         TAIL_pos=pos+len; 
  77.      
  78.  
  79.  
  80. void dastrie::getTAIL(int pos){ 
  81.     if(pos>TAIL_pos) 
  82.         fprintf(stderr,"TAIL访问越界"); 
  83.     int i=0; 
  84.     while(TAIL[pos]!=TAIL_ENDUP_SIGN) 
  85.         TEMP[i++]=TAIL[pos++]; 
  86.     TEMP[i++]=TAIL_ENDUP_SIGN; 
  87.     TEMP[i]='\0'
  88.  
  89.  
  90.  
  91. void dastrie::realloc_BC(){ 
  92.     int pre_bc,i=0; 
  93.     pre_bc=BC_max; 
  94.     BC_max+=BC_INCREASE_SIZE/2; 
  95.     if((BC=(int*)realloc(BC,sizeof(int)*((BC_max+1)*2)))==NULL) 
  96.         {printf("BC再分配出错");exit(-1);} 
  97.     for(i=2*(pre_bc+1);i<2*(BC_max+1);i++) 
  98.         BC[i]=0; 
  99. #ifdef DEBUG  
  100.     {printf("BC_MAX=%d",BC_max); 
  101.     printf("BC REALLOCed\n");} 
  102. #endif 
  103.  
  104. void dastrie::realloc_TAIL(){ 
  105.     int i,pre_tail=TAIL_max; 
  106.     TAIL_max+=TAIL_INCREASE_SIZE; 
  107.  
  108.     if((TAIL=(char*)realloc(TAIL,sizeof(char)*(TAIL_max+1)))==NULL) 
  109.     {printf("TAIL 再分配出错!");exit(-1);} 
  110.     for(i=pre_tail;i<TAIL_max;i++) 
  111.         TAIL[i]='\0'
  112. #ifdef DEBUG 
  113.         printf("tail_max=%d,TAIL_REALLOCED\n",TAIL_max); 
  114. #endif 
  115.  
  116.  
  117.  
  118. bool dastrie::BuildTrie(const char *textname){ 
  119.     FILE* fp;char buff[1025];int i=0; 
  120.     fp=fopen(textname,"r"); 
  121.      
  122.     while(i<KEYNUMBER&&!feof(fp)) 
  123.     {   fscanf(fp,"%s",buff); 
  124.      /*  printf("%s\n",buff);*/ 
  125.       if(!strcmp(buff,"withdraw")) 
  126.           int uuuu=0; 
  127.         insertkey(buff); 
  128.         //printf("bc=%d,tail=%d\n",BC_max,TAIL_max); 
  129.         i++; 
  130.     } 
  131. //  
  132. //   printf("while=%d",while_num);   
  133. //   
  134.  
  135. return true
  136.  
  137.  
  138.  
  139. bool dastrie::SearchKey(char *keyinput){ 
  140.     int h=0,s=1; 
  141.     int t; 
  142.     char* key=(char* )malloc(sizeof(char)*sizeof(keyinput+1)); 
  143.     strcpy(key,keyinput); 
  144.     strcat(key,"#"); 
  145.     while(1){ 
  146.         //while_num++; 
  147.         t=getbase(s)+key[h]; 
  148.         if(t>BC_pos||getcheck(t)!=s) 
  149.             return(false);               
  150.         if(getbase(t)==-1)               //已经匹配终止符(本版本为#)到达终点 
  151.             return true
  152.         if(getbase(t)<0)                 //到达separate node 
  153.             break
  154.         s=t; 
  155.         h++; 
  156.     } 
  157.      
  158.      
  159.     getTAIL(-getbase(t)); 
  160.     if(!strcmp(TEMP,(key+h+1))) 
  161.        return true
  162.     return(false); 
  163.  
  164.  
  165. void dastrie::insertkey(char* key) 
  166.     int h=0,s=1,i; 
  167.     int t; 
  168.     strcat(key,"#"); 
  169.     while(1){ 
  170.         //while_num++; 
  171.         t=getbase(s)+key[h]; 
  172.          
  173.         if(getcheck(t)!=s) 
  174.         {A_Insert(s,key+h);return;} 
  175.         if(getbase(t)==-1)                 //如果是-1表示匹配了一个以#结尾的字串,即已经存在 
  176.             return;                         
  177.         if(getbase(t)<-1)                 //到达separate node 
  178.             break
  179.         s=t; 
  180.         h++; 
  181.     } 
  182.  
  183.  
  184.     getTAIL(-getbase(t)); 
  185.      
  186.     int no=mycmp(TEMP,key+h+1); 
  187.     if(no==-1) 
  188.         return;//already in our list,no need to insert 
  189.     char* samepre=(char*)malloc(sizeof(char)*(no+1)); 
  190.     for(i=0;i<no;i++) 
  191.         samepre[i]=TEMP[i]; 
  192.     samepre[i]='\0'
  193.     char *temp1=(char*)malloc(sizeof(char)*(strlen(key+h+1)-no+1)); 
  194.     for(i=0;i<=strlen(key+h+1)-no;i++) 
  195.         temp1[i]=(key+h+1)[i+no]; 
  196.      
  197.     char *temp2=(char*)malloc(sizeof(char)*(strlen(TEMP)-no+1)); 
  198.     for(i=0;i<=strlen(TEMP)-no;i++) 
  199.         temp2[i]=TEMP[i+no]; 
  200.  
  201.     B_Insert(t,samepre,temp1,temp2); 
  202. //  return(false); 
  203.     free(samepre); 
  204.     free(temp1); 
  205.     free(temp2); 
  206.  
  207.  
  208. void dastrie::fprint_info() 
  209.     FILE* fp; 
  210.     fp=fopen("d:\\info.txt","w+"); 
  211.     fprintf(fp,"BC:"); 
  212.     for(int i=0;i<BC_max;i++) 
  213.         fprintf(fp,"%d  ",BC[i]); 
  214.     fprintf(fp,"\n"); 
  215.     fprintf(fp,"TAIL:\n"); 
  216.     for(int i=0;i<TAIL_max;i++) 
  217.         fprintf(fp,"%c ",TAIL[i]); 
  218.     fprintf(fp,"\n"); 
  219.     fprintf(fp,"mem use:%ld",MemUse); 
  220.  
  221. void dastrie::A_Insert(int pos,char*aa){ 
  222.     ASSERT(pos>0); 
  223.     int t=getbase(pos)+aa[0];  //t为本次应该插入的位置 
  224.     if(getcheck(t)==0){                    //希望插入的位置是空的,皆大欢喜 
  225.         setcheck(t,pos); 
  226.         setbase(t,-TAIL_pos); 
  227.         TAIL_insert(aa+1,TAIL_pos); 
  228.          
  229.         } 
  230.     else{                                 //希望插入的位置是被占用的,要'强拆',代价比较大 
  231.         vector<int> v1; 
  232.         vector<int> v2; 
  233.         set_list(pos,&v1); 
  234.         set_list(getcheck(t),&v2); 
  235.         if(v1.size()+1<v2.size()&&pos!=1){ 
  236.              
  237.             pos=MODIFY(pos,pos,aa[0],v1); 
  238.             setcheck(getbase(pos)+(int)aa[0],pos); 
  239.             setbase(getbase(pos)+(int)aa[0],-TAIL_pos); 
  240.             TAIL_insert(aa+1,TAIL_pos); 
  241.              
  242.         } 
  243.         else
  244.             pos=MODIFY(pos,getcheck(t),NULL,v2); 
  245.             setcheck(t,pos); 
  246.             setbase(t,-TAIL_pos); 
  247.              
  248.             TAIL_insert(aa+1,TAIL_pos);} 
  249.      
  250.         } 
  251.  
  252.  
  253.  
  254. void dastrie::B_Insert(int pos,char* pre,char* aremain,char* bremain){ 
  255.     int old_tailpos=-getbase(pos); 
  256.     TAIL_RESET(old_tailpos); 
  257.     for(int i=0;i<strlen(pre);i++){ 
  258.         vector<int> vv; 
  259.         vv.push_back(pre[i]); 
  260.         setbase(pos,X_CHECK(vv)); 
  261.         setcheck(getbase(pos)+pre[i],pos); 
  262.         pos=getbase(pos)+pre[i]; 
  263.     } 
  264.     vector<int> vv; 
  265.     vv.push_back(aremain[0]); 
  266.     vv.push_back(bremain[0]); 
  267.     setbase(pos,X_CHECK(vv));// 
  268.      
  269.     setcheck(getbase(pos)+aremain[0],pos); 
  270.     if(*(aremain+1)=='\0'
  271.         setbase(getbase(pos)+aremain[0],-1); 
  272.     else
  273.         setbase(getbase(pos)+aremain[0],-TAIL_pos); 
  274.     TAIL_insert(aremain+1,TAIL_pos); 
  275.     } 
  276.     setcheck(getbase(pos)+bremain[0],pos); 
  277.     if(*(bremain+1)=='\0'
  278.         setbase(getbase(pos)+bremain[0],-1); 
  279.     else
  280.         setbase(getbase(pos)+bremain[0],-old_tailpos); 
  281.         TAIL_insert(bremain+1,old_tailpos);} 
  282.  
  283.  
  284. void dastrie::set_list(int pos,vector<int> *pvlist)  //找到某个pos的所有出边,放入vector中 
  285.     if (getbase(pos)<0) 
  286.         return
  287.     for(int i=0;i<256;i++) 
  288.         if(getcheck(getbase(pos)+i)==pos) 
  289.             pvlist->push_back(i); 
  290.  
  291. int dastrie::X_CHECK(vector<int> vv)      //找到一个合适的值n,满足n>0且对于vector中的所有c,check[n+c]==0.如果找不到,返回-1. 
  292. {vector<int>::iterator p; 
  293.     for(int i=1;i<BC_max;i++) 
  294.         {for(p=vv.begin();p<vv.end();p++) 
  295.             if(getcheck(*p+i)!=0) 
  296.                 break
  297.             if (p==vv.end()) 
  298.                 return i;  
  299.           
  300.         } 
  301.     return(-1); 
  302.  
  303.  
  304. void dastrie::TAIL_RESET(int pos){ 
  305.     while(TAIL[pos]!=TAIL_ENDUP_SIGN) 
  306.         TAIL[pos++]=0; 
  307.     TAIL[pos]=0; 
  308.  
  309.  
  310.  
  311. int dastrie::MODIFY(int current_s,int change_s,char ch,vector<int> int_v){ 
  312.     int old_base=getbase(change_s); 
  313.     vector<int> vv; 
  314.     vv=int_v; 
  315.     if(ch!=NULL) 
  316.         vv.push_back((int)ch); 
  317.     setbase(change_s,X_CHECK(vv)); 
  318.     for(vector<int>::iterator i=int_v.begin();i<int_v.end();i++){ 
  319.         int t=old_base+*i; 
  320.         int t_new=getbase(change_s)+*i; 
  321.         setbase(t_new,getbase(t)); 
  322.         setcheck(t_new,change_s); 
  323.         if(getbase(t)>0) 
  324.         { 
  325.             for(int j=0;j<256;j++) 
  326.                 if(getcheck(getbase(t)+j)==t) 
  327.                     setcheck(getbase(t)+j,t_new); 
  328.              
  329.         } 
  330.  
  331.  
  332.         setbase(t,0);//释放旧的节点 
  333.         setcheck(t,0); 
  334.         if(t=current_s&&current_s!=change_s) 
  335.             current_s=t_new; 
  336.     } 
  337.  
  338.      
  339.     //return current_s; //?????????????????????????????????????????????// 
  340.      
  341.  
  342.     return current_s; 
  343.      

请大家看看我的复杂度怎么能降下来,thx。

ps:我知道可以把空闲节点连接成双向链表,但是时间复杂度不会降那么多吧?

你可能感兴趣的:(算法,array,职场,double,trie,trie,休闲,DA)