2016-07-28 135 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]