如何返回给定数组中的回文数组?不是回文数字,如11,22,33,44和& c。,而是与同一数组中其他数字的回文数字。假设所有元素都是正数,结果不应返回单个数字(例如下面的代码)
假设我有array = [13, 31, 51, 79, 83, 97]
。从13& 31和79& 97是回文,我希望它返回array_pali = [13, 31, 79, 97]
def pali_array(array)
array_reverse = array.map{|el| el.to_s.reverse.to_i}
array_pali = array & array_reverse
return array_pali
end
我的初步计划是提出该数组的反向,array_reverse = array.map{|el| el.to_s.reverse.to_i}
并将它们相交:array & array_reverse
如果我想从2-100返回素数数组,则会出现一个问题:
array = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
我改变了它:
array_reverse = array.map{|el| el.to_s.reverse.to_i}
=> [2, 3, 5, 7, 11, 31, 71, 91, 32, 92, 13, 73, 14, 34, 74, 35, 95, 16, 76, 17, 37, 97, 38, 98, 79]
它返回:
array & array_reverse
=> [2, 3, 5, 7, 11, 13, 17, 31, 37, 71, 73, 79, 97]
这种方法的问题:
2,3,5,7和11不是与其他元素的回文。单个数字的反转是该数字本身,它使代码返回所有单个数字和所有回文数字(如11,22,33)。它应该只返回[13, 17, 31, 37, 71, 73, 79, 97]
如何让它将仅元素作为回文返回到同一数组中的其他元素?
答案 0 :(得分:2)
这是一个非常天真和懒惰的实现。不保留元素的原始顺序。应该是O(N)。
我希望代码不言自明。
array = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
require 'set'
seen_numbers = Set.new
result = []
array.each do |elem|
next if elem < 10
normal_str = elem.to_s
rev_str = normal_str.reverse
if seen_numbers.include?(rev_str)
result << rev_str.to_i
result << elem
end
seen_numbers << normal_str
end
result # => [13, 31, 17, 71, 37, 73, 79, 97]
答案 1 :(得分:1)
如果您想要替代方案,请认为这是有效的:
array = [13, 31, 51, 79, 83, 97]
array.combination(2)
.select {|pair| pair.first.to_s == pair.last.to_s.reverse }
.flatten
#=> [13, 31, 79, 97]
使用Array#combination
获取每对组合,然后我们仅选择那些回文对。然后压扁你的阵列。
答案 2 :(得分:1)
arr = [7, 13, 31, 51, 31, 60, 70, 13, 79, 83, 79, 97]
请注意arr
中有各种重复值。
arr.reject { |n| n < 10 || (n%10).zero? }.
group_by { |n| n.to_s.each_char.sort }.
values.
reject { |arr| arr.size == 1 }.
flat_map { |arr| arr.group_by(&:itself).values.min_by(&:size) }
#=> [13, 13, 97]
如果需要,匹配值很容易计算。
添加 || (n%10).zero?
只是为了加快速度。
步骤如下。
a = arr.reject { |n| n < 10 || (n%10).zero? }
#=> [13, 31, 51, 31, 13, 79, 83, 79, 97]
b = a.group_by { |n| n.to_s.each_char.sort }
#=> {["1", "3"]=>[13, 31, 31, 13], ["1", "5"]=>[51],
# ["7", "9"]=>[79, 79, 97], ["3", "8"]=>[83]}
c = b.values
#=> [[13, 31, 31, 13], [51], [79, 79, 97], [83]]
d = c.reject { |arr| arr.size == 1 }
#=> [[13, 31, 31, 13], [79, 79, 97]]
d.flat_map { |arr| arr.group_by(&:itself).values.min_by(&:size) }
#=> [13, 13, 97]
考虑最后一步。 flat_map
将d
的第一个元素传递给其块,并将块变量设置为该值:
arr = d[0]
#=> [13, 31, 31, 13]
并执行块计算:
e = arr.group_by(&:itself)
#=> {13=>[13, 13], 31=>[31, 31]}
f = e.values
#=> [[13, 13], [31, 31]]
f.min_by(&:size)
#=> [13, 13]
接下来,
arr = d[1]
#=> [79, 79, 97]
e = arr.group_by(&:itself)
#=> {79=>[79, 79], 97=>[97]}
f = e.values
#=> [[79, 79], [97]]
f.min_by(&:size)
#=> [97]
flat_map
因此返回
[*[13, 13], *[97]]
#=> [13, 13, 97]