python找最长的字符串_为Python找到最长重复字符串的有效方法(从Pearls编程)

我的解决方案是基于后缀数组。它是由最长公共前缀的两倍前缀构成的。最坏情况下的复杂度是O(n(logn)^2)。任务”伊利亚特.mb.txt“在我的笔记本上花了4秒钟。代码在函数suffix_array和longest_common_substring中有很好的文档记录。后一个函数很短,可以很容易地修改,例如搜索10个最长的非重叠子串。如果重复字符串长度超过10000个字符,则此Python代码比问题中的original C code (copy here)快。from itertools import groupby

from operator import itemgetter

def longest_common_substring(text):

"""Get the longest common substrings and their positions.

>>> longest_common_substring('banana')

{'ana': [1, 3]}

>>> text = "not so Agamemnon, who spoke fiercely to "

>>> sorted(longest_common_substring(text).items())

[(' s', [3, 21]), ('no', [0, 13]), ('o ', [5, 20, 38])]

This function can be easy modified for any criteria, e.g. for searching ten

longest non overlapping repeated substrings.

"""

sa, rsa, lcp = suffix_array(text)

maxlen = max(lcp)

result = {}

for i in range(1, len(text)):

if lcp[i] == maxlen:

j1, j2, h = sa[i - 1], sa[i], lcp[i]

assert text[j1:j1 + h] == text[j2:j2 + h]

substring = text[j1:j1 + h]

if not substring in result:

result[substring] = [j1]

result[substring].append(j2)

return dict((k, sorted(v)) for k, v in result.items())

def suffix_array(text, _step=16):

"""Analyze all common strings in the text.

Short substrings of the length _step a are first pre-sorted. The are the

results repeatedly merged so that the garanteed number of compared

characters bytes is doubled in every iteration until all substrings are

sorted exactly.

Arguments:

text: The text to be analyzed.

_step: Is only for optimization and testing. It is the optimal length

of substrings used for initial pre-sorting. The bigger value is

faster if there is enough memory. Memory requirements are

approximately (estimate for 32 bit Python 3.3):

len(text) * (29 + (_size + 20 if _size > 2 else 0)) + 1MB

Return value: (tuple)

(sa, rsa, lcp)

sa: Suffix array for i in range(1, size):

assert text[sa[i-1]:] < text[sa[i]:]

rsa: Reverse suffix array for i in range(size):

assert rsa[sa[i]] == i

lcp: Longest common prefix for i in range(1, size):

assert text[sa[i-1]:sa[i-1]+lcp[i]] == text[sa[i]:sa[i]+lcp[i]]

if sa[i-1] + lcp[i] < len(text):

assert text[sa[i-1] + lcp[i]] < text[sa[i] + lcp[i]]

>>> suffix_array(text='banana')

([5, 3, 1, 0, 4, 2], [3, 2, 5, 1, 4, 0], [0, 1, 3, 0, 0, 2])

Explanation: 'a' < 'ana' < 'anana' < 'banana' < 'na' < 'nana'

The Longest Common String is 'ana': lcp[2] == 3 == len('ana')

It is between tx[sa[1]:] == 'ana' < 'anana' == tx[sa[2]:]

"""

tx = text

size = len(tx)

step = min(max(_step, 1), len(tx))

sa = list(range(len(tx)))

sa.sort(key=lambda i: tx[i:i + step])

grpstart = size * [False] + [True] # a boolean map for iteration speedup.

# It helps to skip yet resolved values. The last value True is a sentinel.

rsa = size * [None]

stgrp, igrp = '', 0

for i, pos in enumerate(sa):

st = tx[pos:pos + step]

if st != stgrp:

grpstart[igrp] = (igrp < i - 1)

stgrp = st

igrp = i

rsa[pos] = igrp

sa[i] = pos

grpstart[igrp] = (igrp < size - 1 or size == 0)

while grpstart.index(True) < size:

# assert step <= size

nextgr = grpstart.index(True)

while nextgr < size:

igrp = nextgr

nextgr = grpstart.index(True, igrp + 1)

glist = []

for ig in range(igrp, nextgr):

pos = sa[ig]

if rsa[pos] != igrp:

break

newgr = rsa[pos + step] if pos + step < size else -1

glist.append((newgr, pos))

glist.sort()

for ig, g in groupby(glist, key=itemgetter(0)):

g = [x[1] for x in g]

sa[igrp:igrp + len(g)] = g

grpstart[igrp] = (len(g) > 1)

for pos in g:

rsa[pos] = igrp

igrp += len(g)

step *= 2

del grpstart

# create LCP array

lcp = size * [None]

h = 0

for i in range(size):

if rsa[i] > 0:

j = sa[rsa[i] - 1]

while i != size - h and j != size - h and tx[i + h] == tx[j + h]:

h += 1

lcp[rsa[i]] = h

if h > 0:

h -= 1

if size > 0:

lcp[0] = 0

return sa, rsa, lcp

与more complicated O(n log n)相比,我更喜欢这种解决方案,因为Python具有非常快速的列表排序(列表.排序),可能比文章中的方法中必要的线性时间操作快,在非常特殊的随机字符串和一个小字母表(典型的DNA基因组分析)假设下,应该是O(n)。我在Gog 2011中读到,我的算法中最糟糕的情况O(n logn)在实践中可以比许多O(n)算法更快,即不能使用CPU内存缓存。

如果文本包含8kb长的重复字符串,基于grow_chains的另一个答案中的代码比问题的原始示例慢19倍。长时间重复的文本不是古典文学的典型,但它们经常出现在“独立”学校的家庭作品集中。程序不应该冻结它。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/446095.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux加密框架 crypto 算法模板 CBC模板举例

参考链接 Linux加密框架中的主要数据结构&#xff08;三&#xff09;_家有一希的博客-CSDN博客https://blog.csdn.net/CHYabc123456hh/article/details/122194754 CBC算法模板 cbc.c - crypto/cbc.c - Linux source code (v5.15.11) - BootlinCBC算法模板属性 1)CBC算法模板名…

leetcode数组汇总_LeetCode刷题实战43:字符串相乘

算法的重要性&#xff0c;我就不多说了吧&#xff0c;想去大厂&#xff0c;就必须要经过基础知识和业务逻辑面试算法面试。所以&#xff0c;为了提高大家的算法能力&#xff0c;这个公众号后续每天带大家做一道算法题&#xff0c;题目就从LeetCode上面选 &#xff01;今天和大家…

Linux加密框架 crypto 算法模板 HMAC模板举例

参考链接 Linux加密框架中的主要数据结构&#xff08;三&#xff09;_家有一希的博客-CSDN博客Linux加密框架 crypto 算法模板_CHYabc123456hh的博客-CSDN博客 HMAC算法模板 hmac.c - crypto/hmac.c - Linux source code (v5.15.11) - Bootlinhmac.c - crypto/hmac.c - Linux…

判断非负整数是否是3的倍数_五年级数学因数与倍数知识点汇总与解题方法技巧...

在日常教学过程中&#xff0c;我发现孩子们和某些家长对学习数学的方法有一些误区&#xff0c;就是觉着数学&#xff0c;单纯就是逻辑思维&#xff0c;只要多做练习题就能学好&#xff0c;但是不是这样的&#xff0c;低年级的学生&#xff0c;学习数学还是以背诵为主&#xff0…

tcp通讯一次最多能发送多少数据?_关于TCP/IP,必须知道的十个知识点

本文整理了一些TCP/IP协议簇中需要必知必会的十大问题&#xff0c;既是面试高频问题&#xff0c;又是程序员必备基础素养。一、TCP/IP模型TCP/IP协议模型&#xff08;Transmission Control Protocol/Internet Protocol&#xff09;&#xff0c;包含了一系列构成互联网基础的网络…

Linux内核crypto子系统的调用逻辑

testmgr.c - crypto/testmgr.c - Linux source code (v5.15.11) - Bootlin上述代码是内核内部即crypto子系统对外提供密码服务的测试程序调用流程&#xff1a;crypto API <—> crypto core <—> crypto_register_alg处于用户态的程序想要调用处于内核态的密码算法&…

python成语填空_python定期循环成语?

我有一个工作单位我希望每N秒发生一次.如果我使用简单化minute 60while True:doSomeWork()time.sleep(minute)取决于doSomeWork()花费的时间,实际循环周期将是一分钟加上那个时间.如果doSomeWork()所花费的时间不是确定性的,则工作周期更加难以预测.我想做的就是这样minute 6…

Linux加密框架 crypto算法模板 以及CBC算法模板实例

参考链接 Linux加密框架中的主要数据结构&#xff08;四&#xff09;_家有一希的博客-CSDN博客algapi.h - include/crypto/algapi.h - Linux source code (v5.15.11) - Bootlin struct crypto_instance {struct crypto_alg alg;struct crypto_template *tmpl;union {/* Node i…

tomcat temp 大量 upload 文件_渗透测试之文件上传漏洞总结

文末下载上传环境源码客户端js检查一般都是在网页上写一段javascript脚本&#xff0c;校验上传文件的后缀名&#xff0c;有白名单形式也有黑名单形式。查看源代码可以看到有如下代码对上传文件类型进行了限制&#xff1a;我们可以看到对上传文件类型进行了限制。绕过方法1.我们…

Linux加密框架 crypto算法模板 以及HMAC算法模板实例

HMAC算法模板实例 HMAC算法模板的创建实例的接口是hmac_create函数hmac.c - crypto/hmac.c - Linux source code (v5.15.11) - Bootlin hmac_create输入的参数包括 算法模板 tmpl 和 算法模板实例参数 tbhmac_cretae函数返回的结果为0表示算法模板实例已经创建注册算法模…

python判断密码强度并输出_密码强度判断

[python]代码库def pdsz(cd):nnnn Falsefor c in cd:if c.isnumeric():nnnn Truebreakreturn nnnndef pdzm(cd):nnnn Falsefor c in cd:if c.isupper():nnnn Truebreakreturn nnnndef pdhh(cd):nnnn Falsefor c in cd:if c.islower():nnnn Truebreakreturn nnnndef main(…

linux加密框架 crypto 算法crypto_register_alg的注册流程

算法注册流程 静态算法模块初始化 分组算法模块初始化 AES算法模块&#xff08;aes_generic.c&#xff09;的初始化接口aes_init实现向加密框架注册AES算法的功能&#xff0c;如下所示。aes_generic.c - crypto/aes_generic.c - Linux source code (v5.15.12) - Bootlin sta…

python 方法的实例_python调用自定义函数的实例操作

在python中&#xff0c;想要调用自定义函数必须先声明&#xff0c;然后才能调用。使用函数时&#xff0c;只要按照函数定义的形式&#xff0c;向函数传递必需的参数&#xff0c;就可以调用函数完成相应的功能或者获得函数返回的处理结果。(1)声明函数python中使用 def 可以声明…

linux加密框架 crypto 静态哈希算法crypto_register_shash注册流程

参考链接 Linux加密框架的算法管理&#xff08;一&#xff09;_家有一希的博客-CSDN博客_linux加密框架设计与实现shash.c - crypto/shash.c - Linux source code (v5.15.12) - Bootlin 函数介绍 crypto_register_shash函数实现向加密框架注册静态哈希算法的功能&#xff0c;…

多个线程访问统一对象的不同方法_C#多线程读写同一文件处理

在多线程访问读写同一个文件时&#xff0c;经常遇到异常&#xff1a;“文件正在由另一进程使用&#xff0c;因此该进程无法访问此文件”。多线程访问统一资源的异常&#xff0c;解决方案1&#xff0c;保证读写操作单线程执行&#xff0c;可以使用lock解决方案2&#xff0c;使用…

linux加密框架 crypto 通用算法注册接口__crypto_register_alg注册流程

函数介绍 __crypto_register_alg函数实现向加密框架注册算法&#xff08;包括静态算法和动态算法&#xff09;的功能&#xff0c;输入参数为算法说明alg&#xff0c;注册成功时返回算法注册用的算法幼虫larval&#xff0c;注册失败时返回失败原因。__crypto_register_alg函数执…

spark官方文档_Spark整合Ray思路漫谈

什么是Ray之前花了大概两到三天把Ray相关的论文&#xff0c;官网文档看了一遍&#xff0c;同时特意去找了一些中文资料看Ray当前在国内的发展情况(以及目前国内大部分人对Ray的认知程度)。先来简单介绍下我对Ray的认知。首先基因很重要&#xff0c;所以我们先需要探查下Ray最初…

python用http协议传数据_python基础 -- 简单实现HTTP协议

标签&#xff1a;一、直接代码# -*- coding: utf-8 -*-import socket__author__ ‘lpe234‘__date__ ‘2015-03-12‘if __name__ ‘__main__‘:sock socket.socket(socket.AF_INET, socket.SOCK_STREAM)sock.bind((‘127.0.0.1‘, 8001))sock.listen(5)while True:connecti…

linux加密框架 crypto 算法管理 - 算法查找接口 crypto_find_alg

算法查找接口crypto_find_alg 算法实例tfm是算法的一个可运行的副本&#xff0c;因此在创建算法实例前首先要查找确认算法是否已经注册有效&#xff0c;此时算法查找由函数crypto_find_alg实现。补充&#xff1a; struct crypto_tfm *tfm; crypto_tfm类型指针tfm可以理解为指代…

linux加密框架 crypto 算法管理 - 算法查找接口 crypto_alg_mod_lookup

参考链接 Linux加密框架的算法管理&#xff08;二&#xff09;_家有一希的博客-CSDN博客linux加密框架 crypto 算法管理 - 算法查找接口 crypto_find_alg_CHYabc123456hh的博客-CSDN博客 函数介绍 crypto_alg_mod_lookup函数输入参数包括待查找的算法名name、算法类型type和算…