查找在其他数组中重复的数组

Posted

技术标签:

【中文标题】查找在其他数组中重复的数组【英文标题】:Find array that is repeating in other array 【发布时间】:2022-01-21 00:13:42 【问题描述】:

假设数组 B 由数组 A 与自身连接 n 次而成 (例如:A=[1,2,3], n=3, B=[1,2,3,1,2,3,1,2,3]) 什么是通过给定 B(我们不知道 n)找到 A 的有效算法? UPD 我们搜索最小的 A(当 B=[1,2,1,2,1,2,1,2],A = [1,2],而不是 [1,2,1,2])

【问题讨论】:

【参考方案1】:

例如,假设 [1,2,1,2,1,2,1,2] 表示 n 是 4 而不是 2。换句话说,您假设最小的此类子列表 A。否则,可能会有多个解决方案。

    枚举B长度的唯一整数除数(包括1)。这些将是n 的唯一有效候选人。

    对于每个除数,从最小的开始,将其视为n的候选值:

    一个。获取 B 的第一个 len(B)/n 元素并开始检查它是​​否是通过 B 重复的子列表(我假设您可以找到一种有效的方法。如果您需要,我可以添加建议。)

    b.如果n 有效(你到达 B 的末尾并且所有内容都匹配),那么你就完成了,否则,尝试下一个除数

【讨论】:

感谢您的分析!在 2.a 中,只有 B[i] 和 B[i+k*n] 从 0 到 n 的索引比较(其中 k 是从 1 到 length(B)/n ),是对还是存在更有效的方式? 在 2.a 中你的意思是“取第一个 k=len(B)/n 个元素”? (所以我的回答也是从 0 到 k) @СергейМельников 是的,这就是净效应。编码步骤变得非常简单。如果您有 B 和候选 A,则从索引 0 开始,并按顺序比较每个元素。您不断将每个索引推进 1 比较元素,并在 A 索引达到最大值(A 的长度)时将其重置为 0。一旦你发现了差异,你就知道你需要去找下一个候选人 A。 @СергейМельников 我的意思是取 B 的第一个 n 元素。在我的描述中,n 是候选子列表 B 中的元素数。您的原始问题陈述将 n 定义为子列表的长度。 抱歉,现在才明白 [1,2,3]*3 是不好的例子,我的意思是 n 是重复次数(对于 [1,2,1,2,1,2 ,1,2] A=[1,2], n=4 是正确的解决方案)但似乎如果我们从最小除数开始,就会收到这个结果【参考方案2】:

您基本上可以在B 中找到最长的前缀,这也是一个后缀。您可以从KMP pattern matching算法中涉及的步骤推导出该表。

请注意,可能有多个正确的解决方案。(比如1,2,1,2,1,2,1,2 可以有A1,2,1,21,2

一旦找到,您将需要针对B 的切片重新运行匹配,以确保整个数组B 与重复模式匹配。这是必要的,因为可能存在诸如1,2,1,2,3,4,1,2,1,2 之类的极端情况,其中1,2,1,2 作为最长前缀,也是一个后缀,但它不是A 的连续重复。

如果获得的长度不能均匀地除以B 的长度,则每次都需要均匀地减小长度(如因子明智)以查看哪个匹配。 (示例:1,2,1,2,1,2)。

【讨论】:

感谢您的回答!忘了说我们只搜索 lurker 提到的最小的子列表:在这种情况下我们可以使用 KMP 吗? @СергейМельников 从技术上讲你可以,但它会涉及额外的步骤。您还可以使用我推测的 KMP 表中的值对长度进行二分搜索。

以上是关于查找在其他数组中重复的数组的主要内容,如果未能解决你的问题,请参考以下文章

使用 C# 在复杂的 JSON 数组中查找和打印重复项

查找和替换数组中的重复项

从数组中查找重复的 3D 顶点

查找数组中是不是存在字符串[重复]

关于如何去除数组中重复项

查找数组中重复的数字