Ruby 如何编写在字符串中查找最常见字母的方法?

Ruby 如何编写在字符串中查找最常见字母的方法?,ruby,string,methods,Ruby,String,Methods,以下是问题提示: 编写一个接受字符串的方法。您的方法应该返回数组中最常见的字母,以及它出现的次数计数 到目前为止,我还不能完全确定我要去哪里 def most_common_letter(string) arr1 = string.chars arr2 = arr1.max_by(&:count) end 一种简单的方法,不用担心检查空字母: letter, count = ('a'..'z') .map {|letter| [letter, s

以下是问题提示:

编写一个接受
字符串的方法。您的方法应该返回数组中最常见的字母,以及它出现的次数计数

到目前为止,我还不能完全确定我要去哪里

def most_common_letter(string)
  arr1 = string.chars
  arr2 = arr1.max_by(&:count)
end

一种简单的方法,不用担心检查空字母:

letter, count = ('a'..'z')
                .map {|letter| [letter, string.count(letter)] }
                .max_by(&:last)

一种简单的方法,不用担心检查空字母:

letter, count = ('a'..'z')
                .map {|letter| [letter, string.count(letter)] }
                .max_by(&:last)
编辑:
使用哈希:

def most_common_letter(string)
  chars             = {}
  most_common       = nil
  most_common_count = 0
  string.downcase.gsub(/[^a-z]/, '').each_char do |c|
    count = (chars[c] = (chars[c] || 0) + 1)
    if count > most_common_count
      most_common       = c
      most_common_count = count
    end
  end
  [most_common, most_common_count]
end
编辑:
使用哈希:

def most_common_letter(string)
  chars             = {}
  most_common       = nil
  most_common_count = 0
  string.downcase.gsub(/[^a-z]/, '').each_char do |c|
    count = (chars[c] = (chars[c] || 0) + 1)
    if count > most_common_count
      most_common       = c
      most_common_count = count
    end
  end
  [most_common, most_common_count]
end

我建议您使用计数散列:

str = "The quick brown dog jumped over the lazy fox."

str.downcase.gsub(/[^a-z]/,'').
             each_char.
             with_object(Hash.new(0)) { |c,h| h[c] += 1 }.
             max_by(&:last)
   #=> ["e",4]
如果参数为零,则创建一个默认值为零的空哈希

步骤如下:

s = str.downcase.gsub(/[^a-z]/,'')
  #=> "thequickbrowndogjumpedoverthelazyfox"
enum0 = s.each_char
  #=> #<Enumerator: "thequickbrowndogjumpedoverthelazyfox":each_char>  
enum1 = enum0.with_object(Hash.new(0))
  #=> #<Enumerator: #<Enumerator:
  #    "thequickbrowndogjumpedoverthelazyfox":each_char>:with_object({})> 
enum1
[“t”,{}]
)的第一个元素被传递给块,并分配给块变量:

c,h = enum1.next
  #=> ["t", {}] 
c #=> "t" 
h #=> {} 
然后执行块计算:

h[c] += 1
  #=> h[c] = h[c] + 1
  #=> h["t"] = h["t"] + 1
  #=> h["t"] = 0 + 1 #=> 1
h #=> {"t"=>1}
c,h = enum1.next
  #=> ["h", {"t"=>1}] 
h[c] += 1
  #=> 1 
h #=> {"t"=>1, "h"=>1} 
Ruby将
h[c]+=1
扩展为
h[c]=h[c]+1
,即
h[“t”]=h[“t”]+1
h#=>{}
h
没有键
“t”
,因此等号右侧的
h[“t”
将替换为哈希的默认值
0
。下一次
c#=>“t”
h[“t”]=h[“t”]+1
将减少到
h[“t”]=1+1#=>2
(即,将不使用默认值,因为
h
现在有一个键
“t”

然后将
enum1
的下一个值传递到块中,并执行块计算:

h[c] += 1
  #=> h[c] = h[c] + 1
  #=> h["t"] = h["t"] + 1
  #=> h["t"] = 0 + 1 #=> 1
h #=> {"t"=>1}
c,h = enum1.next
  #=> ["h", {"t"=>1}] 
h[c] += 1
  #=> 1 
h #=> {"t"=>1, "h"=>1} 

enum1
的其余元素的处理方式类似。

我建议您使用计数哈希:

str = "The quick brown dog jumped over the lazy fox."

str.downcase.gsub(/[^a-z]/,'').
             each_char.
             with_object(Hash.new(0)) { |c,h| h[c] += 1 }.
             max_by(&:last)
   #=> ["e",4]
如果参数为零,则创建一个默认值为零的空哈希

步骤如下:

s = str.downcase.gsub(/[^a-z]/,'')
  #=> "thequickbrowndogjumpedoverthelazyfox"
enum0 = s.each_char
  #=> #<Enumerator: "thequickbrowndogjumpedoverthelazyfox":each_char>  
enum1 = enum0.with_object(Hash.new(0))
  #=> #<Enumerator: #<Enumerator:
  #    "thequickbrowndogjumpedoverthelazyfox":each_char>:with_object({})> 
enum1
[“t”,{}]
)的第一个元素被传递给块,并分配给块变量:

c,h = enum1.next
  #=> ["t", {}] 
c #=> "t" 
h #=> {} 
然后执行块计算:

h[c] += 1
  #=> h[c] = h[c] + 1
  #=> h["t"] = h["t"] + 1
  #=> h["t"] = 0 + 1 #=> 1
h #=> {"t"=>1}
c,h = enum1.next
  #=> ["h", {"t"=>1}] 
h[c] += 1
  #=> 1 
h #=> {"t"=>1, "h"=>1} 
Ruby将
h[c]+=1
扩展为
h[c]=h[c]+1
,即
h[“t”]=h[“t”]+1
h#=>{}
h
没有键
“t”
,因此等号右侧的
h[“t”
将替换为哈希的默认值
0
。下一次
c#=>“t”
h[“t”]=h[“t”]+1
将减少到
h[“t”]=1+1#=>2
(即,将不使用默认值,因为
h
现在有一个键
“t”

然后将
enum1
的下一个值传递到块中,并执行块计算:

h[c] += 1
  #=> h[c] = h[c] + 1
  #=> h["t"] = h["t"] + 1
  #=> h["t"] = 0 + 1 #=> 1
h #=> {"t"=>1}
c,h = enum1.next
  #=> ["h", {"t"=>1}] 
h[c] += 1
  #=> 1 
h #=> {"t"=>1, "h"=>1} 

enum1
的其余元素的处理方式类似。

下面是另一种方法:

str = 'aaaabbbbcd'
h = str.each_char.with_object(Hash.new(0)) { |c,h| h[c] += 1 }
max = h.values.max
output_hash = Hash[h.select { |k, v| v == max}]
puts "most_frequent_value: #{max}"
puts "most frequent character(s): #{output_hash.keys}"

下面是做你想做的事情的另一种方式:

str = 'aaaabbbbcd'
h = str.each_char.with_object(Hash.new(0)) { |c,h| h[c] += 1 }
max = h.values.max
output_hash = Hash[h.select { |k, v| v == max}]
puts "most_frequent_value: #{max}"
puts "most frequent character(s): #{output_hash.keys}"

我想提到一个由Ruby 2.7.0推出的解决方案,它是:

str =<<-END
Tallies the collection, i.e., counts the occurrences of each element. Returns a hash with the elements of the collection as keys and the corresponding counts as values.
END

str.scan(/[a-z]/).tally.max_by(&:last)
#=> ["e", 22]

我想提到一个由Ruby 2.7.0推出的解决方案,它是:

str =<<-END
Tallies the collection, i.e., counts the occurrences of each element. Returns a hash with the elements of the collection as keys and the corresponding counts as values.
END

str.scan(/[a-z]/).tally.max_by(&:last)
#=> ["e", 22]


它是有效的,但是我怎样才能知道这封信出现的次数呢?哦,那是一封很快的信@基里尔,不,这是一个缓慢的。当只需要一个字符串时,它使整个字符串通过26次(当然比您的解决方案慢得多)。是的,这是一个慢得多的解决方案,尽管是直接的。这很奇怪。我和你的解决方案比我的快。它有效,但我怎么能得到这封信出现的次数呢?哦,这是一个快速的解决方案@基里尔,不,这是一个缓慢的。当只需要一个字符串时,它使整个字符串通过26次(当然比您的解决方案慢得多)。是的,这是一个慢得多的解决方案,尽管是直接的。这很奇怪。我和你的解决方案比我的快。很好的答案,一旦你解决了一个小问题:
最常见的字母(“a”)=>[“”,21]
(我的大部分空格都很挤。正如你看到的,有21个。)当然不仅仅是空格:
最常见的字母(“她——安——很酷”)。
@CarySwoveland,这很奇怪。我得到的是最常见的字母(“a”)=>[“”,2]
最常见的字母(“她——安——很酷”)有什么问题?
?还有,我如何摆脱
res
变量?字符
”-“
不是字母。字母是
“a”-“z”
“a”-“z”
。请看我的答案。你可以用:
str.split('').groupby(&:itself.map{k,v |[k,v.size]}.max_by(&:last)
来消除
res
。你得到的是
最常见的字母(“a”)=>[“”,2]
,因为你在复制我的评论。我的字符串有10个空格,后跟一个
“a”
,后跟11个空格。但是,在格式化注释中的文本时,SO删除了多余的空白,所以看起来我的字符串只有两个空格。很好的答案,一旦你解决了一个小问题:
最常见的字母(“a”)=“a=>[”,21]
(我的大部分空格都被压缩了。如你所见,有21个)。当然不仅仅是空格:
最常见的字母(“她——安——很酷。”——,4]
@CarySwoveland,这很奇怪。我得到了
最普通的字母(“a”)——>,2]
最普通的字母(“她——安——很酷”)有什么问题?——”——,4]
?还有,我如何摆脱
res
变量?字符
”-“
不是字母。字母是
“a”-“z”
“a”-“z”
。请看我的答案。你可以用:
str.split('').groupby(&:itself.map{k,v |[k,v.size]}.max_by(&:last)
来消除
res
。你得到的是
最常见的字母(“a”)=>[“”,2]
,因为你在复制我的评论。我的字符串有10个空格,后跟一个
“a”
,后跟11个空格。但是,在格式化注释中的文本时,SO删除了多余的空白,因此看起来我的字符串只有两个空格。排序是查找集合中定义的函数的最大或最小值的一种效率极低的方法。@CarySwoveland我已更新了答案。