2014-12-19 2 views
4

Я пытаюсь написать метод, который возвращает n-е простое число.Как создать метод, который возвращает n-мерное число?

Я разработал решение, но проблема в моем методе. Я создаю большой массив чисел, который, кажется, обрабатывается очень медленно. (1..104729).to_a, если быть точным. Я выбрал 104729, потому что max n может быть 10000, а 10000-е число - 104729. Я ищу способ оптимизации моего метода.

Это 104729 слишком большое значение? Есть ли способ написать это, чтобы я не создавал большой массив?

Вот метод:

def PrimeMover(num) 

    def is_prime(x) 
    i = 0 
    nums = (2..x).to_a 
    while nums[i] < nums.max 
     if x % nums[i] != 0 
     i += 1 
     else 
     return false 
     end 
    end 
    return true 
    end 

    primes_arr = (3..104729).to_a.select {|y| is_prime(y)} 

    primes_arr[num] 

end 
+0

Возможный дубликат [Как создать первые n простых чисел?] (Http://stackoverflow.com/questions/11673968/how-do-i-generate-the-first-n-prime-numbers) – Humza

ответ

0

Вы можете использовать Руби built in #prime? method, который кажется довольно эффективным.

Код:

require 'prime' 
primes_arr = (3..104729).to_a.select &:prime? 

работает в 2-3 секунды на моей машине, которые я нахожу несколько приемлемым.

Если вам нужна еще более высокая производительность или вам действительно нужно написать свой собственный метод, попробуйте реализовать Sieve of Erathostenes. Вот некоторые Рубиновые образцы, которые: http://rosettacode.org/wiki/Sieve_of_Eratosthenes#Ruby

+0

Вау. Мне потребовалось навсегда создать этот главный метод. Поэтому 'require 'prime'' вызывает основной метод? и является 'select &: prime?' другим способом записи '.select {| x | x.prime?} ' – user3640511

+1

@ user3640511: Нет, оператор' require' просто определяет необходимый класс, чтобы вы могли его использовать; в стандартной библиотеке есть много классов, которые недоступны, не требуя их. И да, 'select (&: prime?)' Является сокращением для 'select {| x | x.prime?} '. –

+0

Нет.Вызов метода выглядит так: 'expr.meth (args)' или 'expr.meth args', который вызывает метод' meth' на объекте, возвращаемом путем вычисления выражения 'expr', передающего' args' в качестве аргумента. Вы можете оставить приемник, и в этом случае подразумевается 'self', это выглядит так:' meth (args) 'или' meth args'. Итак, 'require 'prime'' вызывает метод' require', передавая строковый литерал '' prime'' в качестве аргумента. 'require' загружает скрипт Ruby или расширение интерпретатора из' $ LOAD_PATH', в этом случае он загружает файл из стандартной библиотеки Ruby. –

5

Объединить Рубин встроенный prime library и lazy enumerator для исполнения:

require 'prime' 
(1...100_000).lazy.select(&:prime?).take(100).to_a 

Или просто, как было подчеркнуто Артуро:

Prime.take(100) 
+0

Спасибо! Я точно не понимаю счетчиков и не видел ленивого или взятого метода. Посмотрим сейчас. Цените помощь. – user3640511

+2

Использование 'lazy' очень полезно при работе с большими диапазонами. Взрыв диапазона в массив может поглотить много памяти и взять машину на колени, тогда как использование «ленивого» помогает избежать этого. –

9
require "prime" 

def find_prime(nth) 
    Prime.take(nth).last 
end 
+1

Это должен быть выбранный ответ. – Humza

1

Вот оптимальный осуществление пробного деления is_prime, не полагаясь на Prime класс:

Простое число - это целое число, делящееся только на 1 и само по себе, а 1 не является простым. Поэтому мы хотим знать, делится ли x на что-либо меньшее, чем х, и больше 1. Итак, мы начинаем отсчет в 2, и заканчиваем на x - 1.

def prime?(x) 
    return false if x < 2 
    2.upto(x - 1) do |n| 
    return false if (x % n).zero? 
    end 
    true 
end 

Как только x % n есть остаток, мы можем разорвать петлю и сказать, что это число не является простым. Это избавит вас от цикличности по всему диапазону. Если все возможные числа были исчерпаны, мы знаем, что число является простым.

Это еще не оптимально. Для этого вам понадобится sieve или другой алгоритм обнаружения для пробного деления. Но это большое улучшение в вашем коде. Принимая n-й до вас.

+1

Thumbs up for the effort, но обратите внимание, что 'prime' - это не внешняя библиотека, а встроенный stdlib, который по умолчанию не загружается. –

+0

@BorisStitnicky ahh, спасибо, что указали это. Я думал, что это не часть stdlib. – Mohamad

+1

Приятно, но определенно не оптимально. Вы делаете пробное деление слишком большим количеством чисел. – DanaJ

Смежные вопросы