为什么拒绝不拒绝?

时间:2015-01-29 16:27:15

标签: ruby dictionary

此代码在Exercism.io上的汉明距离问题上为my initial stab,但是当字符串a比字符串b更长时,情况就失败了,我尝试了了解原因。

def self.compute(a, b)
  a.split('').reject.with_index { |c, i| c == b[i] }.size
end

我通过修剪第一个字符串解决了这个问题......

def self.compute(a, b)
  a[0...b.size].split('').reject.with_index { |c, i| c == b[i] }.size
end

...但我不明白为什么reject包含了额外的字符。当我检查比较时,它们似乎是假的,正如我所料,但仍然包含在结果中。

谁能告诉我为什么?

2 个答案:

答案 0 :(得分:5)

  

我不明白为什么拒绝包含额外的字符。当我检查比较时,它们似乎是错误的

正确。当你拒绝时,false表示"接受" - 拒绝的反面。

问题仅在于你没有理解"拒绝"手段。当您遇到类似这样的问题时, debug 。在这种情况下,这样做的方法是消除多余的材料,并专注于让你感到困惑的事情。移除size来电,然后查看reject来电的结果:

def compute(a, b)
  a.split('').reject.with_index { |c, i| c == b[i] }
end
result = compute("hey", "ha")
puts result

输出为"e""y"。这是有道理的:

  • 在第一次传递时,"h" == "h"被拒绝。

  • 在第二遍,"e"!= "a"并接受。

  • 在第三遍中,"y"无法与之比较,因此无法成功;因此我们无法拒绝 - 因此"y"被接受。这就是你要问的问题。

答案 1 :(得分:1)

这是另一种涉及大量排序的方法,可能是次优的,但可以作为更有效解决方案的基础:

def ham(a,b)
  [ a.length, b.length ].sort[1].times.reject do |i|
    a[i] != b[i]
  end.sort[-1]
end

pairs = [
  ['A', 'A'],
  ['A','G'],
  ['AG','CT'],
  ['AT','CT'],
  ['GGACG', 'GGTCG'],
  ['AGAGACTTA', 'AAA'],
  ['AGG', 'AAAACTGACCCACCCCAGG'],
  ['GATACA', 'GCATAA'],
  ['GGACGGATTCTG', 'AGGACGGATTCT']
]

pairs.each do |pair|
  puts '%s -> %s' % [ pair.inspect, ham(*pair).inspect ]
end

# ["A", "A"] -> 0
# ["A", "G"] -> nil
# ["AG", "CT"] -> nil
# ["AT", "CT"] -> 1
# ["GGACG", "GGTCG"] -> 4
# ["AGAGACTTA", "AAA"] -> 2
# ["AGG", "AAAACTGACCCACCCCAGG"] -> 0
# ["GATACA", "GCATAA"] -> 5
# ["GGACGGATTCTG", "AGGACGGATTCT"] -> 8

在您的版本中,如果长度不同,您不会将最长的字符串与最短的字符串进行比较。按长度排序可以解决这个问题。