python 字符串处理算法总结

2019-03-26  本文已影响0人  知子不由

  应届生找工作的时候,第一轮笔试中,必然是有一个字符串的算法题。字符串处理是算法领域里非常重要的东西,有些是关于文字处理,有些关于子字符串处理,这一章对常见常用的字符串算法题进行了分析总结。

1.1 易位构词

def anagrams(w):
    w = list(set(w.split()))                     #分割删除重复项
    d = {}
    for i in range (len(w)):                    #相同标签的单词序号保存在一起
        s = "".join(sorted(w[i]))
        if s in d:
            d[s].append(i)
        else:
            d[s] = [i]
    reponse = []
    for s in d:                                  #输出易位单词
        if len(d[s]) > 1:
            reponse.append([w[i] for i in d[s]])
    return reponse

1.2 KMP算法

  KMP算法可以说是一个很经典的算法,我们在日常编程中也经常会用到,KMP算法用来解决一系列字符串单模式匹配问题以及延伸出来的最大边KMP算法等等。

def kmp(s,p):
    len_s = len(s)
    len_p = len(p)
    next = [0] * len_p
    next[0] = -1
    k = -1
    j = 0
    while j < len_p-1:                         
        if k == -1 or p[j] == p[k]:
            j += 1
            k += 1
            next[j] = k
        else:
            k = next[k]
    i = 0
    j = 0
    while i < len_s and j < len_p:
        if j == -1 or s[i] == p[j]:
            i += 1
            j += 1
        else:
            j = next[j]
    if j == len_p:
        return i - j
    else:
        return -1

模式匹配算法除了KMP算法之外,还有Rabin-Karp算法,有时间的话会加上Rabin-Karp算法,Rabin-Karp算法时间复杂度一般也为 O(n) 。

1.3 回文字符: Manacher 算法

  manacher算法,我们习惯叫他 “马拉车”算法。
  Manacher算法的应用范围比较狭窄,但是它的思想和拓展kmp算法有很多共通之处,所以在这里介绍一下。Manacher算法是查找一个字符串的最长回文子串的线性算法。
  首先介绍一下什么是回文串,所谓回文串,简单来说就是正着读和反着读都是一样的字符串,比如abba,noon等等,一个字符串的最长回文子串即为这个字符串的子串中,是回文串的最长的那个。
  计算字符串的最长回文字串最简单的算法就是枚举该字符串的每一个子串,并且判断这个子串是否为回文串,这个算法的时间复杂度为O(n3)的,显然无法令人满意,稍微优化的一个算法是枚举回文串的中点,这里要分为两种情况,一种是回文串长度是奇数的情况,另一种是回文串长度是偶数的情况,枚举中点再判断是否是回文串,这样能把算法的时间复杂度降为O(n2),但是当n比较大的时候仍然无法令人满意,Manacher算法可以在线性时间复杂度内求出一个字符串的最长回文字串。

def manachers(s):
    if s == "":
        return (0,1)
    t = "^#" + "#".join(s) + "#$"
    id_cent = 0
    mx = 0
    p = [0] * len(t)
    for i in range(1,len(t)-1):
        mirror = 2 * id_cent -i
        p[i] = max(0, min(p[mirror],mx-i))
        while t[i + 1 + p[i]] == t[i - 1 - p[i]]:
            p[i] += 1
        if i + p[i] > mx:
            mx,id_cent, = i + p[i],i                           
    (k,i) = (max(p),p.index(max(p)))
    return (s[(i-k) // 2 :(i+k) //2])

1.4小结

  字符串的处理我只记录了这三种,相对来说马拉车算法比较难理解。其他形式字符串的处理基本都是基于这些进行变化,比如:最长字串,最长公共字串等等。后续如果有时间,会继续在本文中更新Rabin-Karp算法。碰到有意思的字符串算法题也会继续更新。

上一篇 下一篇

猜你喜欢

热点阅读