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.pswp.cn/news/446095.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/446095.shtml
英文地址,請注明出處:http://en.pswp.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和算…