【问题标题】:Using threads to count all occurrences of a substring使用线程计算子字符串的所有出现次数
【发布时间】:2020-08-09 15:26:11
【问题描述】:

假设我有 t 个线程,计算字符串 S 中子字符串 T 的所有非重叠出现的最佳解决方案是什么?

这是一段正常计数的代码,但我不确定如何同时实现它。如果 t 小于子字符串的长度会怎样?

public class Substrings {
public int countOccurrences(String S, String T) {
  int count = 0, offset = 0, index;
  while((index = S.indexOf(T, offset)) != -1) {
    offset = index + T.length();
            count++;
  }
  return count;
}

}

【问题讨论】:

  • 当您想有效地计算所有不重叠的事件时,请使用int count = 0; Matcher m = Pattern.compile(T, Pattern.LITERAL).matcher(S); while(m.find()) count++; return count; 和正则表达式Pattern class,让它花时间进行准备。实际上,这意味着在内部使用Boyer–Moore algorithm,这可能比并行处理有更大的好处。

标签: java multithreading concurrency


【解决方案1】:

我不确定你为什么要这样做,因为这样的操作非常快,除非你有很多巨大的字符串。最佳解决方案不是我想考虑的,但是有一种简单的方法可以做到这一点,它的速度大约是最佳解决方案的两倍。将字符串拆分为多个部分,并使用线程在每个部分上运行 countOccurrences。将您找到的所有索引放入一个集合中。然后将这些部分向前滑动一段长度的一半,然后再做一次。第二部分将查找跨节的任何事件。当然,您可以通过两侧字符串的长度来限制第二次搜索,但这会使代码复杂化。作为一个练习,也许你可以用 Boyer-Moore 来做这个。

【讨论】:

  • 我不明白为什么您认为将部分滑动“部分长度的一半”将保证找到跨越旧部分边界的正确非重叠匹配项。此类匹配的潜在位置取决于搜索字符串长度和先前匹配的实际位置。此外,这样的部分边界交叉匹配可能与先前在下一部分中找到的匹配重叠,使其无效,这反过来又会使所有后续匹配无效。因此,只有在您可以提前反驳搜索字符串的重叠匹配时,拆分策略才有用。
  • 我明白你的意思。这有点棘手,不是吗?也许要做的事情是先解决更简单的问题,即先找到所有匹配项,然后通过查看索引和字符串长度来消除重叠匹配项?
  • 这将增加成本,甚至超过多线程所能弥补的。
猜你喜欢
  • 1970-01-01
  • 2020-02-21
  • 2012-02-12
  • 2020-06-02
  • 2014-07-03
  • 2014-05-19
  • 2015-12-01
相关资源
最近更新 更多