Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
Sheptashka
0 / 0 / 0
Регистрация: 21.03.2012
Сообщений: 22
02.06.2012, 23:59     Оптимизация цикла (перебор 5000000 элементов) #1
Можно ли как-то оптимизировать данный цикл?
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 элементов по времени очень долго и программа не укладывается во времени)

Заранее спасибо
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.06.2012, 23:59     Оптимизация цикла (перебор 5000000 элементов)
Посмотрите здесь:

C++ Перебор элементов массива
C++ Скорость перебор элементов vector'a и list'a
C++ Оптимизация условия цикла while
C++ Работа цикла - считывание 1000 элементов (double)
перебор элементов массива C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
KeyGen
 Аватар для KeyGen
333 / 289 / 6
Регистрация: 07.08.2011
Сообщений: 789
Записей в блоге: 1
03.06.2012, 00:04     Оптимизация цикла (перебор 5000000 элементов) #2
Так нехорошо писать:
C++
1
for (k = i, j = 0; j < 8; j++, k /= 10)
Что на выходе должно быть?

mas[j] = k % 10; - не совсем понятно
Sheptashka
0 / 0 / 0
Регистрация: 21.03.2012
Сообщений: 22
03.06.2012, 00:06  [ТС]     Оптимизация цикла (перебор 5000000 элементов) #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;
и т.д
KeyGen
 Аватар для KeyGen
333 / 289 / 6
Регистрация: 07.08.2011
Сообщений: 789
Записей в блоге: 1
03.06.2012, 00:30     Оптимизация цикла (перебор 5000000 элементов) #4
Sheptashka, а если использовать не число а string? Проще будет...
Sheptashka
0 / 0 / 0
Регистрация: 21.03.2012
Сообщений: 22
03.06.2012, 00:32  [ТС]     Оптимизация цикла (перебор 5000000 элементов) #5
Цитата Сообщение от KeyGen Посмотреть сообщение
Sheptashka, а если использовать не число а string? Проще будет...
А как стринг перебирать?
valeriikozlov
Эксперт C++
 Аватар для valeriikozlov
4660 / 2486 / 321
Регистрация: 18.08.2009
Сообщений: 4,550
03.06.2012, 07:04     Оптимизация цикла (перебор 5000000 элементов) #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 нужный результат
KeyGen
 Аватар для KeyGen
333 / 289 / 6
Регистрация: 07.08.2011
Сообщений: 789
Записей в блоге: 1
03.06.2012, 10:52     Оптимизация цикла (перебор 5000000 элементов) #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;
    }
Sheptashka
0 / 0 / 0
Регистрация: 21.03.2012
Сообщений: 22
03.06.2012, 12:05  [ТС]     Оптимизация цикла (перебор 5000000 элементов) #8
Цитата Сообщение от valeriikozlov Посмотреть сообщение
Далее цикл:
Код C++
for(i=0; i<10000; i++)
{
* * // здесь вычисляете сумму цифр каждого i (заносите эту сумму например в переменную t)
* * a[t]++;
}
Немножко не понял для чего этот цикл, можно поподробнее?
valeriikozlov
Эксперт C++
 Аватар для valeriikozlov
4660 / 2486 / 321
Регистрация: 18.08.2009
Сообщений: 4,550
03.06.2012, 19:59     Оптимизация цикла (перебор 5000000 элементов) #9
Цитата Сообщение от Sheptashka Посмотреть сообщение
Немножко не понял для чего этот цикл, можно поподробнее?
можно.
Для решения этой задачи нужно знать сколько сколько каких сумм будет получаться в левой половине. Всего сумм может быть 37 (от 0 до 36): Число с суммой 0000 - минимальная сумма, число 9999 - максимальная сумма (сумма цифр равна 36).
В данном цикле расчитывается сколько каких сумм встречается в левой половине 8-ми значного числа. Например a[0] в конце цикла будет равно 1: соответствует числу 0000.
Или например a[1] в конце цикла будет равно 4: соответсвует числам 0001, 0010, 0100, 1000.
И т.д.
Sheptashka
0 / 0 / 0
Регистрация: 21.03.2012
Сообщений: 22
03.06.2012, 22:39  [ТС]     Оптимизация цикла (перебор 5000000 элементов) #10
Цитата Сообщение от valeriikozlov Посмотреть сообщение
можно.
Для решения этой задачи нужно знать сколько сколько каких сумм будет получаться в левой половине. Всего сумм может быть 37 (от 0 до 36): Число с суммой 0000 - минимальная сумма, число 9999 - максимальная сумма (сумма цифр равна 36).
В данном цикле расчитывается сколько каких сумм встречается в левой половине 8-ми значного числа. Например a[0] в конце цикла будет равно 1: соответствует числу 0000.
Или например a[1] в конце цикла будет равно 4: соответсвует числам 0001, 0010, 0100, 1000.
И т.д.
Будет ли это работать, если я задам ленту (начало и конец ленты) билетов сам?
Например с 30000000 до 35000000.
valeriikozlov
Эксперт C++
 Аватар для valeriikozlov
4660 / 2486 / 321
Регистрация: 18.08.2009
Сообщений: 4,550
03.06.2012, 23:07     Оптимизация цикла (перебор 5000000 элементов) #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 нужное значение
Sheptashka
0 / 0 / 0
Регистрация: 21.03.2012
Сообщений: 22
04.06.2012, 12:25  [ТС]     Оптимизация цикла (перебор 5000000 элементов) #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

Не могли бы пояснить , как надо составить цикл в этом случае?
Заранее спасибо
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.06.2012, 15:39     Оптимизация цикла (перебор 5000000 элементов)
Еще ссылки по теме:

C++ Перебор элементов массива
Некоректный инкремент переменной цикла for при сравнении элементов массива C++
Перебор элементов очереди C++

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

Или воспользуйтесь поиском по форуму:
valeriikozlov
Эксперт C++
 Аватар для valeriikozlov
4660 / 2486 / 321
Регистрация: 18.08.2009
Сообщений: 4,550
04.06.2012, 15:39     Оптимизация цикла (перебор 5000000 элементов) #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 нужное значение
Yandex
Объявления
04.06.2012, 15:39     Оптимизация цикла (перебор 5000000 элементов)
Ответ Создать тему
Опции темы

Текущее время: 20:12. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru