0Pricing
Kotlin Academy · Pelajaran

Fungsi tailrec

Optimalkan rekursi

Fungsi tailrec adalah pelajaran Kotlin Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Kotlin Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Kotlin Academy mencakup 4 pelajaran total.

Apa Itu Rekursi Ekor

Sebuah fungsi bersifat rekursi ekor jika pemanggilan rekursifnya merupakan operasi terakhir. Kotlin kemudian dapat mengoptimalkannya menjadi perulangan sehingga luapan tumpukan dapat dihindari.

tailrec fun countdown(n: Int) {
    if (n < 0) return
    println(n)
    countdown(n - 1)
}

fun main() {
    countdown(3)
}

Modifier Rekursi Ekor

Tambahkan modifier tailrec dan kompilator akan menulis ulang rekursi tersebut sebagai iterasi dengan menggunakan ruang tumpukan yang konstan.

tailrec fun sum(n: Int, acc: Int = 0): Int {
    if (n == 0) return acc
    return sum(n - 1, acc + n)
}

fun main() {
    println(sum(100))
}

Pola Accumulator

Agar rekursi berbentuk ekor, teruskan hasil melalui parameter akumulator sehingga tidak ada lagi perhitungan yang tersisa setelah pemanggilan.

tailrec fun factorial(n: Int, acc: Long = 1): Long {
    if (n <= 1) return acc
    return factorial(n - 1, acc * n)
}

fun main() {
    println(factorial(10))
}

Mengapa Pemanggilan Harus Menjadi yang Terakhir

Jika ada hal yang dilakukan setelah pemanggilan rekursif, seperti mengalikan hasilnya, pemanggilan tersebut tidak berada pada posisi ekor dan tidak dapat dioptimalkan.

tailrec fun length(s: String, acc: Int = 0): Int {
    if (s.isEmpty()) return acc
    return length(s.drop(1), acc + 1)
}

fun main() {
    println(length("hello"))
}

Contoh Tandingan Rekursi Bukan Ekor

Faktorial ini bersifat NOT rekursi ekor karena perkalian dilakukan setelah pemanggilan mengembalikan hasil. Menandainya dengan tailrec akan memunculkan peringatan.

fun badFactorial(n: Int): Long {
    if (n <= 1) return 1
    return n * badFactorial(n - 1)
}

fun main() {
    println(badFactorial(5))
}

Menghindari Luapan Tumpukan

Rekursi mendalam tanpa tailrec dapat menyebabkan kerusakan. Dengan modifier tersebut, input berukuran besar sekalipun dapat diproses menggunakan ruang tumpukan yang konstan.

tailrec fun count(n: Int, acc: Int = 0): Int {
    if (n == 0) return acc
    return count(n - 1, acc + 1)
}

fun main() {
    println(count(100000))
}

Verifikasi oleh Kompilator

Jika Anda menandai sebuah fungsi dengan tailrec tetapi pemanggilannya tidak berada pada posisi ekor, kompilator akan mengeluarkan peringatan dan tidak mengoptimalkannya. Percayailah peringatan tersebut.

tailrec fun gcd(a: Int, b: Int): Int {
    if (b == 0) return a
    return gcd(b, a % b)
}

fun main() {
    println(gcd(48, 18))
}

Rekursi Ekor dan Perulangan

Fungsi tailrec dikompilasi menjadi kode yang kurang lebih sama dengan perulangan yang setara, tetapi menyatakan algoritmanya secara rekursif.

tailrec fun powerOfTwo(n: Int, acc: Long = 1): Long {
    if (n == 0) return acc
    return powerOfTwo(n - 1, acc * 2)
}

fun main() {
    println(powerOfTwo(10))
}

Beberapa Parameter

Fungsi rekursi ekor sering meneruskan beberapa parameter status, yang semuanya diperbarui dalam pemanggilan rekursif.

tailrec fun fib(n: Int, a: Long = 0, b: Long = 1): Long {
    if (n == 0) return a
    return fib(n - 1, b, a + b)
}

fun main() {
    println(fib(20))
}

Membalikkan dengan tailrec

Akumulator dapat membangun hasil seperti teks yang dibalik.

tailrec fun reverse(s: String, acc: String = ""): String {
    if (s.isEmpty()) return acc
    return reverse(s.drop(1), s.first() + acc)
}

fun main() {
    println(reverse("kotlin"))
}

Pencarian Praktis

Pencarian iteratif dapat dipetakan dengan rapi ke rekursi ekor.

tailrec fun indexOf(list: List<Int>, target: Int, i: Int = 0): Int {
    if (i >= list.size) return -1
    if (list[i] == target) return i
    return indexOf(list, target, i + 1)
}

fun main() {
    println(indexOf(listOf(5, 6, 7), 7))
}

Pemeriksaan Singkat

Uji pemahaman Anda tentang fungsi tailrec.

Rangkuman

Anda telah mempelajari fungsi tailrec:

  • tailrec mengubah rekursi pada posisi ekor menjadi perulangan sehingga luapan tumpukan dapat dihindari.
  • Pemanggilan rekursif harus menjadi operasi terakhir.
  • Gunakan parameter akumulator untuk mencapai bentuk ekor.
  • Kompilator memberikan peringatan jika sebuah fungsi tidak dapat dioptimalkan.
tailrec fun sum(n: Int, acc: Int = 0): Int =
    if (n == 0) acc else sum(n - 1, acc + n)

fun main() {
    println(sum(50))
}

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Fungsi tailrec” gratis?

Ya — teks lengkap “Fungsi tailrec” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Kotlin Academy, upgrade ke CoddyKit PRO. Kursus Kotlin Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Fungsi tailrec”?

Optimalkan rekursi Kamu berlatih Kotlin Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Kotlin Academy?

Tidak diperlukan pengalaman sebelumnya. Kotlin Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.

Berapa lama pelajaran “Fungsi tailrec” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Kotlin Academy ini?

Ya. Setiap pelajaran Kotlin Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Fungsi Infix
  2. Membangun API Mirip DSL
  3. Fungsi tailrec
  4. Kapan Menggunakan Masing-masingnya
← Kembali ke Kotlin Academy