哈希映射算法

时间:2016-11-29 16:55:35

标签: ruby algorithm hashmap

分配是使用散列图计算字母在单词中显示的次数。例如:"猫"应该是{' c' => 1,' a' => 1,' t' => 1},那么为什么我所写的不起作用?提前谢谢!

def letter_count(str)
  i=0 
  letters = {}
  while i<str.length 
    letters[str[i]]=0
    i+=1 
  end
  puts letters
  letters.each do |letter, number| 
    j=0 
    while j<str.length 
     # puts letters[str[j]]
      if letters[str[j]] == letter
        puts "something happens"
        number=number+1 
      end
      j+=1 
    end 
  end
  letters.delete(" ")
  puts letters
  return letters
end

4 个答案:

答案 0 :(得分:3)

你可以在循环内修改number变量(它只是变量而不是散列值),并且不可能这样做。 另一个问题是letters[str[j]]永远不会与letter具有相同的价值,因为letters会返回Integer(在这种情况下为0)而不是String

所以你可以修改你的代码:

def letter_count(str)
  i=0
  letters = {}
  while i<str.length
    letters[str[i]] = 0
    i+=1
  end
  puts letters
  letters.each do |letter, number|
    j=0
    while j<str.length
      # puts letters[str[j]]
      if str[j] == letter
        puts "something happens"
        letters[letter] += 1
      end
      j+=1
    end
  end
  letters.delete(" ")
  puts letters
  return letters
end

将产生

letter_count("cats")

# something happens
# something happens
# something happens
# something happens
# => {"c"=>1, "a"=>1, "t"=>1, "s"=>1}

但更易于更简单的例子:

def letter_count(str)
  str.chars.each_with_object(Hash.new(0)) do |char, hsh|
    hsh[char] += 1
  end
end

letter_count("cats")
# => {"c"=>1, "a"=>1, "t"=>1, "s"=>1}

letter_count("tests")
# => {"t"=>2, "e"=>1, "s"=>2}

答案 1 :(得分:2)

你可以这样做:

def letter_count(str)
  tmp_hash = {}
  str.split('').uniq.each do |letter|
    tmp_hash[letter] = str.count(letter)
  end

  puts tmp_hash
  return tmp_hash
end

输出

word = 'hello'
letter_count(word)
# output: {"h"=>1, "e"=>1, "l"=>2, "o"=>1}

答案 2 :(得分:2)

str中定义的字符串的一种方式:

Hash[str.chars.group_by(&:itself).map { |k,v| [k, v.count] }]

关键方法:String#charsEnumerable#group_byString#count

答案 3 :(得分:2)

我会使用计算哈希

"muddled".each_char.with_object(Hash.new(0)) { |c,h| h[c] += 1 }
  #=> { 'm'=>1, 'u'=>1, 'd'=>3, , 'l'=>1, 'e'=>1 }

请参阅Hash::new,特别是参考默认值作为new的参数。 Ruby将h[c] += 1扩展为

h[c] = h[c] + 1

进一步处理表达式之前。假设

h = Hash.new(0).merge('d'=>2)
  #=> {"d"=>2}

然后

h["cat"]
  #=> 0

因为没有密钥'cat'h的默认值为零。现在假设c = 'd'。然后

h['d'] = h['d'] + 1
   #=> 2 + 1 => 3

所以

h #=> {"d"=>3}

接下来,如果c = 'm',因为h.key?('m') #=> false,等式右侧的h[c]会返回h的默认值,为零。

h['m'] = h['m'] + 1
   #=> 0 + 1 => 1

请注意,等式左侧的方法Hash[]=与右侧的方法Hash[]不同。

我可以改为写

"muddled".each_char.with_object({}) do |c,h|
   h[c] = 0 unless h.key?(c)
   h[c] += 1
end

"muddled".each_char.with_object({}) { |c,h| h[c] = (h[c] || 0) + 1 }

如果您不熟悉Enumerator#with_object,则会产生与以下相同的结果,代价是另外两行代码。

h = Hash.new(0)
"muddled".each_char { |c| h[c] += 1 }
h