Поиск:

Ответ в темуСоздание новой темы Создание опроса
> algoritm GCD (greatest common divisor ), pomogite naiti 
:(
    Опции темы
padlais
  Дата 13.12.2006, 06:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 13.12.2006

Репутация: нет
Всего: нет



 smile pomogite naiti opisanie GCD algoritma (greatest common divisor ) vi4isliaet naibolwii obwi delitel dvyx ili bolee 4isel?!  smile   smile 
PM MAIL   Вверх
Alexandr87
Дата 13.12.2006, 06:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


дыкий псых
***


Профиль
Группа: Завсегдатай
Сообщений: 1459
Регистрация: 27.11.2004
Где: Алматы, Казахстан

Репутация: 1
Всего: 39



гугл расширенный алгоритм евклида
PM Jabber   Вверх
V.A.KeRneL
  Дата 13.12.2006, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Vadim A. Kazantsev
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 3.12.2006
Где: Moscow, Russia

Репутация: 1
Всего: 14



По книге Стивена С. Скиены и Мигеля А. Ревиллы «ОЛИМПИАДНЫЕ ЗАДАЧИ ПО ПРОГРАММИРОВАНИЮ. Руководство по подготовке к соревнованиям» (Steven S. Skiena, Miguel A. Revilla. «PROGRAMMING CHALLENGES. The Programming Contest Training Manual»).
Глава 7. Теория чисел
7.2. Делимость
7.2.1. Наибольший общий делитель
7.2.2. Наименьшее общее кратное

Наибольший общий делитель

Так как на 1 делится любое целое число, то наименьшим общим делителем любой пары целых чисел a, b является 1. Интереснее рассматривать наибольший общий делитель, или НОД (GCD, Greatest Common Divisor), самый большой делитель, общий для двух заданных целых чисел. Рассмотрим дробь x/y, скажем 24/36. Мы можем получить приведённую форму этой дроби, если разделим числитель и знаменатель на НОД(x, y), равный в этом случае 12. Мы говорим, что два числа взаимно простые, если их НОД равен 1.

Алгоритм Евклида для нахождения наибольшего общего делителя считается первым интересным алгоритмом, который донесла до нас история. Чтобы найти НОД «в лоб», мы можем перебрать все делители первого числа и явно проверить, являются ли они делителями второго, или, как вариант, найти разложение на простые множители обоих чисел и взять произведение всех их общих множителей. Но и тот, и другой подход требует значительных вычислительных затрат.

Алгоритм Евклида основывается на двух наблюдениях.
1. Если b|a, то НОД(a, b) = b
   Это очевидно. Если a делится на b, то a = b*k для какого-то целого k, но тогда НОД(b*k, b) = b.
2. Если a = b*t + r для целых t и r, то НОД(a, b) = НОД(a, r).
   Почему? По определению НОД(a, b) = НОД(b*t + r, b). Любой общий делитель a и b должен делить r без остатка, так что очевидно, что b*t делится на любой делитель b.

Алгоритм Евклида -- это рекурсивное, повторяющееся замещение большего из двух чисел на остаток от целочисленного деления большего числа на меньшее. Обычно при этом один из аргументов уменьшается примерно вдвое, так что после логарифмического числа операций мы приходим к базовому случаю. Рассмотрим следующий пример. Пусть a = 34398 и b = 2132.
Код

НОД(34398, 2132) = НОД(34398 mod 2132, 2132) = НОД(2132, 286), 
НОД(2132, 286) = НОД(2132 mod 286, 286) = НОД(286, 130), 
НОД(286, 130) = НОД(286 mod 130, 130) = НОД(130, 26), 
НОД(130, 26) = НОД(130 mod 26, 26) = НОД(26, 0).


Таким образом НОД(34398, 2132) = 26.

Тем не менее из алгоритма Евклида мы можем найти не только НОД(a, b). С его помощью мы можем также найти целые x и y такие, что 
Код
a*x + b*y = НОД(a, b)
, 
что окажется весьма полезно при решении линейных сравнимостей. Мы знаем, что НОД(a, b) = НОД(b, a'), где a' = a - b*floor(a/b). floor(x) -- ближайшее целое, не превосходящее x. Более того, преположим, что из рекурсии мы знаем целые x' и y' такие, что 
Код
b*x' + a'*y' = НОД(a, b)
.
Подставив наше выражение для a' в это выражение, получим: 
Код
b*x' + (a - b*floor(a/b)) * y' = НОД(a, b)
, 
тогда, приведя подобные, мы найдём искомые x и y. Чтобы наш алгоритм был полным, нам нужен базисный случай, он выбирается просто: a*1 + 0*0 = НОД(a, 0).

Для предыдущего примера мы получаем: 34398*15 + 2132*(-242) = 26. Вот реализация этого алгоритма (Расширенного алгоритма Евклида) на языке программирования Си: 

Код

#include <stdio.h>
#include <math.h>

/* 
   Вычисляет gcd(p, q) и x и y такие, что p*x + q*y = gcd(p, q).  
 */
long 
gcd(long p, long q, long * x, long * y) 
{ 
    long x1, y1;  /* предыдущие коэффициенты */
    long g;       /* значение gcd(p, q) */
    
    if (q > p) 
        return (gcd(q, p, y, x));
    
    if (q == 0) { 
        *x = 1;
        *y = 0;
        return (p);
    }
    
    g = gcd(q, p%q, &x1, &y1);
    
    *x = y1;
    *y = (x1 - floor(p/q)*y1);
    
    return (g);
}

/* 
   Main.  
 */
int 
main(void) 
{ 
    long p, q, x, y, g;
    
    printf("p := "); scanf("%ld", &p);
    printf("q := "); scanf("%ld", &q);
    
    g = gcd(p, q, &x, &y);
    
    printf("p*x + q*y = gcd(p, q)\n");
    printf("gcd(%ld, %ld) = %ld\n", p, q, g);
    printf("x = %ld\n", x);
    printf("y = %ld\n", y);
    
    return (0);
}


Сохраним код, например, в файлике gcd.c
И затем, если Вы используете компилятор GCC, то строка для компиляции может быть такой: 
Код
gcc -lm gcd.c -o gcd


Бонус: 

Наименьшее общее кратное

Ещё одной важной функцией от двух целых чисел является наименьшее общее кратное (НОК), самое маленькое целое число, которое делится на оба заданных целых числа. Например, наименьшее общее кратное 24 и 36 -- это 72.

Наименьшее общее кратное появляется в тех задачах, где требуется посчитать периодичность совпадения двух различных периодических событий. Когда в следующий раз (после 2000-го) год президентских выборов (которые проводятся каждые 4 года) совпадает с годом переписи населения (которая проводится раз в 10 лет)? Эти события совпадают каждые 20 лет, так как НОК(4, 10) = 20.

Очевидно, что НОК(x, y) >= max(x, y). Аналогично, так как x*y кратно и x, и y, то НОК(x, y) <= x*y. Меньшее ощее кратное может существовать только в том случае, если существует нетривиальный множитель, общий для x и y.

Это наблюдение вместе с алгоритмом Евклида даёт нам эффективный алгоритм вычисления наименьшего общего кратного, а именно НОК(x, y) = x*y/НОД(x, y). Более хитрый алгоритм, в котором нет необходимости в умножении и, как следствие, исчезает возможность переполнения, можно найти в книге E.W. Dijkstra. «Дисциплина прграммирования». 1976.


Это сообщение отредактировал(а) V.A.KeRneL - 15.1.2007, 04:32


--------------------
«C'est un pense-creux d'ici. C'est le meilleur et le plus irascible homme du monde...» © Ф.М. Достоевский, «Бесы»
---/)/)---(\.../)---(\(\
--(':'=)---(=';'=)---(=':')
(")(")..)-(").--.(")-(..(")(")

PM MAIL IM ICQ AOL YIM MSN   Вверх
padlais
Дата 13.12.2006, 19:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 13.12.2006

Репутация: нет
Всего: нет



spasibo bolwoe vsem kto otozvalsia!
tak je est xoroweeopisanie po adresy : http://en.wikipedia.org/wiki/Binary_GCD_algorithm
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Алгоритмы"

maxim1000

Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Алгоритмы | Следующая тема »


 




[ Время генерации скрипта: 0.0435 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.