查找字符串
字符串查找算法在于其效率的高低,单个字符的一次比较从头到尾遍历一遍肯定能找出来,但这样效率太低。
比较著名的算法有KMP和BM(KMP看着烦躁),但个人来说,Sunday算法是我最能理解且效率不错的算法(而且代码很简单啊)。
sunday算法关注的是模式串的下一个字符的匹配情况(因为字符串不匹配的话,模式串至少会移动一位),不等则跳过,相等则移动;
现举个例子来说明:
比如:
匹配串:O U R S T R O N G X S E A R C H
模式串:S E A R C H
这里我们看到O-S不相同,我们就看匹配串中的O在模式串的位置,没有出现在模式串中。
匹配串:O U R S T R O N G X S E A R C H
模式串: ____________S E A R C H
移动模式串,使模式串的首字符和O的下一个字符对齐。
匹配串:O U R S T R O N G X S E A R C H
模式串:____________S E A R C H
继续比较,N-S不相同,字符R出现在模式串,则后移模式串,将把它们对齐
匹配串:O U R S T R O N G X S E A R C H
模式串: _ _ _ _ _ _ _ _ _ _ _S E A R C H
===========================================================================
下面实现的代码:已测试
char* str_find(char* str_s, char* str_t){ char* p_s = str_s; while(*p_s){ int count=0; char* p_t = str_t; while( !strncmp(p_t,p_s,1) && *p_t){ //依次比较每个字符,只到不相等或比较到模式串末尾 ++p_t;++p_s } if(!(*p_t)) return p_t-strlen(str_t); p_s = p_s +strlen(srt_t); for(count=0,p_t=str_t; *p_t && strncmp(p_t,p_s,1)!=0; ++p_t,++count){} //查找下一个字符在模式串中有没有出现,首次出现便退出循环 if(!(*p_t)) ++p_s; //如果是查找到字符串末尾退出循环的话,说明没找到,p_s下移一个字符; else p_s = p_s - count; //查找到的话,将匹配串与模式串重新对齐 } if(!*p_s) //匹配串查到末尾仍未找到模式串的情况 return p_s; }
上面代码返回的是第一次匹配的地址,如果要实现像文本编辑器那样全部查找且上下翻动的话,可以将查找到的地址存入环链表中, return p_t-strlen(str_t) 改为 p_t写入; continue;