Mencari Pembahagi Biasa yang Paling Hebat di Jawa

1. Gambaran keseluruhan

Dalam matematik, GCD dua integer, yang bukan sifar, adalah bilangan bulat positif terbesar yang membahagi setiap bilangan bulat secara sama rata.

Dalam tutorial ini, kita akan melihat tiga pendekatan untuk mencari Pembahagi Umum Terbesar (GCD) dua bilangan bulat. Selanjutnya, kita akan melihat pelaksanaannya di Jawa.

2. Brute Force

Untuk pendekatan pertama kami, kami melakukan iterasi dari 1 hingga bilangan terkecil yang diberikan dan periksa sama ada bilangan bulat yang diberi dibahagi oleh indeks. Indeks terbesar yang membahagi nombor yang diberikan adalah GCD nombor yang diberikan:

int gcdByBruteForce(int n1, int n2) { int gcd = 1; for (int i = 1; i <= n1 && i <= n2; i++) { if (n1 % i == 0 && n2 % i == 0) { gcd = i; } } return gcd; }

Seperti yang dapat kita lihat, kerumitan pelaksanaan di atas adalah O (min (n1, n2)) kerana kita perlu melakukan iterasi pada loop untuk n kali (bersamaan dengan bilangan yang lebih kecil) untuk mencari GCD.

3. Algoritma Euclid

Kedua, kita boleh menggunakan algoritma Euclid untuk mencari GCD. Algoritma Euclid bukan sahaja cekap tetapi juga mudah difahami dan senang dilaksanakan menggunakan rekursi di Java.

Kaedah Euclid bergantung pada dua teorema penting:

  • Pertama, jika kita mengurangkan nombor yang lebih kecil dari jumlah yang lebih besar, GCD tidak akan berubah - oleh itu, jika kita terus mengurangkan nombor itu, akhirnya kita akan berakhir dengan GCD mereka
  • Kedua, apabila bilangan yang lebih kecil membagi nombor yang lebih besar, nombor yang lebih kecil adalah GCD dari dua nombor yang diberikan.

Perhatikan dalam pelaksanaan kami bahawa kami akan menggunakan modulo dan bukannya pengurangan kerana pada dasarnya banyak pengurangan pada satu masa:

int gcdByEuclidsAlgorithm(int n1, int n2) { if (n2 == 0) { return n1; } return gcdByEuclidsAlgorithm(n2, n1 % n2); }

Juga, perhatikan bagaimana kita menggunakan n2 dalam posisi n1 dan gunakan selebihnya dalam kedudukan n2 dalam langkah rekursif algoritma .

Selanjutnya, kerumitan algoritma Euclid adalah O (Log min (n1, n2)) yang lebih baik jika dibandingkan dengan kaedah Brute Force yang kita lihat sebelumnya.

4. Algoritma Stein atau Algoritma GCD Binari

Akhirnya, kita dapat menggunakan algoritma Stein, juga dikenali sebagai algoritma BCD GCD , untuk mencari GCD dua bilangan bulat bukan negatif. Algoritma ini menggunakan operasi aritmetik sederhana seperti pergeseran, perbandingan, dan pengurangan aritmetik.

Algoritma Stein berulang kali menggunakan identiti asas berikut yang berkaitan dengan GCD untuk mencari GCD dua bilangan bulat bukan negatif:

  1. gcd (0, 0) = 0, gcd (n1, 0) = n1, gcd (0, n2) = n2
  2. Apabila n1 dan n2 keduanya sama bilangan bulat, maka gcd (n1, n2) = 2 * gcd (n1 / 2, n2 / 2) , kerana 2 adalah pembahagi biasa
  3. Sekiranya n1 genap dan n2 adalah bilangan bulat ganjil, maka gcd (n1, n2) = gcd (n1 / 2, n2) , kerana 2 bukan pembahagi biasa dan sebaliknya
  4. Sekiranya n1 dan n2 adalah kedua-dua bilangan bulat ganjil, dan n1> = n2 , maka gcd (n1, n2) = gcd ((n1-n2) / 2, n2) dan sebaliknya

Kami mengulangi langkah 2-4 sehingga n1 sama dengan n2 , atau n1 = 0 . GCD ialah (2n) * n2 . Di sini, n adalah berapa kali 2 dijumpai biasa di n1 dan n2 semasa melakukan langkah 2:

int gcdBySteinsAlgorithm(int n1, int n2) { if (n1 == 0) { return n2; } if (n2 == 0) { return n1; } int n; for (n = 0; ((n1 | n2) & 1) == 0; n++) { n1 >>= 1; n2 >>= 1; } while ((n1 & 1) == 0) { n1 >>= 1; } do { while ((n2 & 1) == 0) { n2 >>= 1; } if (n1 > n2) { int temp = n1; n1 = n2; n2 = temp; } n2 = (n2 - n1); } while (n2 != 0); return n1 << n; }

Kita dapat melihat bahawa kita menggunakan operasi pergeseran aritmetik untuk membahagi atau mengalikan dengan 2. Selanjutnya, kita menggunakan pengurangan untuk mengurangkan angka yang diberikan.

Kerumitan algoritma Stein apabila n1> n2 adalah O ((log 2 n1) 2) sedangkan. apabila n1 <n2, itu adalah O ((log 2 n2) 2).

5. Kesimpulan

Dalam tutorial ini, kami melihat pelbagai kaedah untuk mengira GCD dua nombor. Kami juga menerapkannya di Jawa dan melihat kerumitannya dengan cepat.

Seperti biasa, kod sumber lengkap contoh kami di sini, seperti biasa, habis di GitHub.