我试图想出一个GNU扩展正则表达式,它检测一串ascii编码位中的重复子串。我有一个有效的表达式。问题是,当给出一个可能有很多解决方案的字符串时,它会执行非常慢
表达式
([01] +)(\ 1)+
快速编译,但需要大约一分钟来执行字符串
1010101010101010101010101010101010101010101010101010101010
我正在使用glibc 2.5-49(附带CentOS 5.5)的正则表达式实现。
FWIW,pcre库快速执行,如gregexp或perl直接执行。所以明显但错误的答案是“使用libpcre”。我不能轻易地在我的项目中引入新的依赖项。我需要在CentOS / RHEL附带的std C库中工作。
答案 0 :(得分:3)
如果输入字符串可以是相当长的,或者性能完全是一个问题,那么解决这个问题的一个更好的方法不是使用正则表达式,而是使用更复杂的字符串数据结构来促进这些类型查询更有效率。
这样的数据结构是suffix tree。给定字符串S
,其后缀树基本上是其所有后缀的Patricia trie。尽管看似复杂,但它可以在线性时间内构建。
"BANANA"
的后缀树(由维基百科提供)
您可以使用后缀树真正有效地执行多种查询,例如:找到子串的所有出现,最长的子串至少出现两次,等等。你所追求的字符串类型称为tandem repeats。为了便于此查询,您必须在线性时间内预处理后缀树,以便您可以在固定时间内进行lowest common ancestor次查询。
这个问题在计算生物学中很常见,其中DNA可以被视为由ACGT
中的字母组成的非常长字符串。因此,性能和效率至关重要,并且设计了这些非常复杂的算法和技术。
你应该研究从头开始为你的二进制序列实现这些技术,或者更容易将二进制序列映射到“假的”DNA字符串,然后使用许多可用于基因研究的工具之一。