2017-09-27 20 views
1

所以 #[11,13,17,23] => [13,17,19,29]給定一個數組,下一個素數

替換每個質數,如果數不是素數,則該函數返回只是我有這樣的數量 #[11,8,2,24] => [13,8,3,24]

最後一個數字(29)出了很多麻煩,出於某種原因,它將陷入無限循環。我覺得有這樣一個簡單的解決方案,但它只是逃避我。

def next_prime(arr) 
    new_arr = [] 
    arr.each do |num| 
    #puts num 
    if prime?(num) 
     p = false 
     i = num + 2 
     while !p 
     p = prime?(i) 
     i += 2 
     end 
     new_arr << i 
    else 
     new_arr << num 
    end 
    end 
    new_arr 
end 

編輯:這裏是主要功能

def prime?(num) 
    if num ==1 
    return false 
    elsif num < 3 
    return true 
    elsif num % 2 == 0 || num % 3 == 0 
    return false 
    end 


    i = 5 
    while i*i <= num 
    if num % i == 0 || num % (i + 2) == 0 
     return false 
    end 
    i += 6 
    end 
    return true 
end 
+0

你可以請發佈主要功能?也許這是29的返回false。 – Darzen

+0

我添加了上面的主要功能,並確認當調用它時,29是素數 – Yitzhak

回答

2

第一陣列工作體面對我來說,即使是29,除了一個事實,這一切都是2高於它應該是,因爲你加2勾選後,如果你有一個主要可以通過固定輕微改動代碼:

if prime?(num) 
    p = false 
    i = num 
    while !p 
    i += 2 

    p = prime?(i) 
    end 
    new_arr << i 

唯一的無限循環中我遇到的是,當你第二陣列中打2,因爲檢查素數,只需保持2遞增,所以你最終檢查每2的倍數以查看它是否爲素數。當然,你永遠也找不到的2素多個爲了解決這個問題,不是檢查下一任前由2遞增,如果加1會工作,你只需要檢查兩倍多的數字:

if prime?(num) 
    p = false 
    i = num 
    while !p 
    i += 1 

    p = prime?(i) 
    end 
    new_arr << i 

你的最後的問題是,你的prime?函數返回false爲3,其可通過改變被固定:

elsif num <= 3 
    return true 

,現在你的2個樣品得到:

[11, 13, 17, 23] => [13, 17, 19, 29] 
[11, 8, 2, 24] => [13, 8, 3, 24] 
+0

愚蠢的簡單。我只需要另一雙眼睛。謝謝。 – Yitzhak

0

我假設數組arr排序。如果不是,則保存排序值的原始索引,然後將這些索引用於對包含素數和非素數的值數組的元素重新排序。例如,如果

arr = [57, 13, 28, 6] 

然後

indices = arr.each_with_index.sort.map(&:last) 
    #=> [3, 1, 2 0] 

的主要方法的步驟如下。

  • 第1步:創建一個空數組a將由該方法返回。
  • 第2步:創建一個枚舉數,enum,它生成一個無限序列的素數(2,3,5,7,...)。生成第一個素數m = enum.next #=> 2
  • 第3步:創建一個枚舉數,earr,它們生成給定數組arr的元素。
  • 第4步:考慮數組中的下一個元素x = earr.next,它最初是數組的第一個元素。當沒有更多的數組元素時,從循環中斷開並返回數組a
  • 步驟5:如果x不是素數保存到數組aa << x)並重復步驟4;
  • 步驟6:(x爲素數)if x < m,將m保存到數組a並轉到 步驟4; (即m <= x),獲得下一個素數(m = enum.next)並重復此步驟。

require 'prime" 

def next_primes(arr) 
    enum = Prime.each 
    m = enum.next  
    earr = arr.to_enum 
    x = earr.next 
    a = [] 
    loop do 
    if x.prime? 
     if x < m 
     a << m 
     x = earr.next 
     else 
     m = enum.next 
     end 
    else 
     a << x 
     x = earr.next 
    end 
    end 
    a 
end 

next_primes([2, 6, 7, 23, 100]) 
    #=> [3, 6, 11, 29, 100] 
next_primes([2, 6, 7, 7, 100]) 
    #=> [3, 6, 11, 11, 100] 
+0

感謝您的解決方案。但是,這個問題明確指出我不能使用Prime或任何素數生成器:) – Yitzhak

+0

我沒有看到你在問題中說了什麼。無論如何,我認爲出於效率的原因,我的方法有其優點。所有人需要做的就是實現'Integer#prime?'(直接)和一個產生素數(Eratosthenes的Sieve)的枚舉器。另一種方法是檢查一個素數後面的數字,直到找到一個素數,這會比較慢。 –

0

@Cary Swoveland答案相似,但更地道的紅寶石恕我直言。

require 'prime' 

def next_primes(ary) 
    ary.map { |candidate| candidate.prime? ? next_prime(candidate) : candidate } 
end 

def next_prime(previous_prime) 
    all_primes = Prime.each 
    all_primes.find { |prime| prime > previous_prime } 
end        

next_primes([11,8,2,24]) # => [13, 8, 3, 24] 
next_primes([11,13,17,23]) # => [13, 17, 19, 29] 
+1

一個弱點是,每當搜索滿足要求的素數時,每次調用next_prime時都會從'2開始。僅通過一次枚舉就更有效率。 –

+0

同意,但是當它可能時,我總是喜歡可讀性超過效率:) – Sofa

+0

我喜歡這個解決方案的簡潔性。爲了使效率更高,您可以記錄結果。 –

相關問題