目标:
编写一个带有两个参数的函数:(1) 表示文本文档的字符串和 (2) 提供要返回的项目数的整数。实现该函数,使其返回按词频排序的字符串列表,首先出现最频繁的词。使用您的最佳判断来决定如何分隔单词。您的解决方案应该在 O(n) 时间内运行,其中 n 是文档中的字符数。
我的想法是,在最坏的情况下,函数的输入可能是文档中的单词总数,从而将问题减少到按单词的频率排序。这让我认为如果我使用比较排序方法,时间复杂度的下限将是 O (n log n)。所以,我的想法是最好的方法是实现计数排序。这是我的代码。
我想让你告诉我我的分析是否正确,我已经用我对时间复杂度的想法对代码进行了注释,但它肯定是不正确的。这段代码的实际时间和空间复杂度是多少?另外,我想知道这实际上是否是一种好方法,是否有任何替代方法可以在实践中使用。
### n is number of characters in string, k is number of words ###
def word_frequencies(string, n)
words = string.split(/\s/) # O(n)
max = 0
min = Float::INFINITY
frequencies = words.inject(Hash.new(0)) do |hash,word| # O(k)
occurrences = hash[word] += 1 # O(1)
max = occurrences if occurrences > max # O(1)
min = occurrences if occurrences < min # O(1)
hash; # O(1)
end
### perform a counting sort ###
sorted = Array.new(max + words.length)
delta = 0
frequencies.each do |word, frequency| #O(k)
p word + "--" + frequency.to_s
index = frequency
if sorted[index]
sorted[index] = sorted[index].push(word) # ??? I think O(1).
else
sorted[index] = [word] # O(1)
end
end
return sorted.compact.flatten[-n..-1].reverse
### Compact is O(k). Flatten is O(k). Reverse is O(k). So O(3k)
end
### Total --- O(n + 5k) = O(n). Correct?
### And the space complexity is O(n) for the hash + O(2k) for the sorted array.
### So total O(n).
text = "hi hello hi my name is what what hi hello hi this is a test test test test hi hi hi what hello these are some words these these"
p word_frequencies(text, 4)