2016-07-28 99 views
0

如何返回给定数组中的回文数字数组?不是回文数字,如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

只需添加另一个滤镜步骤即可删除回文数字 – Amit

+0

没有“回文”之类的东西。 1,121和12321都是[根据定义palindromes](https://en.wikipedia.org/wiki/Palindromic_number)。 13和31不是“回文”,它们只是数字相反的数字。 – tadman

+1

我刚看到这个问题,很惊讶地看到你在35分钟后选择了一个答案!为什么不拖延至少几个小时来鼓励其他答案。你并不急于知道。 –

回答

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让每对组合,然后我们只选择那些回文对。然后只是压扁你的阵列。

+3

O(N^2)。加倍输入四倍运行时间:) –

+0

正确。为了我所做的事情,大O并不重要。尽管赶上! – Iggy

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
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]