如果我的理解是我们得到一个dictionary
不包含空格的单词数组和一个 string str
,并且将构造一个哈希,其键是元素,dictionary
其值等于非重叠1的子串的str
数量,其中键是子串。返回的散列应该排除具有零值的键。
该答案解决了以下情况:
substrings(str, dictionary)
dictionary
大,str
不过大(我稍后会详细说明其含义),效率很重要。
我们首先定义一个辅助方法,其目的将变得清晰。
def substr_counts(str)
str.split.each_with_object(Hash.new(0)) do |word,h|
(1..word.size).each do |sub_len|
(0..word.size-sub_len).each do |start_idx|
h[word[start_idx,sub_len]] += 1
end
end
end
end
对于问题中给出的示例,
substr_counts("go going")
#=> {"g"=>3, "o"=>2, "go"=>2, "i"=>1, "n"=>1, "oi"=>1, "in"=>1, "ng"=>1,
# "goi"=>1, "oin"=>1, "ing"=>1, "goin"=>1, "oing"=>1, "going"=>1}
正如所见,此方法分解str
为单词,计算每个单词的每个子字符串并返回一个哈希,其键是子字符串,其值是包含该子字符串的所有单词中不重叠子字符串的总数。
现在可以快速构建所需的哈希。
def cover_count(str, dictionary)
h = substr_counts(str)
dictionary.each_with_object({}) do |word,g|
g[word] = h[word] if h.key?(word)
end
end
dictionary = ["below", "down", "go", "going", "horn", "how", "howdy",
"it", "i", "low", "own", "part", "partner", "sit"]
cover_count("go going", dictionary)
#=> {"go"=>2, "going"=>1, "i"=>1}
另一个例子:
str = "lowner partnership lownliest"
cover_count(str, dictionary)
#=> {"i"=>2, "low"=>2, "own"=>2, "part"=>1, "partner"=>1}
这里,
substr_counts(str)
#=> {"l"=>3, "o"=>2, "w"=>2, "n"=>3, "e"=>3, "r"=>3, "lo"=>2,
# ...
# "wnliest"=>1, "lownlies"=>1, "ownliest"=>1, "lownliest"=>1}
substr_counts(str).size
#=> 109
这里有一个明显的权衡。如果str
是长的,特别是如果它包含长词2,构建将花费太长时间来h
证明不必为 中的每个词确定dictionary
该词是否包含在 的每个词中的节省是合理的str
。但是,如果构建 是值得的h
,那么总体上节省的时间可能是可观的。
1.“不重叠”我的意思是如果str
等于'bobobo'
它包含一个,而不是两个子字符串'bobo'
。
2.substr_counts("antidisestablishmentarianism").size #=> 385
还不错。