Jadual Kandungan
Masalah rekursi?
Springboard
sum?
Gunakan jenis untuk menerangkan papan anjal
Panggilan ekor Fibonacci
Rumah Java javaTutorial Trampolin, contoh di Jawa

Trampolin, contoh di Jawa

Jan 17, 2025 pm 08:18 PM

Trampolim, exemplo em Java

Mari kita tulis atur cara mudah untuk menambah nombor daripada n kepada 0. Tetapi daripada menggunakan pendekatan berulang, mengapa tidak mencuba pendekatan rekursif?

Kami memanggil program ini sum. Kami tahu sum(0) == 0, jadi ini adalah kes asas kami. Bagaimanakah kita sampai ke kes asas? sum(n) == n sum(n-1), sehingga akhirnya mencapai sum(0). Kod Java adalah seperti berikut:

1

2

3

4

5

6

int sum(int n) {

    if (n == 0) {

        return 0;

    }

    return n + sum(n - 1);

}

Salin selepas log masuk
Salin selepas log masuk

Masalah rekursi?

Rekursi mempunyai kelemahan yang wujud apabila kes asas berada jauh daripada nilai input... Dalam kebanyakan bahasa, panggilan fungsi menggunakan tindanan program untuk menyimpan maklumat panggilan fungsi, jadi rekursi yang sangat besar boleh menyebabkan limpahan tindanan.

Tetapi, adakah cara untuk mengelakkan perkara ini? Sebenarnya ada. Ini adalah strategi lama yang dipanggil trampolin.

Springboard

Idea asas strategi papan anjal ialah sebahagian daripada program mengembalikan "nilai" atau "sambungan". Apakah kesinambungan? Fungsi yang akan meneruskan pemprosesan.

Ia kira-kira seperti berikut:

1

2

3

4

5

6

let trampolim = primeiraChamada(input);

 

while (trampolim is continuation) {

    trampolim = trampolim.continue();

}

return trampolim;

Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Apakah kesinambungan

sum?

Mari kita model sum program sebagai: Daripada hanya mengulangi, gunakan sambungan. Satu cara ialah menggunakan acc sebagai objek yang dilalui melalui sambungan. Jadi apabila sum_trampoline(0, acc) dicapai, kami kembali acc. Bagaimana untuk meneruskan?

Mari kita pergi dari sum_trampoline(n, acc) ke sum_trampoline(n-1, acc n). Input pertama ialah sum_trampoline(n, 0).

Jadi, kodnya adalah seperti berikut:

1

2

3

4

5

6

7

8

9

10

Object sum_trampoline_bootstrap(int n) {

    return sum_trampoline(n, 0);

}

 

Object sum_trampoline(int n, int acc) {

    if (n == 0) {

        return acc;

    }

    return (Supplier<object>) () -> sum(n - 1, acc + n);

}

Salin selepas log masuk
Salin selepas log masuk

Gunakan jenis untuk menerangkan papan anjal

Papan anjal perlu kira-kira dalam bentuk berikut:

1

2

3

4

5

6

let trampolim = primeiraChamada(input);

 

while (trampolim is continuation) {

    trampolim = trampolim.continue();

}

return trampolim;

Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Tetapi ini memberikan banyak kebebasan pengekodan dan tidak begitu intuitif untuk dunia Java. Kita boleh menyemak sama ada ia adalah kesinambungan dengan bertanya objek. Bagaimana jika kita bertanya "Adakah nilai ditemui?" Perkara lain ialah memandangkan Java tidak mempunyai jumlah-jenis, return trampolim sebenarnya akan mengembalikan jenis trampolim dan bukannya mengembalikan nilai. Kita boleh kembali ke trampolim.value().

Akhir sekali, perkara utama ialah bootstrap papan anjal. Untuk melakukan ini, kita boleh menggunakan fungsi untuk menukar input kepada nilai pulangan pogo yang sesuai. Input dan hasil boleh digeneralisasikan untuk kegunaan yang lebih baik:

1

2

3

4

5

6

7

8

public static <R> R trampoline(IN input,

                                   Function<IN, TrampolineStep<R>> trampolinebootStrap) {

  TrampolineStep<R> nextStep = trampolinebootStrap.apply(input);

  while (!nextStep.gotValue()) {

    nextStep = nextStep.runNextStep();

  }

  return nextStep.value();

}

Salin selepas log masuk
Salin selepas log masuk

TrampolineStep<R>Bagaimana pula dengan antara muka?

Ia mentakrifkan tiga kaedah:

  • gotValue: Bertanya sama ada nilai telah ditemui
  • value: Mengembalikan nilai yang ditemui
  • runNextStep: Mengembalikan nilai atau kesinambungan

Ia pada asasnya mempunyai dua keadaan:

  • Nilai ditemui
  • Ia adalah kesinambungan

Oleh itu, kita boleh menggunakan kaedah statik untuk memulakannya. Untuk kes di mana nilai telah ditemui, nilai perlu diluluskan:

1

2

3

4

5

6

int sum(int n) {

    if (n == 0) {

        return 0;

    }

    return n + sum(n - 1);

}

Salin selepas log masuk
Salin selepas log masuk

Untuk kes sambungan, anda perlu lulus cara mendapatkan item sambungan seterusnya:

1

2

3

4

5

6

let trampolim = primeiraChamada(input);

 

while (trampolim is continuation) {

    trampolim = trampolim.continue();

}

return trampolim;

Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

sum_trampolineBagaimana ini akan dicapai?

1

2

3

4

5

6

7

8

9

10

Object sum_trampoline_bootstrap(int n) {

    return sum_trampoline(n, 0);

}

 

Object sum_trampoline(int n, int acc) {

    if (n == 0) {

        return acc;

    }

    return (Supplier<object>) () -> sum(n - 1, acc + n);

}

Salin selepas log masuk
Salin selepas log masuk

Panggilan ekor Fibonacci

Pelaksanaan klasik Fibonacci mengikut definisi rekursif:

1

2

3

4

5

6

let trampolim = primeiraChamada(input);

 

while (trampolim is continuation) {

    trampolim = trampolim.continue();

}

return trampolim;

Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Terdapat juga versi berulang yang mengembangkan definisi Fibonacci bukan secara rekursif, tetapi ke hadapan: bermula dari 0 dan 1 sehingga nilai yang sepadan dicapai:

1

2

3

4

5

6

7

8

public static <R> R trampoline(IN input,

                                   Function<IN, TrampolineStep<R>> trampolinebootStrap) {

  TrampolineStep<R> nextStep = trampolinebootStrap.apply(input);

  while (!nextStep.gotValue()) {

    nextStep = nextStep.runNextStep();

  }

  return nextStep.value();

}

Salin selepas log masuk
Salin selepas log masuk

Terdapat versi hadapan pelaksanaan ini, menggunakan "rekursi panggilan ekor":

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

static <X> TrampolineStep<X> valueFound(X value) {

    return new TrampolineStep() {

        @Override

        public boolean gotValue() {

            return true;

        }

 

        @Override

        public X value() {

            return value;

        }

 

        @Override

        public TrampolineStep<X> runNextStep() {

            return this;

        }

    };

}

Salin selepas log masuk

Di sini saya memisahkan antara muka input, yang menyediakan nombor yang akan digunakan dalam panggilan ekor rekursif Fibonacci. Semasa ia bergerak ke hadapan, kita mulakan dengan pemetaan fib[0] => 0, fib[1] => 1 dan menavigasi dari indeks 0 sehingga kita mencapai indeks n.

Fibonacci: Dari Panggilan Ekor ke Papan anjal

Contoh

fib_tc menggambarkan papan anjal Fibonacci dengan baik:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

static <X> TrampolineStep<X> goonStep(Supplier<TrampolineStep<X>> x) {

    return new TrampolineStep() {

        @Override

        public boolean gotValue() {

            return false;

        }

 

        @Override

        public X value() {

            throw new RuntimeException("dont call this");

        }

 

        @Override

        public TrampolineStep<X> runNextStep() {

            return x.get();

        }

    };

}

Salin selepas log masuk

Sila ambil perhatian bahawa ini hanyalah rangka dan memerlukan pelaksanaan lengkap antara muka TrampolineStep dan pelaksanaan lengkap fungsi trampoline untuk menyusun dan menjalankan. Selain itu, IN perlu digantikan dengan jenis input tertentu.

Atas ialah kandungan terperinci Trampolin, contoh di Jawa. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Tag artikel panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Rangka Kerja 4 JavaScript teratas pada tahun 2025: React, Angular, Vue, Svelte Rangka Kerja 4 JavaScript teratas pada tahun 2025: React, Angular, Vue, Svelte Mar 07, 2025 pm 06:09 PM

Rangka Kerja 4 JavaScript teratas pada tahun 2025: React, Angular, Vue, Svelte

Bagaimanakah mekanisme kelas muatan Java berfungsi, termasuk kelas yang berbeza dan model delegasi mereka? Bagaimanakah mekanisme kelas muatan Java berfungsi, termasuk kelas yang berbeza dan model delegasi mereka? Mar 17, 2025 pm 05:35 PM

Bagaimanakah mekanisme kelas muatan Java berfungsi, termasuk kelas yang berbeza dan model delegasi mereka?

Bagaimanakah saya menggunakan Maven atau Gradle untuk Pengurusan Projek Java Lanjutan, Membina Automasi, dan Resolusi Ketergantungan? Bagaimanakah saya menggunakan Maven atau Gradle untuk Pengurusan Projek Java Lanjutan, Membina Automasi, dan Resolusi Ketergantungan? Mar 17, 2025 pm 05:46 PM

Bagaimanakah saya menggunakan Maven atau Gradle untuk Pengurusan Projek Java Lanjutan, Membina Automasi, dan Resolusi Ketergantungan?

Node.js 20: Peningkatan Prestasi Utama dan Ciri -ciri Baru Node.js 20: Peningkatan Prestasi Utama dan Ciri -ciri Baru Mar 07, 2025 pm 06:12 PM

Node.js 20: Peningkatan Prestasi Utama dan Ciri -ciri Baru

Iceberg: Masa Depan Jadual Data Tasik Iceberg: Masa Depan Jadual Data Tasik Mar 07, 2025 pm 06:31 PM

Iceberg: Masa Depan Jadual Data Tasik

Spring Boot Snakeyaml 2.0 CVE-2022-1471 Isu Tetap Spring Boot Snakeyaml 2.0 CVE-2022-1471 Isu Tetap Mar 07, 2025 pm 05:52 PM

Spring Boot Snakeyaml 2.0 CVE-2022-1471 Isu Tetap

Bagaimanakah saya dapat melaksanakan teknik pengaturcaraan berfungsi di Java? Bagaimanakah saya dapat melaksanakan teknik pengaturcaraan berfungsi di Java? Mar 11, 2025 pm 05:51 PM

Bagaimanakah saya dapat melaksanakan teknik pengaturcaraan berfungsi di Java?

Bagaimanakah saya boleh menggunakan JPA (Java Constence API) untuk pemetaan objek-objek dengan ciri-ciri canggih seperti caching dan malas malas? Bagaimanakah saya boleh menggunakan JPA (Java Constence API) untuk pemetaan objek-objek dengan ciri-ciri canggih seperti caching dan malas malas? Mar 17, 2025 pm 05:43 PM

Bagaimanakah saya boleh menggunakan JPA (Java Constence API) untuk pemetaan objek-objek dengan ciri-ciri canggih seperti caching dan malas malas?

See all articles