数组没有返回最频繁的值

时间:2015-05-21 20:58:39

标签: ruby-on-rails arrays ruby

def most_common_letter(string)
  letter = nil
  final_letter = nil
  letter_count = nil
  idx1 = 0
  idx2 = 0
  count = 0
  while idx1 < string.length
    letter = string[idx1]
    while idx2 < string.length
      if letter == string[idx2]
        count += 1
      end
    idx2 += 1
    end
    if (letter_count == nil) || (count > letter_count)
      letter_count = count
      final_letter = letter
    end
  idx1 += 1
  end
  arr = []
  arr.push(final_letter)
  arr.push(letter_count)
  return arr
end

puts(most_common_letter("abbab") == ["b", 3])
#should be true

继续得到[a,2]这让我相信它只是执行代码的一部分,因为在我的脑海里,代码应该在每次有更频繁的字母时重置最终字母和字母数的值。我哪里出错?

4 个答案:

答案 0 :(得分:2)

通常计数哈希用于此类问题:

def most_frequent_letter(str)
  str.each_char.with_object(Hash.new(0)) { |c,h| h[c] += 1 }.max_by(&:last)
end

most_frequent_letter("bananas are so-so")
  #=> ["a",4]

步骤:

h = "bananas are so-so".each_char.with_object(Hash.new(0)) { |c,h| h[c] += 1 }
  #=> {"b"=>1, "a"=>4, "n"=>2, "s"=>3, " "=>2, "r"=>1, "e"=>1, "o"=>2, "-"=>1}
h.max_by(&:last) 
  #=> ["a",4]

答案 1 :(得分:1)

以下是解决此问题的更简单方法:

def most_common_letter(string)
  letters = string.split('').sort!
  frequency = letters.inject(Hash.new(0)) { |h,v| h[v] += 1; h }
  frequency.max_by{|k,v| v}
end

most_common_letter("abbab")
 => ["b", 3]

让我逐行阅读这段代码来解释。

1)获取字符串的字母并按字母顺序排序:

string = "abbab"

letters = string.split('').sort!
=> ["a", "a", "b", "b", "b"]

2)使用键(字母)和值(出现)

创建哈希
frequency = letters.inject(Hash.new(0)) { |h,v| h[v] += 1; h }
 => {"a"=>2, "b"=>3}

3)找到最高值,并将键值对作为数组返回。

frequency.max_by{|k,v| v}
 => ["b", 3]

答案 2 :(得分:0)

您遇到的问题是您在循环后没有重置idx2。

如果puts idx二,您可以调试此项:

def most_common_letter(string)
  letter = nil
  final_letter = nil
  letter_count = nil
  idx1 = 0
  idx2 = 0
  count = 0
  while idx1 < string.length
    letter = string[idx1]
    while idx2 < string.length
      if letter == string[idx2]
        count += 1
      end
      idx2 += 1
    end
    puts "#{idx2}"    #=> This is always 5
    if (letter_count == nil) || (count > letter_count)
      letter_count = count
      final_letter = letter
    end
  idx1 += 1
  end
  arr = []
  arr.push(final_letter)
  arr.push(letter_count)
  return arr
end

puts(most_common_letter("abbab"))

您的算法只是执行以下操作:

将idx1与idx2进行比较:

str [0] with str [0]

str [0] with str [1]

str [0] with str [2]

str [0] with str [3]

str [0] with str [4]

然后idx2超出范围,再也不会满足idx2 < string.length,因为该值未重置。

这是逻辑错误所在。我不会给你另一种解决方案,因为你似乎想要自己解决这个问题。希望这会有所帮助。

答案 3 :(得分:0)

试试这个

def most_common_letter(str)
  str.chars.
    group_by{|v| v}.
    map{|k, l| [k, l.size]}.
    sort_by{|k, size| size}.
    last
end

现在:

  

puts(most_common_letter(“abbab”)== [“b”,3])     #real