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

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

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

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

转载于:https://blog.51cto.com/nick151/710421

我的double array trie相关推荐

  1. sphinx索引分析——文件格式和字典是double array trie 检索树,索引存储 – 多路归并排序,文档id压缩 – Variable Byte Coding...

    1 概述 这是基于开源的sphinx全文检索引擎的架构代码分析,本篇主要描述index索引服务的分析.当前分析的版本 sphinx-2.0.4 2 index 功能 3 文件表 4 索引文件结构 4. ...

  2. Android用Double Array Trie (双数组)实现关键字的搜索

    我们项目本想用这种方法做Android的搜索提示用,也就是,在搜索框中输入一个关键字,下面自动检索出和输入的关键词匹配的关键字,提示用户,用户可以方便的从下面的提示中选择出自己想要的关键字.提高用户体 ...

  3. 双数组Trie树(DoubleArrayTrie)Java实现

    http://www.hankcs.com/program/java/%E5%8F%8C%E6%95%B0%E7%BB%84trie%E6%A0%91doublearraytriejava%E5%AE ...

  4. An Implementation of Double-Array Trie

    An Implementation of Double-Array Trie Contents What is Trie? What Does It Take to Implement a Trie? ...

  5. 双数组trie树的基本构造及简单优化

    一 基本构造 Trie树是搜索树的一种,来自英文单词"Retrieval"的简写,可以建立有效的数据检索组织结构,是中文匹配分词算法中词典的一种常见实现.它本质上是一个确定的有限状 ...

  6. B树,B+树,红黑树应用场景AVL树,红黑树,B树,B+树,Trie树

    B B+运用在file system database这类持续存储结构,同样能保持lon(n)的插入与查询,也需要额外的平衡调节.像mysql的数据库定义是可以指定B+ 索引还是hash索引. C++ ...

  7. 双数组Trie的一种实现

    An Implementation of Double-Array Trie 双数组Trie的一种实现 原文:http://linux.thai.net/~thep/datrie/datrie.htm ...

  8. Double_array trie

    An Implementation of Double-Array Trie Contents What is Trie? What Does It Take to Implement a Trie? ...

  9. 【基础知识】An Implementation of Double-Array Trie

    原文地址:http://linux.thai.net/~thep/datrie/datrie.html Contents What is Trie? What Does It Take to Impl ...

  10. Trie Tree 介绍

    概述 Trie树不同于通常的基于键比较的方法, 直接利用键的数字序列直接定位, 通常用于字符串匹配, 特别对公共前缀查找, 非常有效. 朴素的Trie树使用转移矩阵表示,简单易懂, 查找速度快(O(k ...

最新文章

  1. Linux(11)-Linux系统下用户权限管理
  2. JDBC oracle 错误总结
  3. Object Hook 简单介绍
  4. hive数据库numeric_hive支持sql大全(收藏版)
  5. 电大 计算机应用基础 专科 教材,2016年电大计算机应用基础(专科).doc
  6. python中sorted的用法append_Python中高阶函数sorted()用法
  7. cad在线转低版本_为什么别人制图那么快?41个CAD实用技巧,3天轻松玩转CAD
  8. 360修复导致服务器,桌面安装360软件修复漏洞补丁导致桌面TC端无法登陆,FC端VNC登陆一键修复显示HDC不可达...
  9. Linux (x86) Exploit 开发系列教程之十二 释放后使用
  10. 第一次立会(2019.3.24)
  11. Git提交时提示“Please make sure you have the correct access rights and the repository exists.”的解决方法
  12. python docs库_python库之_thread
  13. jekins 持续集成手记
  14. 深度学习(deep learning)优化调参细节(trick)
  15. 【数据库原理实验(openGauss)】完整性控制
  16. 电大计算机本科离散数学考试题,最新电大《离散数学》形考作业任务01-07网考试题及答案...
  17. 关于工业相机的基本知识
  18. CDN常见问题-Trouble Shooting(二)
  19. iOS UI切图@1x、@2x、@3x的实际尺寸
  20. Java内存模型(JMM)学习总结

热门文章

  1. AI永远不可能产生意识
  2. 代码管理学:域名、产品名、应用名等都不是你能决定的,要上报备案
  3. FreeSwitch会议Banner功能调用流程
  4. VirtualBox启动虚拟机出错VT-x disable
  5. shell脚本一行太长,使用\换行
  6. 怀念的不是初恋,是那段时光
  7. 如何正确获取安卓外置SD卡的路径
  8. 安卓双进程保活的代码
  9. python 读grid 数据_如何将TextGrid文件的变量读入Python?
  10. vs C# 强制结束进程