我试图找出一种方法来检测数字流中某些模式的重复发生。问题是 - 模式元素不一定是相邻的。
例如,采用以下流(这里的每个字母表示一个唯一的数字):
A C B D A E B F G A H B I A J B ...
明显的模式是A _ B
. 自然A
,B
它们本身也是模式,所以假设我们想要所有超过某个阈值长度的模式 - 在这种情况下为 2,或者所有不属于较长模式的模式 - 任何一个定义都对我有用。另请注意,它不会以任何固定速率重复出现(即 - 模式的 2 个实例可以通过任意数量的元素在它们之间间隔开)。您可能还会注意到 'B _ A' 和 'A _ B _ A _ B' 在这里也是重复出现的模式 - 这些也将作为输出受到欢迎。
顺便说一句,这正在简化事情,实际上我可以让 A 和 B 也出现在该模式之外,也许将来我想识别甚至A _ _ B
(或在某个阈值内的距离),但现在我' d 解决上述更简单的问题。
还有一个限制 - 可能的值没有限制,对此感到抱歉。这确实削弱了我能想到的大多数解决方案。然而,从好的方面来说,我对复杂性有点松懈,我会满足于几乎没有攻击性指数的任何事情(尽管我糟糕的计算机将不得不提供一个有效的解决方案:))
有两个想法来解决这个问题 -
保留值的“矩阵”,填充距离,识别重复出现的增量并标记它们。由于该区域是无界的,因此该矩阵必须是整个值空间的瓦片(从最低到最高可见值)。为了空间优化,我可能正在考虑多个矩阵,每个“组”值一个,并以另一种方式处理跨矩阵增量。
某种卷积/类似 FFT 的方法 - 将流的一部分与自身匹配并改变偏移量,看看一次有多少匹配。不过,我真的不明白我们怎么能适应这个。
如果有人有更好的方法来解决这个问题,知道现有的算法,怀疑问题无法解决,或者可以帮助我在建议的两个选项之间进行选择(或发现它们的问题),我将非常感激。如果对约束或示例不清楚 - 发表评论,我会添加它。
提前致谢!
编辑:添加基于后缀树的解决方案的选项。刚刚了解了 Ukkonen 的算法(Ukkonen's suffix tree algorithm in plain English?),试图确定它在这里是否有用......