Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
Sheptashka
0 / 0 / 0
Регистрация: 21.03.2012
Сообщений: 22
#1

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

02.06.2012, 23:59. Просмотров 1207. Ответов 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.06.2012, 23:59
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Оптимизация цикла (перебор 5000000 элементов) (C++):

Оптимизация цикла for - C++
Скажите, пожалуйста, как оптимизируется первый цикл? И чем он отличается от второго? Первый цикл: int a = 2; for (int i = 0; i &lt; 5;...

Оптимизация цикла for - C++
Исходные данные: имеется цикл for, прерывание которого невозможно(должен выполнить все итерации). #include &lt;iostream&gt; int main() {...

Оптимизация цикла по скорости - C++
Помогите пожалуйста оптимизировать данный цикл (изменить его, чтобы он выполнялся быстрее): int a = new int; int b = new int; ...

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

перебор элементов массива - C++
дан массив целых чисел. поменять местами пары элементов в массиве: 1 и2,3 и 4,5 и 6 и т.д.

Перебор элементов массива - C++
Доброго времени! Я новичек в С++, поэтому прошу не ругать. Вопрос - как организовать перебор элементов массива? Вот, например, в таком...

12
KeyGen
384 / 291 / 6
Регистрация: 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
384 / 291 / 6
Регистрация: 07.08.2011
Сообщений: 790
Записей в блоге: 1
03.06.2012, 00:30 #4
Sheptashka, а если использовать не число а string? Проще будет...
0
Sheptashka
0 / 0 / 0
Регистрация: 21.03.2012
Сообщений: 22
03.06.2012, 00:32  [ТС] #5
Цитата Сообщение от KeyGen Посмотреть сообщение
Sheptashka, а если использовать не число а string? Проще будет...
А как стринг перебирать?
0
valeriikozlov
Эксперт С++
4672 / 2498 / 321
Регистрация: 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
384 / 291 / 6
Регистрация: 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
Эксперт С++
4672 / 2498 / 321
Регистрация: 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
Эксперт С++
4672 / 2498 / 321
Регистрация: 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
Эксперт С++
4672 / 2498 / 321
Регистрация: 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
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.06.2012, 15:39
Привет! Вот еще темы с ответами:

Перебор элементов очереди - C++
Здравствуйте! Подскажите, пожалуйста, как мне получить доступ к определённому элементу очереди? Я понимаю, что прямой доступ мы имеем...

Перебор элементов массива - C++
Добрый день, ув. форумчане. В наличии следующий код: int i; WCHAR *slovo = {L&quot;слово1&quot;, L&quot;слово2&quot;, ..., L&quot;слово1000&quot;}; int...

Скорость перебор элементов vector'a и list'a - C++
Видел на форумах пишут что поиск по несортированному вектору быстрее, чем по листу. Логично предположить что все элементы вектора находятся...

Выйти из цикла ввода элементов - C++
надо ввести элементы..... все хорошо...но как выйти из этого состояния и дальше работать , а то так можно вводить бесконечно ...


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

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

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