Алгоритъм на Евклид

Съдържание

НОД - най-голям общ делител (чрез изваждане) с итерация
НОД - най-голям общ делител (чрез изваждане) с рекурсия
НОД - най-голям общ делител (чрез делене)
взаимно прости числа
НОК - най-малко общо кратно
естествено число - прости делители

Един от най-старите известни алгоритми е свързан с намиране на най-голям общ делител на две естествени числа (НОД). Среща в литературата под името алгоритъм на Евклид (Euclidean algorithm). За този алгоритъм е доказано: винаги завършва с определен резултат; броят на необходимите изваждания винаги е по-малък от стойността на по-голямото от двете естествени числа. Тук ще опишем както самия алгоритъм, така и решение на задача извеждаща най-големия общ делител.

Пример най-голям общ делите на 45 и 75:
45 75 НОД=15

НОД - най-голям общ делител (чрез изваждане) с итерация

Нека разгледаме примерно решение на тази задача в два варианта. Общото между тях е наличие на цикличен процес. Чрез изваждане - от по-голямото число се вади по-малкото до достигане на резултат 0, т.е. до равенство на двете числа. Най-големият общ делител е останалото по-голямо число. Следи се винаги да се изважда от по-голямото число по-малкото.

блок схема за алгоритъм на Евклид
  Следва сорс код на примерна програма (DEV C++), съдържаща решение на задача за алгоритъм на Евклид (чрез изваждане) с итерация.
#include<iostream>

using namespace std;

 

int euclid_I(int M, int N) // euclidean algorithm 

{

  while (M!=N)//dokato razlikata mevdu chislata e <> 0

   { cout<<"W momenta chislata sa: "<<M<<":"<<N<<endl;

        if (M>N) M-=N; else N-=M;//rawnostojnoto if (M>N) M=M-N; else N=N-M;


   }//while

return M;

}//euclid

 

int main()//nachalo na programata

{ int M,N;

  cout<<"Da se systawi programa, chrez koqto se izwevda naj-golemiq obsh\n";


  cout<<"delitel na dwe estestweni chisla. Prilovete algoritym na Ewklid.\n";

  cout<<"Primer: 28, 35 Izhod: 7 \n";

  cout<<"Wywedete estestweno chislo ot interwala [3..1001]: ";cin>>M;

  cout<<"Wywedete estestweno chislo ot interwala [3..1001]: ";cin>>N;


  cout<<"Naj-golemiqt obsh delitel e: "<<euclid_I(M, N)<<endl;

 system("pause");//chaka natiskane na klawish ot klawiaturata

 return 0; //oswobovdawa zaetite sistemni resursi

} //kraj na programa algoritym na Ewklid 

Начало на страницата

НОД - най-голям общ делител (чрез изваждане) с рекурсия

Следва сорс код на примерна програма, съдържаща решение на задача за алгоритъм на Евклид (чрез изваждане) с рекурсия.

#include<iostream>

using namespace std;

  

int euclid_R(int M, int N)

{ //algoritym na Ewklid (euclidean algorithm) - ot po-golqmoto chislo se wadi po-malkoto

 //dokato dwete chisla stanat rawni

    if (M!=N) //uslowie za kraj na rekursiqta

    {cout<<"Systoqnie na dwete chisla: "<<M<<":"<<N<<endl;

     if (M>N) return euclid_R(M-N,N); 

      else return euclid_R(M,N-M);    

     }// (M!=N)

   return M;

}//int euclid_R

 

int main()//nachalo na programata

{ int M,N;

  cout<<"Da se systawi programa, chrez koqto se izwevda naj-golemiq obsh\n";

  cout<<"delitel na dwe estestweni chisla. Prilovete algoritym na Ewklid.\n";

  cout<<"Primer: 28, 35 Izhod: 7 \n";

  cout<<"Wywedete estestweno chislo ot interwala [3..1001]: ";cin>>M;

  cout<<"Wywedete estestweno chislo ot interwala [3..1001]: ";cin>>N;

  cout<<"Naj-golemiqt obsh delitel e: "<<euclid_R(M, N)<<endl;

 system("pause");//chaka natiskane na klawish ot klawiaturata

 return 0; //oswobovdawa zaetite sistemni resursi

} //kraj na programa naj-golqm delitel Ewklid 

Начало на страницата

НОД - най-голям общ делител (чрез делене)

Аналогично на алгоритъма чрез изваждане може да се приложи делене - отново по-голямото число се дели на по-малкото до достигане на на целочислен остатък равен на 0, т.е. едното число се явява кратно на другото. Най-големият общ делител е останалото по-голямо число. На всяка стъпка стойностите на двете числа се променят: по-голямото присвоява стойността на по-малкото, а по-малкото на целочисленото частно. Преди началото на цикличния процес се определя по-голямото въведено число. Тази част от програмата може да се замени с условен оператор.

  Следва сорс код на примерна програма, съдържаща решение на задача за алгоритъм на Евклид чрез делене.
#include<iostream>

#include<cmath>

using namespace std;


int main()

{

  int a1,a2,Min, Max,ob;

  cout<<"Da se systawi programa, chrez koqto se wywevdat dwe estestweni chisla\n";


  cout<<"ot interwala [2..1001]. Programata da izwevda tehniq naj-golqm obsh delitel \n";

  cout<<" NOD, chrez algoritym na Ewklid - s delene.\n";

  cout<<"Primer 36,24 Izhod: 12\n";

  

  cout<<"Wywedete stojnostta na promenliwa 1 A= ";  cin>>a1;


  cout<<"Wywedete stojnostta na promenliwa 2 B= ";   cin>>a2;

   //sys sledwashite dwa reda opredelqme po-golqmoto i po-malkoto ot wywedenite chisla 

   Max= ((a1+a2) - abs(a1-a2))/2;//po-golqmoto chislo

   Min= ((a1+a2) + abs(a1-a2))/2;

   

  ob = Max % Min;//celochisleno delene, ako ob==0, to NOD = Min


    

// Ewklid algorithm

  while (ob)//dokato ne se nameri kratno

  {

     Max = Min;

     Min = ob;

    ob= Max % Min;


   }//while


   if (Min-1)    
cout<<"HOD ("<<a1<<",
"<<a2<<")= "<<Min<<endl;

  else cout<<"Chislata "<<a1<<", "<<a2<<" sa wzaimno prosti. NOD = 1. \n";


  system("pause");

  return 0;

}//kraj na programa naj-golqm obsh delitel Ewklid 

Начало на страницата

взаимно прости числа

Две или повече числа, на които най-големият общ делител е 1, се наричат взаимно прости числа. Пример: числата 21 и 16 са взаимно прости числа, защото НОД (21, 16) = 1. Бихме могли да изведем характерни признаци за взаимно прости числа: а) ако едно от двете числа е просто, то двете числа са взаимно прости; б) ако са последователни естествени числа. Ако две числа са прости, те са взаимно прости числа, обратното твърдение не е вярно. Геометрично представяне: нека е зададена точка с M с координати (x,y) – цели числа. Ако в декартова координатна система построим отсечка с начало (0,0) и край (x,y) и на отсечката не принадлежи друга точка с координати цели числа, казваме че x,y са взаимно прости числа. Алгоритъмът за проверка дали две числа са взаимно прости използва алгоритъм на Евклид за намиране на най-голям общ делител - НОД. Ако изчисленият НОД на двете числа е 1, то те са взаимно прости числа.

Следва примерна програма, съдържаща решение на задача за взаимно прости числа:
 
#include<iostream>

using namespace std;

 

 

int euclidean_NOD(int M, int N)  // naj-golqm obsh delitel Ewklid 

{


    while (M!=N)//dokato razlikata mevdu chislata e <> 0

       { if (M>N) M-=N; else N-=M;//rawnostojnoto if (M>N) M=M-N; else N=N-M;

       }//while

return M;

}// naj-golqm obsh delitel 

 

int main()


{ int M,N,obsh;

   char ose;

   cout<<"Da se systawi programa, chrez koqto se prowerqwa dali dwe  \n";

   cout<<"estestweni chisla N i M sa wzaimno prosti.\n";

   cout<<"Primer: 28, 33 Izhod: Da \n";


  do { 

  cout<<"Wywedete estestweno chislo ot interwala [3..1001]: ";cin>>M;

   cout<<"Wywedete estestweno chislo ot interwala [3..1001]: ";cin>>N;

  obsh=euclidean_NOD(M, N);

   if (obsh==1) cout<<"Chislata sa wzaimno prosti.\n";


  else cout<<"Naj-golemiqt obsh delitel na dwete chisla e: "<<obsh<<endl;

   cout<<"She wywevdate li drugi danni <y/n>: ";cin>>ose;

 }while (ose=='y'); 

 system("pause");


 return 0; 

} //kraj na programa naj-golqm obsh delitel Ewklid 

Начало на страницата

НОК - най-малко общо кратно

Число, което е кратно на няколко дадени числа, се нарича тяхно общо кратно. Най-малкото от общите кратни на две или повече числа се нарича най-малко общо кратно на тези числа. Алгоритъмът за най-малко общо кратно използва алгоритъм на Евклид за намиране на най-голям общ делител. Така НОК на две естествени числа N, M с НОД P се получава като отношение между произведенията на двете числа M*N и техния най-голям общ делител P. НОК = M * N / P
Пример: НОК на 14 (2*7) и 21 (3*7) е = 42 (2*3*7)
Пример: 36, 48
Изход: НОК = 144, т.к 36=12*3, 48=12*4, 144=12*3*4
Ако трябва да се обобщи алгоритъма за най-малко общо кратно за повече от две числа A1,A2,A3...An, то формулата би изглеждала НОК = НОД*(A1/НОД)*(А2/НОД) *...* (An/НОД)
Най-малкото общо кратно на две взаимно прости числа е тяхното произведение. Пример: 3 и 5, то най-малко общо кратно НОК = 15

Следва примерна програма, съдържаща решение на задача за намиране на най-малко общ кратно на две естествени числа:
#include<iostream>

using namespace std;

 

int euclidean_NOK(int M, int N) // Ewklid algorithm

{

   while (M!=N)//dokato razlikata mevdu chislata e <> 0

   { if (M>N) M-=N; else N-=M;//rawnostojnoto if (M>N) M=M-N; else N=N-M;

   }//while


return M;

}//naj-malko obsho kratno Ewklid 

 

int main()//nachalo na programata

{ int M,N,obsh,NOK;

  char ose;

   cout<<"Da se systawi programa, chrez koqto se namira  \n";


   cout<<" nai-malko obsho kratno na dwe estestweni chisla N i M.\n";

   cout<<"Primer: 45, 75 Izhod: 225 \n";

 do { 

   cout<<"Wywedete estestweno chislo ot interwala [3..1001]: ";cin>>M;


   cout<<"Wywedete estestweno chislo ot interwala [3..1001]: ";cin>>N;

  obsh=euclidean_NOK(M, N);

   cout<<"NOD = "<<obsh<<endl;

  NOK=M*N/obsh;

  cout<<"naj-malko obsho kratno na "<<M<<" i "<<N<<" e "<<NOK<<endl;


  cout<<"She wywevdate li drugi danni <y/n>: ";cin>>ose;

 }while (ose=='y'); 

 system("pause");

 return 0; 

} //kraj na programa nai-malko obsho kratno Ewklid 

Обяснени и решени задачи с подобни алгоритми, функции и служебни думи са разгледани в страницата с електронни уроци по информатика - програмиране.
Илюстриране работата и последователните стъпки в алгоритъм на Евклид за изчисляване на НОД е даден в предоставените електронни помагала съдържащи решени задачи, примери.

Начало на страницата

 
Размер на шрифта
Increase Font Size Option 3 Reset Font Size Option 3 Decrease Font Size Option 3
Bulgarian Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish
Търсене в сайта: