Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 查找数组中最常用的字符串_Ruby_String_Arrays - Fatal编程技术网

Ruby 查找数组中最常用的字符串

Ruby 查找数组中最常用的字符串,ruby,string,arrays,Ruby,String,Arrays,例如,我有一个数组(大小是可变的): 我需要找到最常用的值(“1.111”) 有没有一个简单的方法 Tks提前 编辑#1:谢谢大家的回答 编辑#2:我根据Z.E.D.的信息更改了我接受的答案。再次感谢大家 您可以对数组进行排序,然后在其上循环一次。在循环中,只需跟踪当前项目及其显示次数。一旦列表结束或项目更改,如果count>max\u count,则设置max\u count==count。当然,还要跟踪哪个项具有max\u count您可以创建一个hashmap,将数组项存储为键,其值为

例如,我有一个数组(大小是可变的):

我需要找到最常用的值(
“1.111”

有没有一个简单的方法

Tks提前


编辑#1:谢谢大家的回答



编辑#2:我根据Z.E.D.的信息更改了我接受的答案。再次感谢大家

您可以对数组进行排序,然后在其上循环一次。在循环中,只需跟踪当前项目及其显示次数。一旦列表结束或项目更改,如果
count>max\u count
,则设置
max\u count==count
。当然,还要跟踪哪个项具有
max\u count

您可以创建一个hashmap,将数组项存储为键,其值为该元素在数组中出现的次数

伪代码:

["1.111", "1.122", "1.250", "1.111"].each { |num|
  count=your_hash_map.get(num)
  if(item==nil)
    hashmap.put(num,1)
  else
    hashmap.put(num,count+1)
}
如前所述,排序可能更快。

Ruby<2.2 注意:
Enumberable.max_by
是Ruby 1.9的新版本,但它已被后移植到1.8.7

Ruby>=2.2 Ruby 2.2引入了一种方法,通过这种方法我们可以使代码更加简洁:

def most_common_value(a)
  a.group_by(&:itself).values.max_by(&:size).first
end
作为一个猴子补丁 或作为
可枚举#模式

Enumerable.class_eval do
  def mode
    group_by do |e|
      e
    end.values.max_by(&:size).first
  end
end

["1.111", "1.122", "1.250", "1.111"].mode
# => "1.111"

使用哈希的默认值功能:

>> x = ["1.111", "1.122", "1.250", "1.111"]
>> h = Hash.new(0)
>> x.each{|i| h[i] += 1 }
>> h.max{|a,b| a[1] <=> b[1] }
["1.111", 2]
>x=[“1.111”、“1.122”、“1.250”、“1.111”]
>>h=散列。新建(0)
>>x.each{i | h[i]+=1}
>>h.max{| a,b | a[1]b[1]}
["1.111", 2]

一次通过散列来累加计数。使用.max()查找具有最大值的哈希项

#!/usr/bin/ruby a = Hash.new(0) ["1.111", "1.122", "1.250", "1.111"].each { |num| a[num] += 1 } a.max{ |a,b| a[1] <=> b[1] } # => ["1.111", 2] #!/usr/bin/ruby a=散列。新建(0) [“1.111”、“1.122”、“1.250”、“1.111”]| a[num]+=1 } a、 max{a,b{a[1]b[1]}}=>[1.111],2] 或者,将其全部滚动到一行:

ary.inject(Hash.new(0)){ |h,i| h[i] += 1; h }.max{ |a,b| a[1] <=> b[1] } # => ["1.111", 2] ary.inject(Hash.new(0)){h,i|h[i]+=1;h}.max{a,b|a[1]b[1]}=>[“1.111”,2] 如果您只想返回项目,请添加.first():

ary.inject(Hash.new(0)){h,i|h[i]+=1;h}.max{a,b|a[1]b[1]}.first#=>1.111
我使用的第一个示例是如何在Perl中完成它。第二种更像红宝石。两者都适用于较旧版本的Ruby。我想对它们进行比较,并看看Wayne的解决方案将如何加快速度,所以我使用benchmark进行了测试:

#!/usr/bin/env ruby require 'benchmark' ary = ["1.111", "1.122", "1.250", "1.111"] * 1000 def most_common_value(a) a.group_by { |e| e }.values.max_by { |values| values.size }.first end n = 1000 Benchmark.bm(20) do |x| x.report("Hash.new(0)") do n.times do a = Hash.new(0) ary.each { |num| a[num] += 1 } a.max{ |a,b| a[1] <=> b[1] }.first end end x.report("inject:") do n.times do ary.inject(Hash.new(0)){ |h,i| h[i] += 1; h }.max{ |a,b| a[1] <=> b[1] }.first end end x.report("most_common_value():") do n.times do most_common_value(ary) end end end #!/usr/bin/env ruby 需要“基准” ary=[“1.111”、“1.122”、“1.250”、“1.111”]*1000 def最常用值(a) a、 按{| e | e}.values.max_按{| values | values.size}分组 结束 n=1000 Benchmark.bm(20)do|x| x、 报告(“Hash.new(0)” n、 时代确实如此 a=散列。新建(0) ary.each{| num | a[num]+=1} a、 max{a,b{a[1]b[1]}。首先 结束 结束 x、 报告(“注入:”)做什么 n、 时代确实如此 ary.inject(Hash.new(0)){h,i|h[i]+=1;h}.max{a,b|a[1]b[1]} 结束 结束 x、 报告(“最常见的值():”)执行 n、 时代确实如此 最常用值(ary) 结束 结束 结束 结果如下:

user system total real Hash.new(0) 2.150000 0.000000 2.150000 ( 2.164180) inject: 2.440000 0.010000 2.450000 ( 2.451466) most_common_value(): 1.080000 0.000000 1.080000 ( 1.089784) 用户系统总真实值 散列新(0)2.150000 0.0000002.150000(2.164180) 注入:2.440000 0.010000 2.450000(2.451466) 最常见值():1.080000 0.000000 1.080000(1.089784)
它将返回数组中最常用的值

x.group_by{|a| a }.sort_by{|a,b| b.size<=>a.size}.first[0]
x.group_by{a | a}。sort_by{a,b | b.sizea.size}。first[0]
即:

x=[“1.111”、“1.122”、“1.250”、“1.111”]
#最受欢迎
x、 按{a{a}分组。按{a,b{b.sizea.size}排序。第一[0]
#=> "1.111
#多少次
x、 group|U by{a | a}。sort|U by{a,b | b.sizea.sizea}。first[1]。size
#=> 2

为什么排序会更快?排序最多是O(n log n),而这是O(n)校正,基于比较的排序是O(n log n)。有线性排序,如桶排序或基数排序。编辑:桶排序或基数排序通常需要某些类型的数据才能比比较排序更有效。它们在时间上弥补的东西通常会占用空间。FTR,上面的伪代码是桶排序。这被选为答案,但请看下面显示了我的基准测试结果。这不是
new.(0)
会为每个哈希项生成相同的对象吗?
hash.new{h,k{h[k]=0}
取而代之的是?非常非常好!非常感谢您提供的这些信息…实际上我正在阅读有关
基准测试的文章来做到这一点。再次感谢您。这说明了为什么基准测试很重要。我认为使用注入比使用每种方法循环数组更快,但Wayne的解决方案将时间缩短了一半。@Z.E.D.,我得到了一个语法分析器ror,
意外的提示符,期望“}”
在第15行,
a.max{a,b | a[1]b[1]}。首先,
插入
b[
(Ruby 1.9.1)。@Smotchkiss,将
a.max{a,b | a[1]b[1]
更改为
a.max{a,b[1]}
是的,这是一个错误。降价或浏览器认为是一个标记并将其隐藏,因此我不得不将其更改为。与通常的方式相比,我对速度印象深刻。做得好。@Wayne Conrad,uber solution.+1这里有一个较短的版本:x.group_by{e | e}.values.max_by(&:size)。首先#=>1.111“如果需要,将其转化为一种方法留给读者作为练习;-)@Michael Kohl,很好。我将编辑我的答案以使用新的…不管你怎么称呼它…技巧。在
end
之后的链式方法如何工作?我通常的示例返回Nil,当然没有可用的方法。有关于这方面的文档吗?(也许是鹤嘴锄书里的页码?)谢谢 #!/usr/bin/env ruby require 'benchmark' ary = ["1.111", "1.122", "1.250", "1.111"] * 1000 def most_common_value(a) a.group_by { |e| e }.values.max_by { |values| values.size }.first end n = 1000 Benchmark.bm(20) do |x| x.report("Hash.new(0)") do n.times do a = Hash.new(0) ary.each { |num| a[num] += 1 } a.max{ |a,b| a[1] <=> b[1] }.first end end x.report("inject:") do n.times do ary.inject(Hash.new(0)){ |h,i| h[i] += 1; h }.max{ |a,b| a[1] <=> b[1] }.first end end x.report("most_common_value():") do n.times do most_common_value(ary) end end end user system total real Hash.new(0) 2.150000 0.000000 2.150000 ( 2.164180) inject: 2.440000 0.010000 2.450000 ( 2.451466) most_common_value(): 1.080000 0.000000 1.080000 ( 1.089784)
x.group_by{|a| a }.sort_by{|a,b| b.size<=>a.size}.first[0]
x = ["1.111", "1.122", "1.250", "1.111"]
# Most popular
x.group_by{|a| a }.sort_by{|a,b| b.size<=>a.size}.first[0]
#=> "1.111
# How many times
x.group_by{|a| a }.sort_by{|a,b| b.size<=>a.size}.first[1].size
#=> 2