我的问题很简单,我有一个子串列表,我必须计算特定字符串中包含的子串数。 这是我的代码:
string = "..."
substrings = ["hello", "foo", "bar", "brol"]
count = 0
substrings.each do |sub|
count += 1 if string.include?(sub)
end
在这个例子中,我们遍历整个字符串4次,这非常消耗。 你会如何优化这个过程?
答案 0 :(得分:7)
这只使用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)
。
<强>更新强>
在再次阅读问题和我的回答之后,我得出的结论是,不仅这是一个不成熟的优化(正如@Max所说),但我的答案在语义上与不同而不是OP
让我解释一下 - OP代码计算字符串中substrings
有多少至少一个外观,而我的解决方案计算多少次出现有{em>任何的substrings
:
op_solution('hello hello there', ["hello", "foo", "bar", "brol"])
# => 1
uri_solution('hello hello there', ["hello", "foo", "bar", "brol"])
# => 2
这也解释了为什么我的解决方案速度太慢,即使对于长字符串 - 尽管输入字符串只有一个传递,但它必须传递所有,而原始代码停在第一次出现一个单词。
我的结论是 - 使用@Arup的解决方案。它不会比你的更快,它只是更简洁,但我想不出更好的东西:)
答案 1 :(得分:3)
写作: -
substrings.count { |sub| string.include?(sub) }