这是一个在 Ruby 中使用内置二进制转换的工作实现。我已经对它进行了足够多的评论,以至于我认为不需要额外的措辞来解释。请注意,此操作不需要对二进制字符串进行排序。
ary = ["1", "010", "100", "110", "11"] # Works with or without leading zeros
n_plus_1 = ary.size + 1
result = n_plus_1 * (n_plus_1 + 1) / 2 # Total if all values were present
# Convert each string in ary to int using base 2, and deduct from the total
ary.each { |str| result -= str.to_i(2) }
# The remainder is the missing value
puts "Missing value is #{result} (binary #{result.to_s(2)})"
它和下面的代码都会产生以下输出:
缺失值为 5(二进制 101)
如果你想避免内置转换,这里有一个递归转换器,它应该可以直接翻译成其他语言。请注意,给定默认值的 Ruby 方法参数不需要在方法调用中显式提供:
def str_to_i(char_ary, power = 1, radix = 2)
return 0 if char_ary.size == 0 # Base case
bit = char_ary.pop.to_i # Remove last character in array and convert to int
return bit * power + str_to_i(char_ary, power * radix, radix)
end
ary = ["1", "010", "100", "110", "11"] # Works with or without leading zeros
n_plus_1 = ary.size + 1
result = n_plus_1 * (n_plus_1 + 1) / 2 # Total if all values were present
# Convert each string to array of chars, then to int, and deduct from total
ary.each { |str| result -= str_to_i(str.chars) }
# The remainder is the missing value
puts "Missing value is #{result} (binary #{result.to_s(2)})"
这也满足了您对recursion 标签的使用。
如果你想在递归上做完整的 Monty:
def str_to_i(char_ary, power = 1, radix = 2)
return 0 if char_ary.size == 0 # Base case
bit = char_ary.pop.to_i # Remove last character in array and convert to int
return bit * power + str_to_i(char_ary, power * radix, radix)
end
# Assuming String -> Integer can be considered O(1):
# T(n) = 2 * T(n/2) + O(1) => O(n)
# Stack size is O(log n), which should avoid stack overflow, where splitting
# array into subsets of 1 an n-1 would exceed recursive stack limits even for
# relatively small arrays (more than a few hundred).
def sum_array(ary, first = 0, last = ary.size - 1)
# return ary[first].to_i(2) if last == first # using built-in conversion
return str_to_i(ary[first].chars) if last == first # avoiding built-in
mid = first + (last - first) / 2
return sum_array(ary, first, mid) + sum_array(ary, mid + 1, last)
end
ary = ["1", "010", "100", "110", "11"] # Works with or without leading zeros
n_plus_1 = ary.size + 1
result = n_plus_1 * (n_plus_1 + 1) / 2 - sum_array(ary)
# The remainder is the missing value
puts "Missing value is #{result} (binary #{result.to_s(2)})"