Operator Ternary dan Nilai Boolean
Di blog ini pernah dibahas mengenai operator ternary untuk menyingkat kode. Contohnya ada sepotong kode seperti berikut:
if ($nilai > 90) echo "Keren"; else echo "Lumayan";
Kode di atas dapat ditulis ulang menggunakan operator ternary menjadi seperti berikut:
echo ($var > 90) ? "Keren" : "Lumayan";
Seorang programer berpengalaman pasti lebih suka menggunakan operator ternary bahkan untuk yang melibatkan lebih dari dua buah pernyataan. Namun tidak direkomendasikan untuk para pemula karena bisa membingungkan.
Saya sendiri pernah melakukan hal konyol pada tulisan yang lalu, yaitu penggunaan operator ternary dengan nilai boolean yang tidak semestinya.
$cek = ($var > 5) ? true : false;
Padahal seharusnya cukup ditulis seperti ini:
$cek = $var > 5;
Variable $cek
otomatis bernilai true
jika kondisi $var > 5
terpenuhi. Sebaliknya bernilai false
jika kondisi tidak terpenuhi. Contoh kasus lain penggunaan operator ternary yang tidak semestinya adalah:
$cek = ($var == true) ? 1 : 0;
Secara tidak sadar mungkin kita sering melakukan hal semacam ini dalam pengkodean sehari-hari. Pada contoh di atas juga terdapat kondisi yang tidak perlu dan seharusnya dihilangkan sehingga menjadi seperti berikut:
$cek = $var ? 1 : 0;
Catatan ini juga sebagai koreksi untuk tulisan yang lalu.
Menukar Nilai Dua Variable Tanpa Perantara
Menukar nilai dua buah variable adalah salah satu algoritma dasar dalam struktur data. Biasanya untuk menulis fungsi swap ini, kita membutuhkan tambahan satu variable sebagai perantara. Berikut ini adalah algoritma untuk menukar nilai dua buah variable dengan perantara.
tmp = x; x = y; y = tmp;
Pada contoh di atas nilai variable x
dan y
bertukar melalui perantara tmp
. Berikut ini adalah algoritma untuk menukar nilai dua buah variable tanpa perantara.
x = x ^ y; y = x ^ y; x = x ^ y;
Singkat dan sederhana, nilai variable x
dan y
sudah bertukar. Tanda caret ^
dalam bahasa pemrograman Java dan C adalah operator bitwise (logika) XOR (Eksklusif Or). Pada eksklusif or berlaku hukum alternatif, yaitu hanya salah satu saja yang boleh bernilai true. Perbedaannya dengan inklusif or (OR) adalah berlaku hukum kumulatif, yaitu boleh salah satu atau keduanya bernilai true.
x y OR XOR -------------- 0 0 0 0 0 1 1 1 1 0 1 1 1 1 1 0
Penjelasan dari keajaiban pertukaran di atas adalah karena operator XOR memiliki dua sifat. Pertama, menggabungkan/mencampurkan informasi, dan kedua, mampu memisahkannya kembali (sekaligus menghapus jejak penggabungannya) dengan cara melakukan lagi operasi XOR kepadanya.
Pada baris pertama, nilai x
dan y
digabungkan sehingga membentuk suatu nilai hybrid di antara keduanya (sifat 1). Simpan nilai hybrid tersebut di x
. Pada baris kedua nilai hybrid di-XOR-kan lagi dengan y
yang akan memunculkan lagi nilai x
semula (sifat 2). Simpan nilai x
semula di y
. Terakhir nilai hybrid di-XOR-kan dengan y
(ingat y
sekarang bernilai x
semula) sehingga memunculkan lagi nilai y
semula (sifat 2). Simpan nilai y
semula di x
.
Supaya lebih jelas lagi, kita coba dengan contoh. Misalnya int x
bernilai 5 (0101) dan int y
bernilai 9 (1001).
x = 5 = 0101; y = 9 = 1001; x = x ^ y; // x = 0101 ^ 1001 = 1100 = hybrid y = x ^ y; // y = 1100 ^ 1001 = 0101 = 5 x = x ^ y; // x = 1100 ^ 0101 = 1001 = 9
Implementasi pertukaran nilai dengan operator logika XOR dalam bahasa pemrograman Java adalah sebagai berikut.
int x = 5, y = 9; x ^= y; // x = hybrid y ^= x; // y = 5 x ^= y; // x = 9
Begitulah cerita dibalik dua nilai variable yang tertukar :D. Pembahasan lebih mendalam tentang XOR Swap Algorithm bisa dibaca di Wikipedia.
Bagaimana Mencari Bilangan Prima?
Salah satu pertanyaan paling penting dalam dunia Matematika adalah menentukan apakah suatu angka merupakan bilangan prima atau tidak. Topik bilangan prima ini juga menjadi salah satu dari tujuh masalah utama dalam bidang Matematika (Millennium Prize Problems), yaitu Riemann hypothesis. Orang pertama yang sanggup memecahkan salah satunya akan mendapat hadiah US$1,000,000 dari Clay Mathematics Institute. Sampai sekarang masih tersisa enam soal yang belum terpecahkan termasuk Riemann hypothesis yang bila dapat dipecahkan dapat menguak pola distribusi bilangan prima.
Bilangan prima adalah bilangan asli yang lebih besar dari 1 dan hanya memiliki dua faktor (pembagi) yaitu 1 dan bilangan itu sendiri. Contoh bilangan prima adalah 7, yang hanya memiliki dua faktor yaitu 1 dan 7. Sebaliknya, 6 bukan merupakan bilangan prima karena memiliki faktor-faktor 1, 2, 3, dan 6. Bilangan selain bilangan prima disebut bilangan komposit.
Bilangan prima sangat menarik karena aturan untuk menentukan bilangan prima sudah sangat jelas dan mudah dipahami, namun belum ada rumus atau persamaan yang mudah untuk menentukan apakah sebuah angka merupakan bilangan prima atau bukan.
Dalam tutorial kali ini akan dibahas bagaimana menentukan sebuah angka adalah prima atau bukan dengan menggunakan bahasa pemrograman Java. Cara yang paling sederhana adalah dengan mencoba membagi sebuah bilangan dengan setiap bilangan dari 2 sampai ke bilangan n – 1. Jika ada satu bilangan saja yang dapat habis membagi berarti bilangan tersebut bukan prima.
boolean isPrime (int n) { for (int i=2; i<n; i++) if (n % i == 0) return false; return true; }
Angka 2 adalah satu-satunya bilangan prima genap, jadi tidak perlu dipusingkan dengan mencobanya. Kode di atas mungkin cukup untuk mencari bilangan kecil, tapi kita butuh algoritma yang lebih cepat/mangkus untuk mencari bilangan besar. Kita tidak perlu mencari dari 2 sampai bilangan n, tapi cukup sampai n/2. Karena jika angka 2 habis membagi n, dapat dipastikan n/2 juga akan habis membagi n.
boolean isPrime (int n) { for (int i=2; i*2<n; i++) if (n % i == 0) return false; return true; }
Masih belum cukup cepat? Algoritma di atas bisa dioptimalkan lagi, yaitu dengan hanya memeriksa bilangan ganjil saja, karena semua bilangan genap pasti habis dibagi 2. Kemudian kita bisa efisienkan percobaan di atas dengan hanya memeriksa pembaginya sampai ke akar kuadrat dari bilangan n (dengan pembulatan ke bawah). Karena jika kita menderetkan semua faktor dari sebuah bilangan, akar kuadratnya pasti selalu berada di tengah-tengah deret tersebut. Misal faktor dari 81 adalah 1, 3, 9, 27, 81. Akar kuadrat dari 81 adalah 9, terletak tepat di tengah-tengah deret tersebut. Tidak perlu diperiksa setengah bagian setelah akar kuadrat karena pasti sudah ketahuan prima atau bukan.
boolean isPrime (long n) { if (n % 2 == 0) return false; for (long i=3; i*i<=n; i+=2) if (n % i == 0) return false; return true; }
Seperti terlihat pada potongan kode di atas, kita hanya memeriksa sampai ke akar kuadrat dari bilangan n dan hanya memproses bilangan ganjil. Dengan algoritma ini, program kita pasti mengalami peningkatan yang signifikan. Terutama ketika bekerja dengan angka yang sangat besar, itulah kenapa digunakan tipe data long
.
Sebenarnya ada satu lagi metode yang lebih mangkus yang disebut The Sieve of Eratosthenes. Namun kurang cocok dengan kebutuhan karena metode ini digunakan untuk mencari semua bilangan prima dari 2 sampai ke bilangan n.
Pembagian dengan Nol dan Kesalahan Kalkulator Google
Ketika duduk di bangku sekolah (baik dasar ataupun menengah), kita diajarkan bahwa pembagian dengan angka nol adalah tak hingga, atau infinity, dan biasanya ditulis dengan lambang ∞. Dengan menggunakan logika sederhana saja, kita dapat membuktikan bahwa pernyataan tersebut salah.
Satu dibagi empat dapat dianalogikan dengan membagi sepotong kue kepada 4 orang, artinya adalah masing-masing orang mendapatkan 1/4 bagian. Sekarang jika satu kue dibagi 0 orang, bagaimana mungkin masing-masing mendapat tak hingga bagian? Orang yang menerima kue saja tidak ada.
Lalu bagaimana jika 0/0? Biasanya setiap bilangan yang dibagi dengan dirinya sendiri hasilnya adalah 1. Namun itu tidak berlaku untuk angka 0. Bagaimana mungkin membagi 0 kue kepada 0 orang dan masing-masing mendapat 1 bagian? Kue dan orang yang menerima sama-sama tidak ada, jadi mustahil bisa muncul angka 1. Dalam matematika kemustahilan dari pembagian dengan angka nol disebut tak terdefinisi (undefined).
Jika dihitung menggunakan kalkulator, pembagian dengan nol akan menghasilkan error. Namun, hasil yang mengejutkan diperoleh dari kalkulator Google. Menurut Google, 1 dibagi 0 adalah Infinity. Programer aplikasi kalkulator Google melakukan kesalahan! Lain halnya jika 0 dibagi 0, kalkulator Google menghasilkan Error.
Analogi di atas mungkin berguna jika kita ingin menjelaskan pembagian dengan nol kepada orang awam atau anak kecil. Konsep matematika tidak bisa hanya dijelaskan dengan analogi, namun membutuhkan definisi atau aksioma.
Belajar Java – Array
Array adalah kumpulan data yang memiliki tipe data dan jumlah elemen yang tetap (tidak bisa ditambah/dikurangi). Array pada Java adalah sebuah object
, maka harus dideklarasikan menggunakan kata kunci new
. Tiap data pada array disebut element, dan masing-masing element dapat diakses menggunakan index yang berupa angka. Index dimulai dari 0 sampai jumlah element – 1.
Contoh untuk mendeklarasikan array sesuai gambar di atas adalah
char [] arrayHuruf = new char[10];
Sedangkan cara untuk menginisialisasinya adalah sebagai berikut
arrayHuruf[0] = 'A'; arrayHuruf[1] = 'B'; //dst
Bisa menggunakan perulangan untuk menginisialisasi array
for (int i = 0; i < 10; i ++) { arrayHuruf[i] = (char) ('A' + i); }
Array arrayHuruf
akan berisi 10 karakter, yaitu ‘A’ sampai ‘J’ secara berurutan. Alternatif lain untuk menginisialisasi array, dapat menggunakan syntax sebagai berikut
char[] arrayHuruf = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J' };
Jumlah element diketahui dari banyaknya nilai di antara tanda ‘{‘ dan ‘}’.
Kita juga dapat mendeklarasikan array dari array atau lebih dikenal sebagai array multidimensi dengan cara seperti berikut char[][] namaArray = new char[10][2]
atau char[][] namaArray = new char[10][]
, tapi tidak boleh seperti ini char[][] namaArray = new char[][2]
. Dalam bahasa Java, pengertian array lebih sederhana daripada pada bahasa C, jadi jumlah element pada baris berikutnya jumlahnya boleh bervariasi (tidak harus sama dengan baris pertama).
char[][] hurufAngka = new char[2][]; hurufAngka[0] = new char[2]; // array index [0][0] sampai [0][1] hurufAngka[1] = new char[1]; // hanya ada array index [1][0]
Array multidimensi juga dapat langsung dideklarasikan dan diinisialisasi seperti berikut
char[][] hurufAngka = { { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J' }, { '1', '2', '3', '4', '5'} };
Pada contoh untuk menginisialisasi di atas, kita menggunakan bentuk perulangan for (nilai_awal; nilai_akhir; penambahan/pengurangan)
, jadi jumlah element-nya harus diketahui. Bagaimana jika jumlah element tidak diketahui? Misalkan kita ingin mencetak array yang berisi huruf-huruf yang tidak diketahui secara pasti jumlahnya. Gunakan enhanced for yang penggunaannya mirip dengan foreach
pada PHP.
char[] arrayHuruf = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J' }; for ( char huruf : arrayHuruf ) { System.out.println( huruf ); }
Kita juga bisa menggunakan built-in property length
untuk mengetahui jumlah element-nya.
for (int i=0; i<arrayHuruf.length; i++) System.out.println( arrayHuruf[i] );
Untuk menyalin array yang satu ke yang lainnya, bisa menggunakan method arraycopy
yang ada pada class System
.
public static void arraycopy(Object arraySumber, int indexSumber, Object arraytujuan, int indexTujuan, int panjangElement)
Contoh penggunaannya adalah seperti berikut
int[] arraySumber = { 1, 2, 3, 4, 5 }; int[] arrayTujuan = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; System.arraycopy (arraySumber, 0, arrayTujuan, 0, arraySumber.length); for (int item : arrayTujuan) System.out.println ( item );
Tambahan:
Meskipun jumlah element pada array tidak bisa ditambah/dikurangi, kita bisa menciptakan array baru dari array yang sudah ada. Namun tentu saja, nilai yang sudah ada akan hilang.
int [] array = new int[5]; array = new int[10];