【问题标题】:Fastest method for determining all substrings of existing string确定现有字符串的所有子字符串的最快方法
【发布时间】:2012-03-20 17:25:12
【问题描述】:

假设我有字符串"Hey"。我想尽可能 fast 确定此字符串中存在的所有字符组合。生成的算法应该生成这个:

H, e, y, He, ey, Hey

算法应该产生字符串"Hy",因为它作为子字符串存在于字符串中。

【问题讨论】:

  • 为什么一定要快?一个简单的双循环解决方案对我来说似乎足够快......
  • HeyHeyHey 的答案是什么?它会有 3 个“嘿”还是只有一个?
  • @wildplasser:从算法的角度来看,您提出的方案似乎是最快的解决方案。
  • 那么你有什么尝试?您需要多少优化?你需要一个吗?在什么环境下尽可能快,有些语言比其他语言做得更好......
  • 我知道,但我不想破坏他的作业!

标签: php string algorithm permutation combinations


【解决方案1】:

这些子字符串中有O(n^2),长度为[1,n],因此任何生成所有子字符串的算法都将是O(n^2) * O(n) = O(n^3)

(*) 见最后的 Edit2 - 取决于字符串的实现 - 复杂性可能从 O(n^2)O(n^3) 不等

伪代码:

result <- {} #result is a set if dupes should be terminated, otherwise - it is a multiset.
for i from 0 to s.length:
   for j from i+1 to s.length:
      result.add(s.substring(i,j))
return result

但是请注意,您可以通过创建迭代器并动态生成子字符串来做一些“作弊”,它应该看起来像这样[伪代码]:

class MyIterator:
  String s
  int i,j
  MyIterator(String s):
     this.s = s
     i = 0
     j = 0
  next():
     j = j + 1
     if (j >= s.length):
     i = i + 1
     j = i + 1
     if (i >= s.length): 
         throw exception
     return s.substring(i,j)

请注意,创建迭代器是O(1),每次迭代都是O(n) - 但要实际生成所有元素,您需要O(n^2) 步骤,因此总体上仍然保持O(n^3) 的复杂性,但您减少了延迟你的申请。

编辑:
我编辑了复杂性,声称它是O(n^2) 是错误的,复杂性是O(n^3),因为您需要生成可变长度的字符串,其中一些字符串很长。至少一半生成的子字符串的长度为n/2 - 因此总复杂度为Theta(n^3)

EDIT2:
在某些情况下,它实际上可以是O(n^2) - 取决于字符串的实现。例如在 java 中 - 它使用单个 char[],并且只与 offsetlength “播放” - 所以在 java 中 - 创建实际上是 O(n^2),因为创建子字符串是 O(1)
但是在 C 中 - 它是 O(n^3),因为每个子字符串都需要复制到不同的 char[]

【讨论】:

  • @TylerJohnson:恐怕我不熟悉php,我不知道如何在php中创建子字符串,但AFAIK大多数现代语言不需要复制字符串,但它只是一个猜测。
【解决方案2】:

检查 php 中 n-gram 的实现。

在您的示例字符串中:嘿

H、E、Y 是一元组

HE、EY 是二元组

嘿是一个三字组

【讨论】:

  • 也许 php 对于 n-gram 有其他含义,但 n-grams通常被称为术语/单词。 1个单词是unigram,2个单词是bigram,3个单词是trigram,...例如:google n-grams
  • 嗨阿米特:NGrams 可能暗示单词或字符。我不使用 PHP 编码,我一般都在接受。我在 Lucene 搜索引擎中使用 NGram 索引来拆分单词。它也可以是术语/单词或字符。
猜你喜欢
  • 1970-01-01
  • 2012-02-12
  • 1970-01-01
  • 1970-01-01
  • 2010-12-06
  • 2014-09-06
  • 2011-12-05
  • 1970-01-01
相关资源
最近更新 更多