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

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

21.12.2012, 23:13. Показов 5435. Ответов 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
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,852
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
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru