代码改变世界

字符串匹配处理

2016-06-20 10:02  halberts  阅读(383)  评论(0编辑  收藏  举报

我先抛砖引玉写几个topic,然后我会指定你们中的一些领域专家分享自己的知识,当然也欢迎你们毛遂自荐。

  1. 将一个string转换为int

这是我以前爱用的面试题,即使不考虑科学计数法和其它进制,短时间写出正确程序仍然不易(需要考虑溢出)

  1. 字符串左旋:比如abcde向左旋转三位变成deabc
  2. 假设客户端和服务器之间的通信是不安全的(传递的所有数据都可能被非法获得,对称加密算法可能被破解)

设计安全机制,在服务正常用户的同时,拒绝非法访问

  1. 随机生成m个整数,要求

a)         每个数出现的概率均等

b)         它们在1到n之间

c)         它们各不相同

d)         效率较高

  1. 给定一个包含n 个整数的数组,找出其中出现超过一次的数

这5道题如果你能不借助任何外力,做出4道,请来找我。

进入正题:

字符串处理在工作中经常遇到,最有名的算法就是kmp。但是,它有几个缺点:

1. 只能单字符串;

2. 需要预处理;

3. 其实,它的速度不是最快的……出名只是因为在教材中;

4. 不能处理最长公共子串等其它非匹配问题。

 

事实上,字符串处理博大精深:

  1. 单字符串匹配

在长度为n的匹配串中查找长度为m的模式串是否出现,以及出现的位置

a)         Brute Force

从左到右一个字符一个字符比较

时间复杂度O(n*m)

b)         KMP

最有名的算法,教科书中,作者之一(K)是图灵奖得主

核心思想是,充分利用m的特性,匹配失败时,尽可能多地移动模式串,以减少比较次数

时间复杂度O(n)

http://jpkc.nwu.edu.cn/datastr/study_online/newsite/pluspage/kmp.htm

c)         Horspool

从右到左比较

当匹配失败时,模式串从不匹配字符处向左寻找匹配串中不匹配的字符,若找到取最靠右的那个,移动模式串对齐;若找不到,移动模式串到不匹配字符处右方

时间复杂度平均O(n),最坏O(n*m)

http://www.cnblogs.com/dsky/archive/2012/04/24/2467655.html

d)         BM

这个算法的实际效果比KMP快数倍;是逻辑上最复杂的算法

相当于KMP和Horspool的结合

时间复杂度O(n)

http://blog.csdn.net/iJuliet/article/details/4200771

e)         Sunday

这是我个人最喜欢的算法,比BM快,同时很简洁

其它和Horspool类似,只是比较的不是不匹配的字符,而是匹配串中下一位字符

http://baike.baidu.com/view/6325831.htm?fr=aladdin

f)          Rabin-Karp

以串而不是字符为单位,串映射为值;值一样再继续比较

http://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm

  1. 多字符串匹配

在很多匹配串(字典)中查找长度为m的模式串

a)         Trie

我个人比较喜欢的一种算法,广泛应用于tips(搜索提示)、禁词过滤等

http://zh.wikipedia.org/zh/Trie

b)         Aho–Corasick

有限状态自动机+KMP

http://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_string_matching_algorithm

  1. 后缀数组

后缀数组是字符处理的利器,广泛应用于求最长前缀、最长公共子串、最长递增子串、最长回文子串和最长重复子串等。

如果参加ACM,此技能必须掌握。

http://baike.baidu.com/view/1240197.htm?fr=aladdin

http://wenku.baidu.com/link?url=Qho60zwH165gwPqq0Eubjvv7k9d0uv9J8NX8tzUi5B7Fechm0LJtS3JPJN8syCLfoXdWjhEi71SVYe661idevKMqnOX_X-akYhXq59e5GLS