在网上对于字符串处理的相关介绍很多,这也是各大公司常考的题型,主要是因为在信息处理中,字符串是最常见的结构,这样,字符串作为一种数据结构类型出现在越来越多的程序设计语言中,同时出现了相关的处理字符串的库;如<string.h>,MFC封装的string类CString,以及现在比较流行的BOOST库中的字符串处理算法等等。所以从基本的知识开始,逐步了解基本的字符串操作,也是自己最近对字符串知识了解的总结和备忘。
在本文中通过系统介绍字符串存储结构;字符串处理函数;字符串模式匹配算法。相应的给出代码实现。
字符串处理函数相关资源参考网站:(PS:相应的代码归其作者所有,使用请声明!)
字符串模式匹配算法相关资源参考网站:(PS:相应的代码归其作者所有,使用请声明!)
http://sundful.iteye.com/blog/263847 (KMP详细讲解!)
http://blog.csdn.net/v_july_v/article/details/6545192 (讲解详细!)
http://www.searchtb.com/2011/07/%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%8C%B9%E9%85%8D%E9%82%A3%E4%BA%9B%E4%BA%8B%EF%BC%88%E4%B8%80%EF%BC%89.html
(简洁明了!)
一.字符串结构:
在严蔚敏数据结构书中,将其结构分为:1.定长顺序存储。2.堆分配存储。3.块链存储。4.字典树存储结构(如:键树,Trie树),树结构存储字符串,主要用于错误单词的处理,这里不做介绍。
二.字符串常规处理函数:(主要是<string.h>中相关函数的实现)
这个的话可以参看string.h中的源码实现。像strstr,strlen,strcpy,strcmp,strcat,以及字符倒置,字符串前(后)移,(或者将这些操作结合一起考察)等基本的字符串操作函数各大公司招聘笔试面试常考的题。其中代码实现见参考连接。其他的操作在平时积累中再添加相应的字符串操作~!
(PS:如果有时间将其用类来封装实现之,待code~~~)
三.字符串模式匹配算法: (KMP算法的实现原理参考严蔚敏版本)
1.KMP算法:(时间复杂度:最好O(n/m), 最坏O(n+m))
模式串与文本串匹配:1.主串无需回溯,而模式串定位到next[j]与s[i]比较继续进行;2.主串与模式串第一个字符匹配,则主串前进下个字符s[i+1]与模式串开始位置继续进行比较匹配。这里关键是next函数的实现。
关于next函数的理论推导:
1.在主串P和模式串S进行匹配时,存在S[i] != P[j]时,则前面字符串满足:P[0...j-1] = S[i-j...i-1]。
2.假设模式串中存在第k+1个字符及P[k]与S[i]正在比较,则前面字符串满足: P[0...k-1] =S[i-k...i-1]。
3.又因为P[j-k...j-1] = S[i-k...i-1], 所以结合上面的条件,推出:P[0...k-1] = P[j-k...j-1]。
于是乎将next函数定义为:(具体推导过程见严蔚敏数据结构书中的介绍P81,很详细~!这里只简单总结备忘)
-1, 当j=0时
next[j] = Max{k|0<k<j,且P[0...k-1]=P[j-k...j-1]} 当此集合不为空时。
0, 其他情况
next函数的实现参考严蔚敏数据结构书中的介绍P83,是一个递推的推导过程(备忘)
KMP算法最大的特点是指示主主串的指针不需要回溯,整个匹配过程中,对主串仅需要从头到尾扫描一遍,这对处理从外设输入的庞大文件很有效,可以边读入边匹配,而无需回头重读。
2.BM算法:(时间复杂度:最好O(n/(m+1)), 最坏O(n*m)?)
后缀匹配,是指模式串的比较从右到左,模式串的移动也是从左到右的匹配过程,经典的BM算法其实是对后缀蛮力匹配算法的改进。为了实现更快移动模式串,BM算法定义了两个规则,坏字符规则和最好后缀规则,分别得到坏字符表和最好后缀表。利用好后缀和坏字符可以大大加快模式串的移动距离。
BM算法则综合坏字符表和最好后缀表,模式串定位位到母串给定位置,移动的最大值。
字符串模式匹配算法实现代码:(代码归其作者所有,使用请声明~!)