Jumlah Digit dalam Integer di Java

1. Perkenalan

Dalam tutorial singkat ini, kita akan menjelajahi berbagai cara untuk mendapatkan jumlah digit dalam Integer di Java.

Kami juga akan menganalisis berbagai metode tersebut dan akan mencari tahu algoritma mana yang paling sesuai dengan situasi kami.

2. Jumlah Digit dalam Integer

Untuk metode yang dibahas di sini, kami hanya mempertimbangkan bilangan bulat positif. Jika kita mengharapkan masukan negatif, maka kita dapat menggunakan Math.abs (bilangan) terlebih dahulu sebelum menggunakan salah satu metode ini.

2.1. Solusi Berbasis String

Mungkin cara termudah untuk mendapatkan jumlah digit dalam Integer adalah dengan mengubahnya menjadi String , dan memanggil metode length () . Ini akan mengembalikan panjang representasi String dari nomor kita:

int length = String.valueOf(number).length();

Tapi, ini mungkin pendekatan sub-optimal, karena pernyataan ini melibatkan alokasi memori untuk String, untuk setiap evaluasi . JVM pertama-tama harus mengurai nomor kami dan menyalin digitnya ke dalam String terpisah dan melakukan sejumlah operasi berbeda juga (seperti menyimpan salinan sementara, menangani konversi Unicode, dll.).

Jika kita hanya memiliki beberapa angka untuk dievaluasi, maka kita dapat dengan jelas menggunakan solusi ini - karena perbedaan antara ini dan pendekatan lainnya akan diabaikan bahkan untuk jumlah besar.

2.2. Pendekatan Logaritmik

Untuk bilangan yang direpresentasikan dalam bentuk desimal, jika kita mengambil log mereka di basis 10 dan membulatkannya maka kita akan mendapatkan jumlah digit dalam bilangan itu:

int length = (int) (Math.log10(number) + 1);

Perhatikan bahwa log 10 0 nomor apa pun tidak ditentukan. Jadi jika kita mengharapkan masukan apa pun dengan nilai 0 , maka kita bisa memeriksanya juga.

Pendekatan logaritmik secara signifikan lebih cepat daripada pendekatan berbasis String karena tidak harus melalui proses konversi data apa pun. Ini hanya melibatkan penghitungan sederhana dan langsung tanpa inisialisasi objek tambahan atau loop.

2.3. Perkalian Berulang

Dalam metode ini, kita akan mengambil variabel sementara (diinisialisasi ke 1) dan akan terus mengalikannya dengan 10 hingga menjadi lebih besar dari bilangan kita. Selama proses ini, kita juga akan menggunakan variabel panjang yang akan melacak panjang nomor:

int length = 0; long temp = 1; while (temp <= number) { length++; temp *= 10; } return length;

Pada kode ini, baris temp * = 10 sama dengan penulisan temp = (temp << 3) + (temp << 1) . Karena perkalian biasanya lebih mahal operasi pada beberapa prosesor jika dibandingkan dengan operator shift, yang terakhir mungkin sedikit lebih efisien.

2.4. Membagi Dengan Kekuatan Dua

Jika kita mengetahui tentang kisaran angka kita, maka kita dapat menggunakan variasi yang selanjutnya akan mengurangi perbandingan kita. Metode ini membagi bilangan dengan pangkat dua (misalnya 1, 2, 4, 8 dll.):

Metode ini membagi angka dengan pangkat dua (misalnya 1, 2, 4, 8 dll.):

int length = 1; if (number >= 100000000) { length += 8; number /= 100000000; } if (number >= 10000) { length += 4; number /= 10000; } if (number >= 100) { length += 2; number /= 100; } if (number >= 10) { length += 1; } return length;

Ini memanfaatkan fakta bahwa bilangan apa pun dapat diwakili dengan penambahan pangkat 2. Misalnya, 15 dapat direpresentasikan sebagai 8 + 4 + 2 + 1, yang semuanya adalah pangkat 2.

Untuk angka 15 digit, kami akan melakukan 15 perbandingan dalam pendekatan kami sebelumnya, yang telah kami kurangi menjadi hanya 4 dalam metode ini.

2.5. Memecah dan menaklukkan

Ini mungkin pendekatan yang paling rumit jika dibandingkan dengan semua yang lain yang dijelaskan di sini, tetapi tentu saja, ini adalah yang tercepat karena kami tidak melakukan jenis konversi, perkalian, penambahan, atau inisialisasi objek apa pun.

Kami mendapatkan jawaban kami hanya dalam tiga atau empat pernyataan if sederhana :

if (number < 100000) { if (number < 100) { if (number < 10) { return 1; } else { return 2; } } else { if (number < 1000) { return 3; } else { if (number < 10000) { return 4; } else { return 5; } } } } else { if (number < 10000000) { if (number < 1000000) { return 6; } else { return 7; } } else { if (number < 100000000) { return 8; } else { if (number < 1000000000) { return 9; } else { return 10; } } } }

Mirip dengan pendekatan sebelumnya, kita dapat menggunakan metode ini hanya jika kita tahu tentang kisaran nomor kita.

3. Pembandingan

Sekarang setelah kita memiliki pemahaman yang baik tentang solusi potensial, sekarang mari kita lakukan pembandingan sederhana dari semua metode kita menggunakan Java Microbenchmark Harness (JMH).

The following table shows the average processing time of each operation (in nanoseconds):

Benchmark Mode Cnt Score Error Units Benchmarking.stringBasedSolution avgt 200 32.736 ± 0.589 ns/op Benchmarking.logarithmicApproach avgt 200 26.123 ± 0.064 ns/op Benchmarking.repeatedMultiplication avgt 200 7.494 ± 0.207 ns/op Benchmarking.dividingWithPowersOf2 avgt 200 1.264 ± 0.030 ns/op Benchmarking.divideAndConquer avgt 200 0.956 ± 0.011 ns/op

The String-based solution, which is the simplest, is also the most costly operation – as this is the only one which requires data conversion and initialization of new objects.

The logarithmic approach is significantly more efficient, compared to the previous solution – as it doesn't involve any data conversion. And, being a single line solution, it can be a good alternative to String-based approach.

Repeated multiplication involves simple multiplication, proportionally with the number length; for example, if a number is fifteen digits long, then this method will involve fifteen multiplications.

Namun, metode selanjutnya memanfaatkan fakta bahwa setiap bilangan dapat diwakili oleh pangkat dua (pendekatan yang mirip dengan BCD), dan mengurangi hal yang sama menjadi 4 operasi pembagian, sehingga lebih efisien daripada yang sebelumnya.

Terakhir, seperti yang dapat kita simpulkan, algoritme yang paling efisien adalah implementasi Divide and Conquer verbose - yang memberikan jawaban hanya dalam tiga atau empat pernyataan if sederhana. Kita dapat menggunakannya jika kita memiliki kumpulan data angka yang besar yang perlu kita analisis.

4. Kesimpulan

Dalam artikel singkat ini, kami menguraikan beberapa cara untuk menemukan jumlah digit dalam sebuah Integer dan kami membandingkan efisiensi setiap pendekatan.

Dan, seperti biasa, Anda dapat menemukan kode lengkapnya di GitHub.