Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

[C++] Нахождение простых чисел.

8.9K
20 июня 2007 года
Prince Firdavs
34 / / 22.11.2006
Вывести все простые числа от M до N включительно.
Ограничения: 2 <= M <= N <= 1 000 000, время 6 с.
(еод нужен на с++)
Благодарю за ранее

[COLOR=Red]Читай правила форума. За неправильное название темы -5. В следущий раз можно и в бан попасть. OlgaKr.[/COLOR]
8.9K
20 июня 2007 года
Prince Firdavs
34 / / 22.11.2006
нетни у кого решения по проше ведь на паскале решено просто
257
20 июня 2007 года
kosfiz
1.6K / / 18.09.2005
2Prince Firdavs
надо было немного погуглить и все. вот тебе ссылочка http://alglib.sources.ru/numbers/erat.php у меня предложенный на дельфи код отрабатывает за 2 с лишком секунды, при среднем по мощности компе.

оффтоп
[quote=Dolonet]У меня есть такая программа, давно еще делал. Выводит и в файл, и на экран. За сколько купишь?[/quote]
голодаешь? кушать нечего? совет тебе: не хочешь помогать, относишься пренебрежительно к тем кто просит помощи в Студентам и т.п.: не отвечай и не флуди, а то как то на модератора неочень похож получаешься.
350
21 июня 2007 года
cheburator
589 / / 01.06.2006
Посмотрел я алгоритм по указанной ссылке... Мда, код настолько велик, что сидит аж в zip-файле. ИМХО, очень неграмотно. Можно было использовать стандартные контейнеры из STL. Указанный код с трудом можно назвать кодом C++.
Вот мой вариант:
Код:
#include <deque>
#include <iostream>
#include <math.h>

using namespace std;

#define MAX_VAL 1000000

// Алгоритм: начинаем с числа 2. Выводим текущее число, "вычеркиваем" числа, кратные текущему, ищем следующее невычеркнутое число.
void main (void)
{
    int min_val, max_val;
    cout << "Enter left limit: ";
    cin >> min_val;
    cout << "Enter right limit: ";
    cin >> max_val;
    if (max_val > MAX_VAL || min_val < 2 || max_val < min_val)
    {
        cout << "Wrong limits";
        return;
    };
    // Поиск простых ведем до корня из max_val
    int sqrt_max_val = (int)sqrt((double)max_val);
    // Признаки "вычеркнутости" чисел (элементы 0 и 1 не используются)
    deque<bool> flags (max_val+1, false);  // первоначально все числа не перечеркнуты
    int current_value (2);
    do
    {
        if (current_value >= min_val)
            cout << current_value << endl;
        // Вычеркиваем все числа, кратные current_value, начиная с его квадрата
        for (int i = current_value * current_value; i <= max_val; i += current_value)
            flags = true;
        // Ищем следующее невычеркнутое число
        for (++current_value; current_value <= sqrt_max_val && flags[current_value]; ++current_value) ;
    } while (current_value <= sqrt_max_val);
    // Выведем все невычеркнутые числа больше корня из N, при этом не рассматриваем числа менее min_val
    for (current_value = min_val > sqrt_max_val+1 ? min_val : sqrt_max_val+1; current_value <= max_val; ++current_value)
        if (!flags[current_value])
            cout << current_value << endl;
};

Код работает долго, но только за счет вывода на экран. Без вывода все числа от 2 до миллиона генерируются менее, чем за полсекунды (Пентиум 4 - 2,4 ГГц).
Код:
#include <stdio.h>
#include <memory.h>
#include <math.h>

#pragma warning (disable: 4996)  
// Для визуал-студии. Она ругается на memset

#define MAX_VAL 1000000

// Алгоритм: начинаем с числа 2. Выводим текущее число, "вычеркиваем" числа, кратные текущему, ищем следующее невычеркнутое число.
void main (void)
{
    int min_val, max_val;
    printf ("Enter left limit: ");
    scanf ("%i", &min_val);
    printf ("Enter right limit: ");
    scanf ("%i", &max_val);
    if (max_val > MAX_VAL || min_val < 2 || max_val < min_val)
    {
        printf ("Wrong limits");
        return;
    };
    // Поиск простых ведем до корня из max_val
    int sqrt_max_val = (int)sqrt((double)max_val);
// Признаки "вычеркнутости" чисел (элементы 0 и 1 не используются)
    char *flags = 0;
    try
    {
      flags = new char [max_val+1];  
// первоначально все числа не перечеркнуты
      memset (flags, 0, max_val+1);
      int current_value (2);
      do
      {
         if (current_value >= min_val)
        printf ("%i\n", current_value);
// Вычеркиваем все числа, кратные current_value, начиная с его квадрата
    for (int i = current_value * current_value; i <= max_val; i += current_value)
    flags = true;
// Ищем следующее невычеркнутое число
    for (++current_value; current_value <= sqrt_max_val && flags[current_value]; ++current_value) ;
      } while (current_value <= sqrt_max_val);
// Выведем все невычеркнутые числа больше корня из N, при этом не рассматриваем числа менее min_val
    for (current_value = min_val > sqrt_max_val+1 ? min_val : sqrt_max_val+1; current_value <= max_val; ++current_value)
    if (!flags[current_value])
      printf ("%i\n", current_value);
    }
    catch(...)
    {
        if (flags != 0)
            delete[] flags;
    };
};

Второй вариант - есть пара проблем с языковой точки зрения: здесь перемешаны С и С++. Это касается printf/scanf и char* вместо deque (это С), и try/catch (это С++).try/catch нужен для гарантированного уничтожения char *flags.
Поиск простых от 2 до 1 000 000 происходит за 3,4 сек. с выводом на экран, и за 0,172 сек., если перенаправить вывод в файл.
Источник:
И. М. Виноградов. Основы теории чисел. Учебное пособие, 2006 г. Стр. 14.
8.9K
30 июня 2007 года
Prince Firdavs
34 / / 22.11.2006
Спасибо большое
8.9K
30 июня 2007 года
Prince Firdavs
34 / / 22.11.2006
А где выводится
19K
30 июня 2007 года
M@STeR.SoBG
10 / / 12.10.2006
Цитата: Prince Firdavs
Вывести все простые числа от M до N включительно.
Ограничения: 2 <= M <= N <= 1 000 000, время 6 с.
(еод нужен на с++)
Благодарю за ранее

[COLOR=Red]Читай правила форума. За неправильное название темы -5. В следущий раз можно и в бан попасть. OlgaKr.[/COLOR]



Посмотри вот этот код еще. Может это то, что тебе нужно...

Код:
#include<cstdio>
#include<cmath>

using namespace std;

#define UPPERBOARD 1000

int mas[168], size = 0;

bool flag;

void makePrecalc()
{  
    for( int i = 2; i <= UPPERBOARD; ++i)
    {
        flag = 1;
        for( int j = 2; j <= sqrt((double)i); ++j)
            if( !(i % j) )
            {
                flag = 0;
                break;
            }
        if( flag )
            mas[ size++ ] = i;
    }
}
void generate(int m, int n)
{
    makePrecalc(); 
    bool isPrimeIntegers = 0;
    for( int i = m; i <= n ;++i )
    {
        flag = 1;
        for( int j = 0; j < size && mas[ j ] <= sqrt((double) i ); ++j)
            if( !(i % mas[ j ]) )
            {
                flag = 0;
                break;
            }
        if( flag )
        {
            isPrimeIntegers = 1;
            printf("%d\n", i);
        }
    }
    if( !isPrimeIntegers )
        printf("Absent");
}
int main()
{
    freopen("input.txt", "r", stdin);
    freopen("output.txt","w", stdout);
    int m, n;
    scanf("%d%d", &m, &n);
    generate(m, n);
    return 0;
}
350
06 июля 2007 года
cheburator
589 / / 01.06.2006
Цитата: Prince Firdavs
А где выводится


Фирдаус, по моим подсчетам, примерно 29-я строка. Привожу собственно код, который выводит:

 
Код:
if (current_value >= min_val)
  cout << current_value << endl;

Короче, алгоритм такой. Пользователь может потребовать, чтобы я вывел ему числа, скажем, от 100 000 до миллиона, но я все равно подсчитываю числа от 2 до миллиона. Просто не вывожу числа, меньшие 100 000. В данном случае - 100 000 - это min_val.
2.7K
10 июля 2007 года
barracuda
76 / / 29.03.2004
Работает 1 - 2 секунды

Код:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
{
unsigned long count=0;
char ss[256];

unsigned long *m = (unsigned long*)new char[500000*sizeof(unsigned long)];
memset((void*)m, 0, 500000*sizeof(unsigned long));

MessageBox(NULL, "Начать", "Program", 0);

for(unsigned long i=3; i<1000000; i+=2){
double sq = sqrt(i);
    for(unsigned long ii=0;ii<500000; ii++)
        if(m[ii] > sq || !m[ii]) {m[count++] = i; break;}
        else if(!(i%m[ii]))break;
}

MessageBox(NULL, "Закончил", "Program", 0);

ofstream logOut;
logOut.open("prime.txt",ios::binary);
if(!logOut.bad())
for(unsigned long ii=0;ii<count; ii++)
{
    sprintf(ss, "%u\r\n", m[ii]);
    logOut.write(ss, strlen(ss));
}
logOut.close();

delete m;
return 0;
}
320
05 августа 2007 года
m_Valery
1.0K / / 08.01.2007
Всем спасибо за участие.Кто хочет выложить свои коды на С и Делфи может сделать это в разделе Исходники.Если кому то интересно, еще раз обсудить алгоритмы нахождения простых чисел - он может создать отдельную тему.
Тему закрываю,поскольку уже не первый раз в ней возникают не нужные разговоры.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог