Программа для поиска простых чисел

Эти ответы помогли мне решить ту же проблему. Хотя моя проблема была более сложной, так как я использовал SASS и GULP.

Мне пришлось изменить (обратите внимание на «\» перед #. Вероятно, побочный эффект от gulp:

 <h:outputStylesheet library="my_theme" name="css/default.css"/>  

 background: $blue url("\#{resource['my_theme/images/background-homepage-h1.png']}");
29
задан Bill the Lizard 17 September 2012 в 13:17
поделиться

7 ответов

Вы можете сделать это быстрее, используя почти оптимальное сито пробного деления в одной (длинной) строке, например:

Enumerable.Range(0, Math.Floor(2.52*Math.Sqrt(num)/Math.Log(num))).Aggregate(
    Enumerable.Range(2, num-1).ToList(), 
    (result, index) => { 
        var bp = result[index]; var sqr = bp * bp;
        result.RemoveAll(i => i >= sqr && i % bp == 0); 
        return result; 
    }
);

Используемая здесь формула аппроксимации для количества простых чисел следующая π (x) <1,26 x / ln (x) . Нам нужно только проверить с помощью простых чисел не больше, чем x = sqrt (num) .

Обратите внимание, что сито Эратосфена имеет гораздо лучшую временную сложность выполнения, чем пробное деление (должно выполняться намного быстрее для больших значений num при правильной реализации).

77
ответ дан 27 November 2019 в 21:22
поделиться

Очень похоже - из упражнения по реализации Решета Эратосфена в C #:

public class PrimeFinder
{
    readonly List<long> _primes = new List<long>();

    public PrimeFinder(long seed)
    {
        CalcPrimes(seed);
    }

    public List<long> Primes { get { return _primes; } }

    private void CalcPrimes(long maxValue)
    {
        for (int checkValue = 3; checkValue <= maxValue; checkValue += 2)
        {
            if (IsPrime(checkValue))
            {
                _primes.Add(checkValue);
            }
        }
    }

    private bool IsPrime(long checkValue)
    {
        bool isPrime = true;

        foreach (long prime in _primes)
        {
            if ((checkValue % prime) == 0 && prime <= Math.Sqrt(checkValue))
            {
                isPrime = false;
                break;
            }
        }
        return isPrime;
    }
}
0
ответ дан 27 November 2019 в 21:22
поделиться

Пахнет домашней работой. В моем очень-очень старом графическом калькуляторе была такая простая программа. Технически цикл проверки внутреннего устройства должен выполняться только до i ^ (1/2). Вам нужно найти «все» простые числа от 0 до L? Другая серьезная проблема заключается в том, что ваши переменные цикла имеют значение "int", в то время как ваши входные данные "длинные", это вызовет переполнение, из-за которого ваши циклы не выполнятся ни разу. Исправьте переменные цикла.

5
ответ дан 27 November 2019 в 21:22
поделиться

It may just be my opinion, but there's another serious error in your program (setting aside the given 'prime number' question, which has been thoroughly answered).

Like the rest of the responders, I'm assuming this is homework, which indicates you want to become a developer (presumably).

You need to learn to compartmentalize your code. It's not something you'll always need to do in a project, but it's good to know how to do it.

Your method prime_num(long num) could stand a better, more descriptive name. And if it is supposed to find all prime numbers less than a given number, it should return them as a list. This makes it easier to seperate your display and your functionality.

If it simply returned an IList containing prime numbers you could then display them in your main function (perhaps calling another outside function to pretty print them) or use them in further calculations down the line.

So my best recommendation to you is to do something like this:

public void main(string args[])
{
    //Get the number you want to use as input
    long x = number;//'number' can be hard coded or retrieved from ReadLine() or from the given arguments

    IList<long> primes = FindSmallerPrimes(number);

    DisplayPrimes(primes);
}

public IList<long> FindSmallerPrimes(long largestNumber)
{
    List<long> returnList = new List<long>();
    //Find the primes, using a method as described by another answer, add them to returnList
    return returnList;
}

public void DisplayPrimes(IList<long> primes)
{
    foreach(long l in primes)
    {
        Console.WriteLine ( "Prime:" + l.ToString() );
    }
}

Even if you end up working somewhere where speration like this isn't needed, it's good to know how to do it.

6
ответ дан 27 November 2019 в 21:22
поделиться

People have mentioned a couple of the building blocks toward doing this efficiently, but nobody's really put the pieces together. The sieve of Eratosthenes is a good start, but with it you'll run out of memory long before you reach the limit you've set. That doesn't mean it's useless though -- when you're doing your loop, what you really care about are prime divisors. As such, you can start by using the sieve to create a base of prime divisors, then use those in the loop to test numbers for primacy.

When you write the loop, however, you really do NOT want to us sqrt(i) in the loop condition as a couple of answers have suggested. You and I know that the sqrt is a "pure" function that always gives the same answer if given the same input parameter. Unfortunately, the compiler does NOT know that, so if use something like '<=Math.sqrt(x)' in the loop condition, it'll re-compute the sqrt of the number every iteration of the loop.

You can avoid that a couple of different ways. You can either pre-compute the sqrt before the loop, and use the pre-computed value in the loop condition, or you can work in the other direction, and change i to i*i. Personally, I'd pre-compute the square root though -- I think it's clearer and probably a bit faster--but that depends on the number of iterations of the loop (the i*i means it's still doing a multiplication in the loop). With only a few iterations, i*i will typically be faster. With enough iterations, the loss from i*i every iteration outweighs the time for executing sqrt once outside the loop.

That's probably adequate for the size of numbers you're dealing with -- a 15 digit limit means the square root is 7 or 8 digits, which fits in a pretty reasonable amount of memory. On the other hand, if you want to deal with numbers in this range a lot, you might want to look at some of the more sophisticated prime-checking algorithms, such as Pollard's or Brent's algorithms. These are more complex (to put it mildly) but a lot faster for large numbers.

There are other algorithms for even bigger numbers (quadratic sieve, general number field sieve) but we won't get into them for the moment -- they're a lot more complex, and really only useful for dealing with really big numbers (the GNFS starts to be useful in the 100+ digit range).

9
ответ дан 27 November 2019 в 21:22
поделиться

Вам нужно только проверить нечетные делители до квадратного корня из номер. Другими словами, ваш внутренний цикл должен запуститься:

for (int j = 3; j <= Math.Sqrt(i); j+=2) { ... }

Вы также можете выйти из функции, как только обнаружите, что число не является простым, вам не нужно больше проверять делители (я вижу, вы уже делаете это!).

Это будет работать, только если num больше двух.

No Sqrt

Вы можете полностью избежать Sqrt, сохранив текущую сумму. Например:

int square_sum=1;
for (int j=3; square_sum<i; square_sum+=4*(j++-1)) {...}

Это потому, что сумма чисел 1+ (3 + 5) + (7 + 9) даст вам последовательность нечетных квадратов (1,9,25 и т. Д.). Следовательно, j представляет собой квадратный корень из square_sum . Пока square_sum меньше i , тогда j меньше квадратного корня.

9
ответ дан 27 November 2019 в 21:22
поделиться

Попробуйте следующее:

void prime_num(long num)
{

    // bool isPrime = true;
    for (long i = 0; i <= num; i++)
    {
        bool isPrime = true; // Move initialization to here
        for (long j = 2; j < i; j++) // you actually only need to check up to sqrt(i)
        {
            if (i % j == 0) // you don't need the first condition
            {
                isPrime = false;
                break;
            }
        }
        if (isPrime)
        {
            Console.WriteLine ( "Prime:" + i );
        }
        // isPrime = true;
    }
}
24
ответ дан 27 November 2019 в 21:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: