【问题标题】:Finding a string inside a string twice as big effectively有效地在两倍大的字符串中查找字符串
【发布时间】:2023-03-28 10:37:01
【问题描述】:

我正在查看数组中每个相邻数字之间的差异是否与另一个数组相同,或者它的旋转,例如

A = {1,2,4}, so the differences are {1,1,2}
B = {4,6,7}, the differences are {1,2,1}

如果{1,2,1}中的所有元素都顺时针移动一个元素,结果是{1,1,2},这是正确的。

到目前为止,我将差异转换为字符串,然后查看是否在与自身连接的第一个数组中找到第二个数组的差异

valid if "1 2 1" is in "1 1 2 1 1 2"

到目前为止,我的代码如下所示 count 是数组的长度,两者长度相同

    int c = count - 1;
    StringBuilder b1 = new StringBuilder();
    StringBuilder b2 = new StringBuilder();
    for (int i = 0; i < c; i++) {
        b1.append(array1[i + 1] - array1[i]);
        b1.append(" ");
        b2.append(array2[i + 1] - array2[i]);
        b2.append(" ");
    }
    b1.append((array1[0] - array1[c]) + d);
    b1.append(" ");
    b2.append((array2[0] - array2[c]) + d);

    String a2 = b2.toString();
    String a3 = b1.toString() + b1.toString();

    System.out.println(a3.contains(a2) ? "valid" : "not valid"); //bottleneck here

我的问题是当我使用大数组(最多大约 250,000 个元素)时,我在 .contains() 的最后一行遇到了巨大的瓶颈。我想知道是否有比我正在使用的方法更快的方法来检查它是否在方法内部,或者我是否可以在构建字符串时进行检查,或者是否有完全不同的方法?

【问题讨论】:

  • "rotate shift {1,2,1}...." 是一个不正确的陈述 - 你想这样表达 - “如果我将元素顺时针移动一个位置”。轮换是一种非常不同的野兽。编辑了帖子。
  • “字符串中的字符串”也称为 String-ception。
  • 您是否尝试使用Short 代替字符串?原因是您的数组中似乎只有一位数字 - 所以您可能可以处理 Short 而不是转换为字符串?我想您尝试使用Integer 并且由于如此大的数组大小而已经失败?可能是Short 会有所作为。此外,您可能可以使用ArrayList&lt;&gt; 使用索引来保存其中的差异。然后你就可以按顺序取出它们了。
  • 数字可能在 0 到 50 万之间

标签: java arrays search


【解决方案1】:

您需要一种比 contains 方法中使用的算法更有效的算法(它实际上取决于具体的实现,但在您使用的 Java 版本中看起来效率不高)。
您可以使用 Knuth-Morris-Pratt 算法:http://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm。它在最坏的情况下具有线性时间和空间复杂性,因此即使对于非常大的阵列也能快速工作。请注意,不需要将数组转换为字符串,因为该算法也适用于数组。

【讨论】:

  • 谢谢,我会进一步研究,我尝试实现伪代码,但当我尝试使用数组时无法得到正确答案
猜你喜欢
  • 1970-01-01
  • 2014-10-31
  • 2019-02-17
  • 2017-01-14
  • 2023-03-19
  • 1970-01-01
  • 2019-07-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多