Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.71/7: Рейтинг темы: голосов - 7, средняя оценка - 4.71
Sheptashka
0 / 0 / 0
Регистрация: 21.03.2012
Сообщений: 22
1

Оптимизация цикла (перебор 5000000 элементов)

02.06.2012, 23:59. Просмотров 1456. Ответов 12
Метки нет (Все метки)

Можно ли как-то оптимизировать данный цикл?
C++
1
2
3
4
5
6
7
8
for (i=10000000; i<15000000; i++)
{
for (k = i, j = 0; j < 8; j++, k /= 10)
           mas[j] = k % 10;
 
        if (mas[0]+mas[1]+mas[2] + mas[3] == mas[4]+mas[5]+mas[6]+mas[7])
            sum_a++;
}
Где, i = Номер какого-то 8-значного числа.
j- счётчик для заполнения mas.
k - счётчик для деления.

Можно что-нибудь придумывать, что бы сравнивать суммы чисел, но применяя меньше делений?

(При переборе 5000000 элементов по времени очень долго и программа не укладывается во времени)

Заранее спасибо
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.06.2012, 23:59
Ответы с готовыми решениями:

Перебор без цикла
Доброго времени суток. У меня есть следующий код: for (int i = 0; i &lt; 10; i++) for (int j =...

Оптимизация цикла for
Исходные данные: имеется цикл for, прерывание которого невозможно(должен выполнить все итерации)....

Оптимизация цикла for
Скажите, пожалуйста, как оптимизируется первый цикл? И чем он отличается от второго? Первый цикл:...

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

Оптимизация условия цикла while
Доброго времени суток, друзья! Я еще совсем новичок в С++. Подскажите плз как оптимизировать...

12
KeyGen
385 / 292 / 21
Регистрация: 07.08.2011
Сообщений: 790
Записей в блоге: 1
03.06.2012, 00:04 2
Так нехорошо писать:
C++
1
for (k = i, j = 0; j < 8; j++, k /= 10)
Что на выходе должно быть?

mas[j] = k % 10; - не совсем понятно
0
Sheptashka
0 / 0 / 0
Регистрация: 21.03.2012
Сообщений: 22
03.06.2012, 00:06  [ТС] 3
На выходе должно быть число, которое показывает, количество "счастливых" чисел
т.е.
a1+a2+a3+a4==a5+a6+a7+a8

mas[j] = k % 10; - не совсем понятно
В цикле, каждый раз число уменьшается на 1 разряд. И берётся остаток от деления на 10
Получается что в каждый m[j] пошагово заносятся числа

Например
число 12345678
будет
m[0]=1;
m[1]=2;
m[2]=3;
и т.д
0
KeyGen
385 / 292 / 21
Регистрация: 07.08.2011
Сообщений: 790
Записей в блоге: 1
03.06.2012, 00:30 4
Sheptashka, а если использовать не число а string? Проще будет...
0
03.06.2012, 00:30
Sheptashka
0 / 0 / 0
Регистрация: 21.03.2012
Сообщений: 22
03.06.2012, 00:32  [ТС] 5
Цитата Сообщение от KeyGen Посмотреть сообщение
Sheptashka, а если использовать не число а string? Проще будет...
А как стринг перебирать?
0
valeriikozlov
Эксперт С++
4693 / 2519 / 751
Регистрация: 18.08.2009
Сообщений: 4,550
03.06.2012, 07:04 6
Sheptashka, нужно пользоваться поиском - эта задача была здесь уже и оптимальное решение уже выкладывалось.
Для 8-мизначных билетов делаете так: заводите массив
C++
1
int a[37]={0};// все элементы массива изначально должны быть равны 0
.
Далее цикл:
C++
1
2
3
4
5
for(i=0; i<10000; i++)
{
    // здесь вычисляете сумму цифр каждого i (заносите эту сумму например в переменную t)
    a[t]++;
}
А в конце:
C++
1
2
3
4
int res=0;
for(i=0; i<37; i++)
  res+=a[i]*a[i];
//здесь в переменной res нужный результат
1
KeyGen
385 / 292 / 21
Регистрация: 07.08.2011
Сообщений: 790
Записей в блоге: 1
03.06.2012, 10:52 7
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
    int size = 12345678;
 
    QString temp;
    for(int i = size; i<87654321; i++)
    {
        temp.setNum(i);
        int one = temp.at(0).digitValue() + temp.at(1).digitValue() + temp.at(2).digitValue() + temp.at(3).digitValue();
        int two = temp.at(4).digitValue() + temp.at(5).digitValue() + temp.at(6).digitValue() + temp.at(7).digitValue();
 
        if(one == two)
            qDebug() << i;
    }
1
Sheptashka
0 / 0 / 0
Регистрация: 21.03.2012
Сообщений: 22
03.06.2012, 12:05  [ТС] 8
Цитата Сообщение от valeriikozlov Посмотреть сообщение
Далее цикл:
Код C++
for(i=0; i<10000; i++)
{
* * // здесь вычисляете сумму цифр каждого i (заносите эту сумму например в переменную t)
* * a[t]++;
}
Немножко не понял для чего этот цикл, можно поподробнее?
0
valeriikozlov
Эксперт С++
4693 / 2519 / 751
Регистрация: 18.08.2009
Сообщений: 4,550
03.06.2012, 19:59 9
Цитата Сообщение от Sheptashka Посмотреть сообщение
Немножко не понял для чего этот цикл, можно поподробнее?
можно.
Для решения этой задачи нужно знать сколько сколько каких сумм будет получаться в левой половине. Всего сумм может быть 37 (от 0 до 36): Число с суммой 0000 - минимальная сумма, число 9999 - максимальная сумма (сумма цифр равна 36).
В данном цикле расчитывается сколько каких сумм встречается в левой половине 8-ми значного числа. Например a[0] в конце цикла будет равно 1: соответствует числу 0000.
Или например a[1] в конце цикла будет равно 4: соответсвует числам 0001, 0010, 0100, 1000.
И т.д.
0
Sheptashka
0 / 0 / 0
Регистрация: 21.03.2012
Сообщений: 22
03.06.2012, 22:39  [ТС] 10
Цитата Сообщение от valeriikozlov Посмотреть сообщение
можно.
Для решения этой задачи нужно знать сколько сколько каких сумм будет получаться в левой половине. Всего сумм может быть 37 (от 0 до 36): Число с суммой 0000 - минимальная сумма, число 9999 - максимальная сумма (сумма цифр равна 36).
В данном цикле расчитывается сколько каких сумм встречается в левой половине 8-ми значного числа. Например a[0] в конце цикла будет равно 1: соответствует числу 0000.
Или например a[1] в конце цикла будет равно 4: соответсвует числам 0001, 0010, 0100, 1000.
И т.д.
Будет ли это работать, если я задам ленту (начало и конец ленты) билетов сам?
Например с 30000000 до 35000000.
0
valeriikozlov
Эксперт С++
4693 / 2519 / 751
Регистрация: 18.08.2009
Сообщений: 4,550
03.06.2012, 23:07 11
Цитата Сообщение от Sheptashka Посмотреть сообщение
Будет ли это работать, если я задам ленту (начало и конец ленты) билетов сам?
Например с 30000000 до 35000000.
нет, не будет.
Именно для случая: с 30000000 до 35000000
нужно формировать два массива: a[37] и b[37].
C++
1
2
3
4
5
6
7
8
9
for(i=3000; i<=3500; i++)
//формируем массив a[]
for(i=0; i<=9999; i++)
//формируем массив b[]
 
int res=0;
for(i=0; i<37; i++)
    res+=a[i]*b[i];
//здесь в переменной res нужное значение
1
Sheptashka
0 / 0 / 0
Регистрация: 21.03.2012
Сообщений: 22
04.06.2012, 12:25  [ТС] 12
Цитата Сообщение от valeriikozlov Посмотреть сообщение
нет, не будет.
Именно для случая: с 30000000 до 35000000
нужно формировать два массива: a[37] и b[37].
C++
1
2
3
4
5
6
7
8
9
for(i=3000; i<=3500; i++)
//формируем массив a[]
for(i=0; i<=9999; i++)
//формируем массив b[]
 
int res=0;
for(i=0; i<37; i++)
    res+=a[i]*b[i];
//здесь в переменной res нужное значение
А если ещё усложнить задачу и задать ленту
12345678 до 23456789

Не могли бы пояснить , как надо составить цикл в этом случае?
Заранее спасибо
0
valeriikozlov
Эксперт С++
4693 / 2519 / 751
Регистрация: 18.08.2009
Сообщений: 4,550
04.06.2012, 15:39 13
Цитата Сообщение от Sheptashka Посмотреть сообщение
А если ещё усложнить задачу и задать ленту
12345678 до 23456789
Не могли бы пояснить , как надо составить цикл в этом случае?
Заранее спасибо
Давайте условимся так (на примере 12345678 до 23456789):
первое число обязательно меньше или равно второму.
A1 назовем левую половину первого числа (для нашего примера это 1234).
A2 назовем правую половину первого числа (для нашего примера это 5678).
B1 назовем левую половину второго числа (для нашего примера это 2345).
B2 назовем правую половину второго числа (для нашего примера это 6789).
Формируем два массива a[37] и b[37] по такому правилу:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
for(i=A1; i<=B1; i++)
// формируем массив a[] (формирование массивов см в посте №6)
if(A1==B1) 
for(i=A2; i<=B2; i++)
// формируем массив b[]
if(A1==B1-1)
{
for(i=A2; i<=9999; i++)
// формируем массив b[]
for(i=0; i<=B2; i++)
// формируем массив b[]
if(A1<B1-1) 
for(i=0; i<=9999; i++)
// формируем массив b[]
}
в конце:
C++
1
2
3
4
int res=0;
for(i=0; i<37; i++)
    res+=a[i]*b[i];
//здесь в переменной res нужное значение
1
04.06.2012, 15:39
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.06.2012, 15:39

Полный перебор и сокращенный перебор, путем исключения одного цикла
1) Разработать на основе метода полного перебора программу razmen1 для решения задачи о способах...

Перебор всех возможных вариантов, оптимизация макроса
Всем доброго времени суток! Для калибровки скоринговой карты необходимо сделать подстановку всех...

Перебор цикла в случайном порядке
for(i=1;i&lt;=10;i++) { alert(i); //do smthn } В данном примере i будут перебираться в...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru