Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.88/26: Рейтинг темы: голосов - 26, средняя оценка - 4.88
0 / 0 / 0
Регистрация: 26.09.2012
Сообщений: 38

Динамический массив, много циклов и простые числа. Как ускорить работу программы ?

21.12.2012, 23:13. Показов 5501. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет.
Задание следующее: Кто нибудь вводит с клавиатуры число n и k, должен создастся массив из чисел от 1 до n, далее каждый элемент массива должен проверится на деление на квадрат простых чисел (*), если делится - сделать этот элемент нулем. Далее нужно посчитать количество q не нулевых элементов и количество h не нулевых элементов с шагом k (**). В конце должно вывести на экран число-результат деления h на q.

(*)допустим кто нибудь ввел с клавиатуры 10 и 2 (n=10, k=2), создался массив с содержанием - 1 2 3 4 5 6 7 8 9 10, далее программа должна выявить какие элементы делятся на квадрат простых чисел (без остатка) и обнулить эти элементы, в данном случае массив будет таким: 1 2 3 0 5 6 7 0 0 10 (число 4 делится на квадрат простого числа 2, число 8 делится на квадрат простого числа 2, число 9 делится на квадрат простого числа 3).
(**)из примера выше получается что q=7 (семь не нулевых элементов), а h=4. Теперь поясняю про h и k:
допустим у нас получился массив 1 2 3 0 5 6 7 0 0 10, начинаем перебирать все элементы от первого и шагом k, получается 1, 3, 5, 7, 0. В результате будет h/q=0.571...

Мой вариант:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <iostream>
using namespace std;
 
int main()
{
    int n, k; 
    double q=0, h=0; //q-счетчик не нулевых элементов, h-счетчик не нулевых элементов с шагом k
    int counter=0; //побочный счетчик для нахождения простых чисел
    cout<<"Enter n=";
    cin>>n;
    cout<<"Enter k=";
    cin>>k;
    int *arr=new int[n]; //создаем динамический массив с размером n
    for(int i=0; i<n; i++) //цикл присвоения элементам массива чисел от 1 до n
        arr[i]=i+1;
    for(int i=0; i<n; i++) //цикл вывода массива на экран
cout<<arr[i]<<" ";
    cout<<endl;
for(int i=0; i<n; i++) //цикл перебора всех элементов массива
{
    for(int z=1; z!=arr[i]; z++) //цикл нахождения всех простых чисел от 2 до arr[i] (элемента массива с которым мы работаем)
    {
        counter=0;
        for(int j=1; j!=z+1; j++) //цикл проверки числа на простоту
        {
            if(z%j==0)
                counter++;
        }
        if(counter==2) //если число делится на единицу и на само себя (делилось всего 2 раза), значит оно простое
        {
            if(arr[i]%(z*z)==0) //если элемент массива делится на квадрат простого числа - выйти из цикла и проверять следующий элемент
            {
                arr[i]=0;
                break;
            }
        }
    }
}
for(int i=0; i<n; i++) //цикл подсчета не нулевых элементов
if(arr[i]!=0)
q++;
for(int i=0; i<n; i+=k) //цикл подсчета не нулевых элементов с шагом k
if(arr[i]!=0)
h++;
cout<<"--------"<<endl;
for(int i=0; i<n; i++) //цикл вывода массива на экран
cout<<arr[i]<<" ";
cout<<endl;
cout<<"h="<<h<<endl;
cout<<"q="<<q<<endl;
cout<<"h/q="<<h/q<<endl;
system("pause");
return 0;
}
Проблема в следующем: при n=1000 и меньше считает нормально, а если увеличивать n, программа работает оооочень долго. Какие изменения нужно внести что бы программа работала быстрее (хотя бы с n=10000)?

PS: для тех кто подзабыл - простые числа, это числа которые делятся только на единицу и на самих себя (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43 и т.д.)
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
21.12.2012, 23:13
Ответы с готовыми решениями:

как ускорить работу программы, если элементов много
Есть такое задание: Найти медиану в массиве. The median is the middlemost element of the array when sorted. For simplicity, when an...

Ускорить работу программы, содержащей много сессий
Это мой первый проект, поэтому я использовал много сессий и тд, при этом сайт теперь работает 10+ секунд при любом нажатии на...

Как можно ускорить работу макроса Excel с большим кол-вом итерационных циклов?
Есть задача, которую решил, но хотел бы ускорить работу. Проблема в том что суть программы пройти по строкам и столбцам в 1 таблице,...

13
Мой лучший друг-отладчик!
 Аватар для ZaMaZaN4iK
167 / 167 / 30
Регистрация: 24.06.2012
Сообщений: 662
Записей в блоге: 5
21.12.2012, 23:49
Ну, можно цикл загона значений в массив и вывод массива обьеденить в 1 цикл - зачем лишний раз пробегать по массиву.
Потом ещё надо удалить из памяти динамический массив.
0
0 / 0 / 0
Регистрация: 26.09.2012
Сообщений: 38
21.12.2012, 23:56  [ТС]
ZaMaZaN4iK, точно, забыл удалить динамический массив! counter нужен для следующего: что бы проверить простое ли число или нет, нужно делить это число на все числа от 1 до самого числа и если оно делилось всего 2 раза (counter==2, на единицу и на само себя), значит оно простое. В начале проверки каждого нового простого числа этот счетчик нужно обнулить.
Придумал! Можно попробовать сделать проверку простого числа не до самого числа, а до корня из него.

Добавлено через 2 минуты
Новая, улучшенная версия:

Добавлено через 1 минуту
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <math.h>
using namespace std;
 
int main()
{
    int n, k; 
    double q=0, h=0; //q-счетчик не нулевых элементов, h-счетчик не нулевых элементов с шагом k
    int counter=0; //побочный счетчик для нахождения простых чисел
    cout<<"Enter n=";
    cin>>n;
    cout<<"Enter k=";
    cin>>k;
    int *arr=new int[n]; //создаем динамический массив с размером n
    for(int i=0; i<n; i++) //цикл присвоения элементам массива чисел от 1 до n
    {
        arr[i]=i+1;
        cout<<i+1<<" ";
    }
    cout<<endl;
for(int i=0; i<n; i++) //цикл перебора всех элементов массива
{
    for(int z=1; z!=arr[i]; z++) //цикл нахождения всех простых чисел от 2 до arr[i] (элемента массива с которым мы работаем)
    {
        counter=0;
        for(int j=1; j<sqrt((float)z); j++) //цикл проверки числа на простоту
        {
            if(z%j==0)
                counter++;
        }
        if(counter==1) //если число делится на единицу и на само себя (делилось всего 2 раза), значит оно простое
        {
            if(arr[i]%(z*z)==0) //если элемент массива делится на квадрат простого числа - выйти из цикла и проверять следующий элемент
            {
                arr[i]=0;
                break;
            }
        }
    }
}
for(int i=0; i<n; i++) //цикл подсчета не нулевых элементов
if(arr[i]!=0)
q++;
for(int i=0; i<n; i+=k) //цикл подсчета не нулевых элементов с шагом k
if(arr[i]!=0)
h++;
cout<<"--------"<<endl;
for(int i=0; i<n; i++) //цикл вывода массива на экран
cout<<arr[i]<<" ";
cout<<endl;
cout<<"h="<<h<<endl;
cout<<"q="<<q<<endl;
cout<<"h/q="<<h/q<<endl;
delete[] arr;
system("pause");
return 0;
}
}
Изменил проверку чисел на простоту до корня из этого числа, добавил удаление массива из памяти.
Интересуют реально действенные способы ускорения работы программы.
0
Мой лучший друг-отладчик!
 Аватар для ZaMaZaN4iK
167 / 167 / 30
Регистрация: 24.06.2012
Сообщений: 662
Записей в блоге: 5
21.12.2012, 23:57
я тут пару циклов поубирал
0
0 / 0 / 0
Регистрация: 26.09.2012
Сообщений: 38
21.12.2012, 23:58  [ТС]
Исправил. Есть еще какие нибудь идеи ?
0
Мой лучший друг-отладчик!
 Аватар для ZaMaZaN4iK
167 / 167 / 30
Регистрация: 24.06.2012
Сообщений: 662
Записей в блоге: 5
22.12.2012, 00:01
слушайте, а может надо воспользоватся решетом Аткина для нахождения простых чисел от 1 до n, загонять их в массив.А потом пробегатся по массиву и сравнивать - если совпало - делаем нужные действия
0
0 / 0 / 0
Регистрация: 26.09.2012
Сообщений: 38
22.12.2012, 00:03  [ТС]
Знаю другое решето - Эратосфена. Сейчас попробую что нибудь придумать, но придется все переписывать заново.
0
Мой лучший друг-отладчик!
 Аватар для ZaMaZaN4iK
167 / 167 / 30
Регистрация: 24.06.2012
Сообщений: 662
Записей в блоге: 5
22.12.2012, 00:05
решето Эратосфена уступает по быстродействию решету Аткина.на cybern.ru есть реализация решета.Вот она:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <math.h>
#include <ctime>
using namespace std;
int main()
{
     int limit = 10001;
     int sqr_lim;
     bool is_prime[10002];
     int x2, y2;
     int i, j;
     int n;
     sqr_lim = (int)sqrt((long double)limit);
     for (i = 0; i <= limit; i++) 
         is_prime[i] = false; // Инициализация решета
     is_prime[2] = true;
     is_prime[3] = true;
// Предположительно простые - это целые с нечетным числом
// представлений в данных квадратных формах.
// x2 и y2 - это квадраты i и j (оптимизация).
     x2 = 0;
     for (i = 1; i <= sqr_lim; i++) 
     {
         x2 += 2 * i - 1;
         y2 = 0;
         for (j = 1; j <= sqr_lim; j++) 
         {
             y2 += 2 * j - 1;
             n = 4 * x2 + y2;
             if ((n <= limit) && (n % 12 == 1 || n % 12 == 5))
                 is_prime[n] = !is_prime[n];
             // n = 3 * x2 + y2; 
             n -= x2; // Оптимизация
             if ((n <= limit) && (n % 12 == 7))
                 is_prime[n] = !is_prime[n];
             // n = 3 * x2 - y2;
             n -= 2 * y2; // Оптимизация
             if ((i > j) && (n <= limit) && (n % 12 == 11))
                 is_prime[n] = !is_prime[n];
         }
     }
// Отсеиваем кратные квадратам простых чисел в интервале [5, sqrt(limit)].
// (основной этап не может их отсеять)
     for (i = 5; i <= sqr_lim; i++) 
     {
         if (is_prime[i]) 
         {
             n = i * i;
             for (j = n; j <= limit; j += n) 
             {
                 is_prime[j] = false;
             }
         }
     }
// Вывод списка простых чисел в консоль.
     printf("2 3 5"); 
     for (i = 6; i <= limit; i++) // проверка делимости на 3 и 5
     { 
         if ((is_prime[i]) && (i % 3 != 0) && (i % 5 != 0))
         {
             printf(" %d", i);
         }
     } 
     cin>>n;
}
0
0 / 0 / 0
Регистрация: 26.09.2012
Сообщений: 38
22.12.2012, 00:06  [ТС]
Спасибо! Попробую разобраться.
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,870
22.12.2012, 00:10
Цитата Сообщение от Alejo Посмотреть сообщение
for(int j=1; j!=z+1; j++) //цикл проверки числа на простоту
* * * * {
* * * * * * if(z%j==0)
* * * * * * * * counter++;
* * * * }
вот здесь можно убыстрить
проверять только до корня из z если есть делитель больше корня значит есть делитель меньше корня
поищи здесь постоянно возникают темы про простое число
а для чисел n=10000 можно рассчитать таблицу простых чисел( а лучше сразу квадратов)
в начале программы или набить вручную
0
Мой лучший друг-отладчик!
 Аватар для ZaMaZaN4iK
167 / 167 / 30
Регистрация: 24.06.2012
Сообщений: 662
Записей в блоге: 5
22.12.2012, 00:14
вот вроде неплохой вариант(относительно быстро работает, без решет)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include <cmath>
using namespace std;
 
int main()
{
    int n, k; 
    double q=0, h=0; //q-счетчик не нулевых элементов, h-счетчик не нулевых элементов с шагом k
    int counter=0; //побочный счетчик для нахождения простых чисел
    cout<<"Enter n=";
    cin>>n;
    cout<<"Enter k=";
    cin>>k;
    int *arr=new int[n]; //создаем динамический массив с размером n
    for(int i=0; i<n; i++) //цикл присвоения элементам массива чисел от 1 до n
        arr[i]=i+1;
    for(int i=0; i<n; i++) //цикл вывода массива на экран
        cout<<arr[i]<<" ";
    cout<<endl;
for(int i=0; i<n; i++) //цикл перебора всех элементов массива
{
    for(int z=1; z!=arr[i]; z++) //цикл нахождения всех простых чисел от 2 до arr[i] (элемента массива с которым мы работаем)
    {
        counter=0;
        int kor=int(sqrt(float(z+1)));
        for(int j=1; j!=kor; j++) //цикл проверки числа на простоту
        {
            if(z%j==0)
            {
                counter++;
                if(counter > 2)
                break;
            }
        }
        if(counter==2) //если число делится на единицу и на само себя (делилось всего 2 раза), значит оно простое
        {
            if(arr[i]%(z*z)==0) //если элемент массива делится на квадрат простого числа - выйти из цикла и проверять следующий элемент
            {
                arr[i]=0;
                break;
            }
        }
    }
}
cout<<"--------"<<endl;
for(int i=0,j=0; i<n; i++,j+=k) //цикл подсчета не нулевых элементов
{
    cout<<arr[i]<<" ";
    if(arr[i]!=0)
        q++;
    if(j<n && arr[i]!=0)
        h++;
}
cout<<endl;
cout<<"h="<<h<<endl;
cout<<"q="<<q<<endl;
cout<<"h/q="<<h/q<<endl;
system("pause");
return 0;
}
Добавлено через 1 минуту
ValeryS, вот эта идея мне сразу и закралась в голову - расчитать таблицу простых чисел до нужного числа сразу при помощи готового быстродействующего алгоритма(Аткина)
1
0 / 0 / 0
Регистрация: 26.09.2012
Сообщений: 38
22.12.2012, 00:22  [ТС]
ZaMaZaN4iK, Спасибо за поправки.
Есть вопрос: sqrt((float)z) знаю что нужно писать так, но не очень понимаю что здесь происходит. В VC 6.0 я просто писал sqrt(n), в новых версиях так делать нельзя.
0
Мой лучший друг-отладчик!
 Аватар для ZaMaZaN4iK
167 / 167 / 30
Регистрация: 24.06.2012
Сообщений: 662
Записей в блоге: 5
22.12.2012, 00:33
просто функция sqrt принимает переменные дробно типа(double, float, long double), а z у нас целого типа - компилятор ругается.А строкой float(z) мы запихиваем в функцию sqrt() переменную z типа float, но при этом тип самой переменной z не менятеся
0
0 / 0 / 0
Регистрация: 26.09.2012
Сообщений: 38
22.12.2012, 00:34  [ТС]
Всем спасибо за помощь! Все таки не буду переделывать работу, с внесенными поправками даже при n=сто_тысяч программа выполняется относительно быстро.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
22.12.2012, 00:34
Помогаю со студенческими работами здесь

Как ускорить работу программы
Доброго времени суток! Разработал первую программу для logo! на FBD. На симуляторе все нормально. После установки на оборудование...

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

Подскажите пожалуйста как ускорить работу программы!
Есть задача :&quot;Во входном файле (вы можете читать данные из файла input.txt) записан текст. Словом считается последовательность непробельных...

Подскажите, как можно ускорить работу программы
Условие: Первая строка входных данных содержит натуральное число N - количество элементов массива (1 ≤ N ≤ 1000). Следующая...

Ускорить работу excel, когда в ячейках много пользовательских функций на VBA
Когда вставляю в большое количество ячеек даже относительно простые функции на VBA, Excel всё равно начинает очень сильно тормозить...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru