我的问题很简单,我有一个子字符串列表,我必须计算一个特定字符串中包含多少个子字符串。下面是我的代码:
string = "..." substrings = ["hello", "foo", "bar", "brol"] count = 0 substrings.each do |sub| count += 1 if string.include?(sub) end
在这个例子中,我们运行了整个字符串4次,这是相当耗时的。你将如何优化这个过程?
iq0todco1#
它 使用 Regexp.union 只 运行 字符 串 一 次 :
Regexp.union
string = 'hello there! this is foobar!' substrings = ["hello", "foo", "bar", "brol"] string.scan(Regexp.union(substrings)).count # => 3
中 的 每 一 个虽然 这个 解决 方案 在 小 输入 时 明显 较慢 , 但 它 具有 较 低 的 复杂 度 - 对于 长度 为 n 的 字符 串 和 长度 为 m 的 子 字符 串 , 原始 解决 方案 的 复杂 度 为 O(m*n) , 而 这个 解决 方案 的 复杂 度 为 O(m+n) 。
n
m
O(m*n)
O(m+n)
在 再次 阅读 了 这个 问题 和 我 的 答案 之后 , 我 得出 了 这样 的 结论 : 这 不仅 是 一 个 过早 的 优化 ( 正如@Max 所 指出 的 ) , 而且 我 的 答案 在 语义 上 与 OP * 不同 * 。让 我 解释 一下 - OP 代码 计算 字符 串 中 有 多少 个 substrings * 至少 出现 一 次 * , 而 我 的 解决 方案 计算 * 有 多少 个 substrings * 出现 在 * 任何 * 字符 串 中 * :
substrings
op_solution('hello hello there', ["hello", "foo", "bar", "brol"]) # => 1 uri_solution('hello hello there', ["hello", "foo", "bar", "brol"]) # => 2
格式这 也 解释 了 为什么 我 的 解决 方案 如此 缓慢 , 即使 对于 长 字符 串 也 是 如此 - - 尽管 它 只 对 输入 字符 串 进行 了 一 次 传递 , 但 它 必须 传递 * 所有 * 字符 串 , 而 原始 代码 在 一 个 单词 的 第 一 次 出现 时 就 停止 了 。我 的 结论 是 - - 采用 奥雅 纳 的 解决 方案 。 它 不会 比 你 的 更 快 , 只是 更 简洁 , 但 我 想 不 出 更 好 的 办法 了 : )
y0u0uwnf2#
书写为:-
substrings.count { |sub| string.include?(sub) }
ars1skjm3#
subtrings.collect { |i| string.scan(i).count }.sum很优雅。
subtrings.collect { |i| string.scan(i).count }.sum
3条答案
按热度按时间iq0todco1#
它 使用
Regexp.union
只 运行 字符 串 一 次 :中 的 每 一 个
虽然 这个 解决 方案 在 小 输入 时 明显 较慢 , 但 它 具有 较 低 的 复杂 度 - 对于 长度 为
n
的 字符 串 和 长度 为m
的 子 字符 串 , 原始 解决 方案 的 复杂 度 为O(m*n)
, 而 这个 解决 方案 的 复杂 度 为O(m+n)
。在 再次 阅读 了 这个 问题 和 我 的 答案 之后 , 我 得出 了 这样 的 结论 : 这 不仅 是 一 个 过早 的 优化 ( 正如@Max 所 指出 的 ) , 而且 我 的 答案 在 语义 上 与 OP * 不同 * 。
让 我 解释 一下 - OP 代码 计算 字符 串 中 有 多少 个
substrings
* 至少 出现 一 次 * , 而 我 的 解决 方案 计算 * 有 多少 个substrings
* 出现 在 * 任何 * 字符 串 中 * :格式
这 也 解释 了 为什么 我 的 解决 方案 如此 缓慢 , 即使 对于 长 字符 串 也 是 如此 - - 尽管 它 只 对 输入 字符 串 进行 了 一 次 传递 , 但 它 必须 传递 * 所有 * 字符 串 , 而 原始 代码 在 一 个 单词 的 第 一 次 出现 时 就 停止 了 。
我 的 结论 是 - - 采用 奥雅 纳 的 解决 方案 。 它 不会 比 你 的 更 快 , 只是 更 简洁 , 但 我 想 不 出 更 好 的 办法 了 : )
y0u0uwnf2#
书写为:-
ars1skjm3#
subtrings.collect { |i| string.scan(i).count }.sum
很优雅。