- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 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
int NOD(int a,int b)
{
if(a==0)
{
return b;
}
if(b==0)
{
return a;
}
if(a==b)
{
return a;
}
if((a%2==0)&&(b%2==0))
{
return 2*NOD(a/2,b/2);
}
else if((a%2==0)&&(b%2!=0))
{
return NOD(a/2,b);
}
else if((a%2!=0)&&(b%2==0))
{
return NOD(a,b/2);
}
else if((a%2!=0)&&(b%2!=0))
{
return NOD(b,abs(a-b));
}
else return 1;
/*
1. НОД(0, n) = n; НОД(m, 0) = m; НОД(m, m) = m;
2. НОД(1, n) = 1; НОД(m, 1) = 1;
3. Если m, n чётные, то НОД(m, n) = 2*НОД(m/2, n/2);
4. Если m чётное, n нечётное, то НОД(m, n) = НОД(m/2, n);
5. Если n чётное, m нечётное, то НОД(m, n) = НОД(m, n/2);
6. Если m, n нечётные, то НОД(m, n) = НОД(n, |m - n|).
*/
}
Oleg_quadro 08.12.2009 00:55 # +1
guest 08.12.2009 01:47 # −1
nil 08.12.2009 11:37 # 0
И да, давайте не будем показывать автору решето Эратосфена!
Oleg_quadro 08.12.2009 18:52 # 0
guest 08.12.2009 20:22 # −1
guest 08.12.2009 20:23 # −1
Oleg_quadro 09.12.2009 16:35 # 0
Billy the Kidd 09.12.2009 20:19 # 0
nil 09.12.2009 13:47 # 0
Oleg_quadro 09.12.2009 16:36 # 0
Billy the Kidd 09.12.2009 21:36 # 0
Все эти подпрыгивания с четностью и деленьями на 2 - попытки "т.н.оптимизации" решетом, из которого взята только двойка. Почему остатки от деления на 3 не проверяются?
Хотя никакого решета не нужно. Если уж работать с делением, то можно сделать так.
Так что в топку решето. Последний пример заруливает решето в минуса между вторым и третьим раундами.
guest 08.12.2009 10:12 # 0
>Алгоритм Евклида - прошлый век!
У вас есть алгоритм нашего века?
nil 08.12.2009 11:45 # 0
zelenov.pavel 08.12.2009 22:24 # 0
Как раз таки эта 30-строчная конструкция, имхо, отличный пример говнокода, в то время как алгоритм Евклида пишется в 5-6 строк))
">Алгоритм Евклида - прошлый век!" - сарказм, если что
nil 09.12.2009 13:51 # 0
interested 09.12.2009 15:28 # 0
Естественно, что приведённая как "говнокод" версия плоха, она использует рекурсию и не сдвигает чётную разность перед следующим вызовом.
Billy the Kidd 09.12.2009 20:23 # 0
interested 09.12.2009 20:37 # 0
(j/k)
Billy the Kidd 09.12.2009 20:58 # 0
Вы еще скажите, что считать числа Фибоначчи рекурсией неэффективно. Но описаны они именно реккурентным соотношением.
Поэтому в посте не говнокод - а отличный школьный пример реализации алгоритма Евклида.
fil teh pawer.
interested 09.12.2009 21:40 # 0
>считать числа Фибоначчи рекурсией неэффективно
Да. Вообще считать рекурсией не эффективно, потому что каждый раз память забивается ненужной числовой информацией, а иногда очень большими числами, хотя хранить их в памяти не нужно.
Billy the Kidd 09.12.2009 21:52 # 0
Например, в общем случае: вычисление длины кратчайшего пути выхода из лабиринта. Рекурсией неэффективно по времени, но требует гораздо меньше ресурсов по памяти. Нерекурсивным волновым методом получится быстрее, но памяти потребует - не горюй. Потому что рекурсия одновременно "помнит" один путь, а волновой метод - одновременно все возможные.
Такшта, каждому овощу - свой шесток. ;) А язык - дело наживное.
interested 09.12.2009 22:02 # 0
Другое дело, когда действительно нужно запомнить.
А в рядах, обычно, ничего запоминать не нужно, потому это и есть банальное забивание памяти.
А алгоритм Евклида, между прочим, ищет НОД последовательным делением с остатком, а не вычитанием.
gecko 08.12.2009 12:25 # 0
nil 08.12.2009 13:06 # 0
TarasB 08.12.2009 22:50 # 0
guest 08.12.2009 23:04 # −1
guest 08.12.2009 23:05 # 0
interested 09.12.2009 09:43 # +1
guest 09.12.2009 09:48 # 0
interested 09.12.2009 10:28 # +1
Правда, существуют два поверья:
1. компиляторы сами оптимизируют деление в сдвиг.
2. компиляторы сами оптимизируют остаток от деления в конъюнкцию
Лично я до сих пор пользуюсь двоичными операторами по привычке.
guest 16.12.2009 13:44 # 0
interested 16.12.2009 14:19 # 0
Нужно к каждому отдельному компилятору читать документацию, а ещё лучше разбираться в сгенерированном машинном коде. Ещё лучше именно для того приложения, которое должно работать, а не приём отдельно.
Вообще, я только за ту оптимизацию, которую глазом вижу, а не миллисекундами. Доли секунд вообще могут сожраться системой. (кстати тоже весело: Макконелл писал, что можно получать существенную оптимизацию, если писать код выровненными кусками; я ничего не понял, но впечатляет заморочка; связано с загрузкой кода в рабочую память процессора)
Вот если я сдвиг написал и у меня программа работает стабильно сорок минут вместо часа -- значит верно воткнуто =]
guest 09.12.2009 15:42 # +4