Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Java - Помогите с алгоритмом

Ответить
Настройки темы
Java - Помогите с алгоритмом

Новый участник


Сообщения: 16
Благодарности: 0

Профиль | Отправить PM | Цитировать


Изменения
Автор: Drongo
Дата: 26-11-2013
Описание: тег код #
Нужно подсчитать сумму всех элементов остаток от деления которых равен 0.
Задача, оптимизировать, ускорить этот процесс, то есть избегая следующей конструкции (цикла):
Код: Выделить весь код
...
for (int i = 0; i < arr.Length; i++)
{
     if (((arr[i] % 3) == 0) || ((arr[i] % 7) == 0))
     count += count + arr[i];
}
...

Отправлено: 21:53, 25-11-2013

 
pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


Цитата nastr:
остаток от деления которых равен 0. »
обычно делят что-то на что-то. Что на что делить надо?

Отправлено: 13:00, 26-11-2013 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Новый участник


Сообщения: 16
Благодарности: 0

Профиль | Отправить PM | Цитировать


Я более точно сформулировал задачу:

Дано:
Отсортированный массив, от 0 до N.
Задание:
Найти оптимальный алгоритм подсчёта суммы значений элементов массива, которые делятся на 3 и на 7 без остатка.

Учитывая условие я не нашел более оптимального алгоритма нежели перебор всех элементов:
Код: Выделить весь код
...
int[] arr = new int[2013];
int count = 0;
for (int i = 0; i < arr.Length; i++)
arr[i] = i;
for (int i = 0; i < arr.Length; i++)
{
if (((arr[i] % 3) == 0) || ((arr[i] % 7) == 0))
count += arr[i];
}
...

Последний раз редактировалось Drongo, 26-11-2013 в 17:20. Причина: тег код #


Отправлено: 13:53, 26-11-2013 | #3


Новый участник


Сообщения: 16
Благодарности: 0

Профиль | Отправить PM | Цитировать


Можно без массива. Дано N. Найти сумму натуральный чисел, не превосходящих N, которые делятся на 3 и на 7 без остатка.
найти сумма всех чисел не превосходящих N, которые делятся на 3 без остатка.

Отправлено: 14:54, 26-11-2013 | #4


Забанен


Сообщения: 5828
Благодарности: 1242

Профиль | Цитировать


nastr, выполняйте одну проверку вместо двух, делится ли элемент массива без остатка на 21. Больше тут нечего оптимизировать.

Отправлено: 15:04, 26-11-2013 | #5


Ветеран


Сообщения: 1807
Благодарности: 146

Профиль | Отправить PM | Цитировать


Цитата Leha Ares:
nastr, выполняйте одну проверку вместо двух, делится ли элемент массива без остатка на 21. Больше тут нечего оптимизировать. »
Пардон, это далеко не выход. Если я правильно понял условие. Найдется куча чисел, вроде 3, 6, 7, 9, 12, 14, которые делятся то на 3, то на 7. Ну, может, я не так понял. А может, автор не вполне корректно сформулировал, оставив лазейку для побочных интерпретаций.

Отправлено: 15:26, 26-11-2013 | #6

pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


Leha Ares, 7 на 21 не делится

XPEHOMETP, всё корректно
nastr, у тебя идеальный алгоритм. Либо это олимпиадная задача и требуется хитрость

Хотя... Leha Ares прав:
"на 3 и на 7" проще понять как "и на 3, и на 7", чем "на 3 либо на 7"

Отправлено: 15:26, 26-11-2013 | #7


Аватара для Coutty

Кот Ти


Сообщения: 7318
Благодарности: 1204

Профиль | Отправить PM | Цитировать


Цитата nastr:
Можно без массива. Дано N. Найти сумму натуральный чисел, не превосходящих N, которые делятся на 3 и на 7 без остатка.
найти сумма всех чисел не превосходящих N, которые делятся на 3 без остатка. »
Вооот, это уже другая задача. Массив-то, как я понимаю, оказывается не просто упорядоченным, а с шагом в 1 (т.к. последовательность натуральных чисел).
Тогда алгоритм весь строится на сумме арифметической прогрессии следующим образом:
Шаг 0. Пусть N = 500 (т.е. числа 1 2 3 4... 499 500)
Шаг 1. Первый член арифметической прогрессии с шагом в 3 [An=3d] - это 3. Последний член прогрессии = mod(500 / 3) * 3 = 166 * 3 = 498 (используем целочисленное деление). Заодно мы в курсе, что последний член прогрессии имеет номер 166.
Шаг 2. Считаем сумму арифметической прогрессии по формуле (в википедии есть) sum = (A1+An)*n/2 = (3 + 498) * 166 / 2 = 41583
Шаг 3. Теперь с семёркой. Тут немного сложнее, т.к. нам надо из суммы исключить числа, делящиеся на 3
Имеем такой ряд: 7 14 28 35 49 56... Т.е. просто An=7d нас не устраивает. Используем хитрость:
Шаг 4. Сначала считаем сумму для прогрессии An=7d. 71 член прогрессии равен 497. Сумма = (7 + 497) * 71 / 2 = 17892
Шаг 5. Теперь нужно исключить числа, делящиеся на 21. Считаем сумму прогрессии An = 21d. 23 член прогрессии равен 483. Сумма = (21 + 483) * 23 / 2 = 5796
Шаг 6. Итоговый результат = 41583 + 17892 - 5796 = 53697.

Для маленького N такой алгоритм не особо эффективен, но для большого - то, что надо. Для предела в 500 значений, в ассемблере получается 40 инструкций для этого алгоритма и около 6500 инструкций для цикла с делением.
Конечно, если у вас массив - это не последовательность натуральных чисел, а просто упорядоченные случайные целые числа больше нуля, то ничего не выйдет, используйте цикл.

Последний раз редактировалось Coutty, 26-11-2013 в 21:06.

Это сообщение посчитали полезным следующие участники:

Отправлено: 18:12, 26-11-2013 | #8


Забанен


Сообщения: 5828
Благодарности: 1242

Профиль | Цитировать


Цитата pva:
Хотя... Leha Ares прав:
"на 3 и на 7" проще понять как "и на 3, и на 7", чем "на 3 либо на 7" »
В программировании "и" - вполне конкретная логическая операция в противовес "или". В задаче "и", значит и решаем через "и".

Отправлено: 18:14, 26-11-2013 | #9


Новый участник


Сообщения: 16
Благодарности: 0

Профиль | Отправить PM | Цитировать


Код: Выделить весь код
// declaration 
            decimal N = numericUpDown1.Value, loopTotaSum = 0, loopAmount = 0,
                prog3Amount, prog3Sum, prog7Amount, prog7Sum, prog21Amount, prog21Sum;
            System.Diagnostics.Stopwatch st = new System.Diagnostics.Stopwatch();

            // Loop
            st.Start();
            for (int i = 1; i <= N; i++)
            {
                if (i % 3 == 0 || i % 7 == 0)
                {
                    loopTotaSum += i;
                    loopAmount++;
                }
            }
            loopTotaSum_textBox.Text = loopTotaSum.ToString();
            loopAmount_textBox.Text = loopAmount.ToString();
            st.Stop();
            loopStopwatch_textBox.Text = st.ElapsedMilliseconds.ToString();
            st.Reset();

            // Progression
            st.Start();
            prog7Amount = decimal.Truncate(N / 7);
            prog7Sum = (7 + prog7Amount * 7) * prog7Amount / 2; //Сначала считаем сумму для прогрессии An=7d
            prog3Amount = decimal.Truncate(N / 3);
            prog3Sum = (3 + prog3Amount * 3) * prog3Amount / 2; //Считаем сумму арифметической прогрессии An=3d
            prog21Amount = decimal.Truncate(N / 21);
            prog21Sum = (21 + prog21Amount * 21) * prog21Amount / 2; //Нужно исключить числа, делящиеся на 21. Считаем сумму прогрессии An = 21d
            progTotalSum_textBox.Text = Convert.ToString(prog3Sum + prog7Sum - prog21Sum); //Итоговый результат
            prog3Amount_textBox.Text = Convert.ToString(prog3Amount + prog7Amount - prog21Amount);
            st.Stop();
            progStopwatch_textBox.Text = st.ElapsedMilliseconds.ToString();

Отправлено: 16:31, 27-11-2013 | #10



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Java - Помогите с алгоритмом

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
[Ну помогите же человеку, а? :)] Помогите с конкурсом HTML64 Тест-форум 0 29-06-2012 10:33
CMD/BAT - [решено] помогите скачал себе этот вирус помогите его разблокировать orell Скриптовые языки администрирования Windows 2 05-05-2012 15:45
Разбивка строки в массив из комбинации слов - помогите с алгоритмом, пожалуйста ANR Программирование и базы данных 1 25-09-2010 06:43
помогите с алгоритмом решения задачи bool Хочу все знать 2 14-06-2008 18:43
Помогите с алгоритмом или исходником двумерного отсечения отрезка. [mzd] Программирование и базы данных 2 04-09-2005 20:31




 
Переход