Python 搜索长的连续重复子字符串
我有一串0和1。将“连续双精度”定义为立即重复自身的子字符串。例如,字符串“0111010101110”可以分解为“0111010101110”,可以压缩为“011(1010)1110” 是否有一个好的算法来查找字符串中所有连续的双精度?我能想到的最好的方法是关于字符串长度的二次方:Python 搜索长的连续重复子字符串,python,algorithm,substring,Python,Algorithm,Substring,我有一串0和1。将“连续双精度”定义为立即重复自身的子字符串。例如,字符串“0111010101110”可以分解为“0111010101110”,可以压缩为“011(1010)1110” 是否有一个好的算法来查找字符串中所有连续的双精度?我能想到的最好的方法是关于字符串长度的二次方: def all_contiguous_doubles(s): for j in range(len(s)): for i in range(j): if s[i:j]
def all_contiguous_doubles(s):
for j in range(len(s)):
for i in range(j):
if s[i:j] == s[j:2*j - i]:
print "%s(%s)%s" % (s[:i], s[i:j], s[2*j - i:])
我会使用regex jan提到的
/(.+)$1/
下面是一个简单的算法,否则可能会起作用:
创建一个函数
get_largest(string, i, j)
返回i和j之间最大的双精度
我将使用最小(20,(j-I)//2)的散列大小
现在假设您的hash_大小为20,查找长度为20的最不频繁的子字符串以及它出现的所有位置。(这可以通过哈希表快速完成)
现在让我们假设它被发现的位置是[10,110,320,500,…]
看看字符串[10:110],字符串[110320],字符串[320500]。。等
如果这些子字符串中的任何一个子字符串多次出现,请找到这些子字符串的所有位置,并使用上面的技术或其修改版本检查是否存在双精度
如果您仍然没有找到包含长度为20的最不频繁子字符串的双精度,我们现在可以递归地进行分治以搜索所有不包含最不频繁子字符串的最长子字符串
希望在大多数情况下这应该很快。我会使用regex jan提到的
/(.+)$1/
下面是一个简单的算法,否则可能会起作用:
创建一个函数
get_largest(string, i, j)
返回i和j之间最大的双精度
我将使用最小(20,(j-I)//2)的散列大小
现在假设您的hash_大小为20,查找长度为20的最不频繁的子字符串以及它出现的所有位置。(这可以通过哈希表快速完成)
现在让我们假设它被发现的位置是[10,110,320,500,…]
看看字符串[10:110],字符串[110320],字符串[320500]。。等
如果这些子字符串中的任何一个子字符串多次出现,请找到这些子字符串的所有位置,并使用上面的技术或其修改版本检查是否存在双精度
如果您仍然没有找到包含长度为20的最不频繁子字符串的双精度,我们现在可以递归地进行分治以搜索所有不包含最不频繁子字符串的最长子字符串
希望在大多数情况下,这应该是快速的。这里我介绍了我的动态规划解决方案,它的时间复杂度为O(n^2)和 O(n^2)的空间复杂度,其中n是原始字符串的长度 下面我递归地定义函数dl(r,c)。 如果您将dl(r,c)作为一个表,并按照正确的顺序填写,您将在O(n^2)中完成它 定义: 字符(i)=位置i处的字符 substr(i)=从位置i开始到原始字符串末尾的子字符串 dl(r,c)=substr(r)和substr(c)的公共、非重叠前缀的长度 dl(r,c)的递归定义:
对于十六进制字符串中的字母:检查前一个或当前字母是否为“灰色代码”顺序中的对应字母。如果是这样,您可以进一步压缩它。(不同的位也可以在中间-有些情况必须正确处理)< P>如果压缩实际上是你的最终目标: 为什么不创建一个大小为16的查找表,将字符串“0000”、“0001”、“1010”等映射到它们各自的十六进制数“0-F” 存储表示时:将二进制字符串转换为十六进制字符串序列 您可能还想在上查找。其中,在二进制序列中,前一个数字和当前正好相差1位 如果表中的灰色代码表示为0-F,则:
对于十六进制字符串中的字母:检查前一个或当前字母是否为“灰色代码”顺序中的对应字母。如果是这样,您可以进一步压缩它。(不同的位也可以在中间-有些情况必须正确处理)可以有二次方的许多双倍。考虑字符串“111…111”,在任何类型的字符串搜索中避免二次行为的方法是跳过前缀。但这在只有两个字符值的字符串中不太有用,因此这可能是一个不好的折衷。每四位字符串至少包含一个双精度,因此,在任意长度的n个零和1字符串中,总是至少有
n/4
个双精度。您可以让正则表达式引擎在某个位置为您找到最长的双精度起点:/(.+)$1/
@wye。