alphabet = ["A","B","C","D","E","F","G","H","I","J",
"K","L","M","N","O","P","Q","R","S","T",
"U","V","W","X","Y","Z"," ",".",",",";",
"-","'"
]
file = File.read("vt_00.txt")
i = 0
while i < alphabet.count do
single_char = alphabet[i]
single_char_count = file.count(single_char)
print "#{alphabet[i]} = #{single_char_count} "
j = 0
while j < alphabet.count do
two_chars = alphabet[i] + alphabet[j]
two_chars_count = file.scan(two_chars).count
if two_chars_count > 10 && two_chars_count < 15
print "#{two_chars} = #{two_chars_count} "
end
k = 0
while k < alphabet.count do
three_chars = alphabet[i] + alphabet[j] + alphabet[k]
three_chars_count = file.scan(three_chars).count
if three_chars_count > 10 && three_chars_count < 15
print "#{three_chars} = #{three_chars_count} "
end
k += 1
end
j += 1
end
i += 1
end
我有类似高级代码的代码。但是后来我通过each_cons找到了一个解决方案,您能解释一下它的工作原理吗?我不明白.inject .. part。
count = string.each_cons(1).inject(Hash.new(0)) { |total, bigram| total[bigram] += 1; total }.sort_by { |_key, value| value }.reverse.to_h
更详细的编写方式为:
total = Hash.new(0)
string.each_cons(1).each{|bigram| total[bigram] += 1}
inject
允许注入一些起始值(Hash.new(0)
->我们使用默认值0,因此我们可以安全地使用+=
运算符),并且在下一次迭代中注入该块返回的任何内容。因此,在这种情况下,我们必须显式返回哈希(total
),以便在下一步中对其进行操作。
一个简单的例子是添加数组的所有值:
[1,4,5,23,2,66,123].inject(0){|sum, value| sum += value}
[从0开始,我们执行0 + 1
的第一个迭代,然后将其结果注入下一个迭代中。
注意:在您的原始代码中,您可以更轻松地遍历数组,而不是使用while
循环和维护计数器,如下所示:
alphabet.each do |single_char|
single_char_count = file.count(single_char)
print "#{alphabet[i]} = #{single_char_count} "
alphabet.each do |second_char|
two_chars = single_char + second_char
# do something with two_chars
alphabet.each do |third_char|
three_chars = single_char + second-char + third_char
# do something with three_chars
end
end
end
我猜想是迭代file
(1-2-3)还是使用each_cons
会更有效,这取决于file.scan
的大小。