此代码在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
包含了额外的字符。当我检查比较时,它们似乎是假的,正如我所料,但仍然包含在结果中。
谁能告诉我为什么?
答案 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
在您的版本中,如果长度不同,您不会将最长的字符串与最短的字符串进行比较。按长度排序可以解决这个问题。