Saya mencoba untuk menemukan algoritma yang efisien di Jawa untuk menemukan bagian desimal berulang dari dua bilangan bulat adan di bmana a/b.
misalnya. 5/7 = 0.714258 714258 ....
Saat ini saya hanya tahu metode pembagian panjang.
Saya mencoba untuk menemukan algoritma yang efisien di Jawa untuk menemukan bagian desimal berulang dari dua bilangan bulat adan di bmana a/b.
misalnya. 5/7 = 0.714258 714258 ....
Saat ini saya hanya tahu metode pembagian panjang.
Jawaban:
Saya percaya bahwa ada dua pendekatan umum di sini, Anda pada dasarnya dapat "brute force" mencari string berulang berulang, atau Anda dapat menyelesaikannya sebagai masalah teori bilangan.
Sudah lama sejak saya menemukan masalah ini, tetapi kasus khusus (1 / n) adalah masalah # 26 di Project Euler, jadi Anda mungkin dapat menemukan informasi lebih lanjut dengan mencari solusi efisien untuk nama spesifik tersebut. Satu pencarian membawa kita ke situs web Eli Bendersky, tempat dia menjelaskan solusinya . Berikut beberapa teori dari halaman Desimal Ekspansi Mathworld :
Setiap fraksi tidak beraturan
m/nbersifat periodik, dan memiliki periode yang tidaklambda(n)bergantung padam, yang palingn-1panjang digit. Jikanrelatif prima terhadap 10, maka periodelambda(n)darim/nadalah pembagi dariphi(n)dan memiliki paling banyakphi(n)digit, dimanaphiadalah fungsi totient. Ternyata itulambda(n)adalah urutan multiplikasi 10 (modn) (Glaisher 1878, Lehmer 1941). Jumlah digit dalam bagian berulang dari ekspansi desimal dari bilangan rasional juga dapat ditemukan langsung dari urutan multiplikatif dari penyebutnya.
Teori bilangan saya agak berkarat saat ini, jadi yang terbaik yang bisa saya lakukan adalah mengarahkan Anda ke arah itu.
Biarkan n < d, dan Anda mencoba mencari tahu bagian yang berulang n/d. Membiarkan pmenjadi jumlah digit di bagian berulang: lalu n/d = R * 10^(-p) + R * 10^(-2p) + ... = R * ((10^-p)^1 + (10^-p)^2 + ...). Bagian kurung adalah deret geometris, sama dengan 1/(10^p - 1).
Jadi n / d = R / (10^p - 1). Atur ulang untuk mendapatkan R = n * (10^p - 1) / d. Untuk menemukan R, loop pdari 1 hingga tak terbatas, dan berhenti segera setelah dmembagi secara merata n * (10^p - 1).
Berikut ini adalah implementasi dengan Python:
def f(n, d):
x = n * 9
z = x
k = 1
while z % d:
z = z * 10 + x
k += 1
return k, z / d
( kmelacak panjang urutan berulang, sehingga Anda dapat membedakan antara 1/9 dan 1/99, misalnya)
Perhatikan bahwa implementasi ini (ironisnya) berulang selamanya jika ekspansi desimal terbatas, tetapi berakhir jika tidak terbatas! Anda dapat memeriksa kasus ini, karena n/dhanya akan memiliki representasi desimal terbatas jika semua faktor prima dyang bukan 2 atau 5 juga ada n.
0.123123... = 123/999 0.714258714258... = 714258/999999 (=5/7)dll.
Divisi panjang? : /
Ubah hasilnya menjadi string, dan kemudian terapkan algoritma ini ke sana. Gunakan BigDecimal jika string Anda tidak cukup panjang dengan tipe biasa.