Rumah > pembangunan bahagian belakang > C++ > Pelaksanaan rekursif fungsi C++: Bagaimana untuk menggunakan teknik pengoptimuman rekursif ekor?

Pelaksanaan rekursif fungsi C++: Bagaimana untuk menggunakan teknik pengoptimuman rekursif ekor?

PHPz
Lepaskan: 2024-04-22 16:03:02
asal
417 orang telah melayarinya

Masalah kecekapan fungsi rekursif boleh diselesaikan melalui teknologi pengoptimuman rekursif ekor (TCO). Walaupun pengkompil C++ tidak menyokong TCO, ia boleh mensimulasikan tingkah laku ini melalui kata kunci [__tail_recursive](https://en.cppreference.com/w/cpp/keyword/tail_recursive), menukarkan panggilan rekursif kepada lelaran. TCO digunakan apabila panggilan rekursif ialah operasi terakhir fungsi. Ia dilaksanakan dengan menggunakan tupel untuk mengembalikan nilai keadaan baharu dan penunjuk panggilan rekursif ekor, menghapuskan overhed penciptaan bingkai tindanan dan meningkatkan kecekapan.

C++ 函数的递归实现:如何使用尾递归优化技术?

Pelaksanaan Fungsi C++ Rekursif: Panduan Praktikal untuk Menggunakan Teknik Pengoptimuman Rekursi Ekor

Rekursi ialah proses memanggil dirinya sendiri dalam fungsi dan sangat berguna apabila menyelesaikan jenis struktur data tertentu, seperti struktur data travers. Atau cari penyelesaian. Walau bagaimanapun, rekursi boleh mengurangkan kecekapan program dengan mencipta banyak tindanan panggilan fungsi, yang amat membimbangkan apabila bekerja dengan set data yang besar.

Pengoptimuman Rekursif Ekor

Pengoptimuman Rekursi Ekor (TCO) ialah teknik pengkompil yang menukar panggilan rekursif kepada lelaran apabila fungsi membuat panggilan rekursif sebagai operasi terakhirnya, dengan itu menghapuskan overhed penciptaan bingkai tindanan . Ini penting untuk fungsi dengan banyak panggilan rekursif.

Melaksanakan TCO dalam C++

C++ pengkompil biasanya tidak menyokong TCO, tetapi kita boleh menggunakan [__tail_recursion](https://en.cppreference.com/w/cpp /keyword/tail_recursive ) kata kunci mensimulasikan tingkah laku ini: __尾_递归](https://en.cppreference.com/w/cpp/keyword/tail_recursive) 关键字模拟此行为:

#include <utility>

template <typename F, typename T, typename... Args>
std::pair<bool, T> tail_recursive(F&& f, T&& x, Args&&... args) {
  while (true) {
    const bool is_tail_call = false;
    const auto result = f(std::forward<T>(x), std::forward<Args>(args)...);
    if constexpr (!is_tail_call) {
      return result;
    }
    x = std::move(std::get<0>(result));
    f = std::move(std::get<1>(result));
  }
}
Salin selepas log masuk

tail_recursive 函数接收一个函数对象 f、初始状态 x 和附加参数 args。它返回一个元组,其中第一个元素表示是否进行尾递归调用,第二个元素是新状态值。如果当前调用不是尾递归调用,则返回结果;否则,使用新状态值和更新的函数调用进行递归调用。

实战案例

考虑以下用于计算阶乘的递归函数:

int factorial(int n) {
  if (n == 0) {
    return 1;
  }
  return n * factorial(n - 1);
}
Salin selepas log masuk

使用 TCO 将其转换为尾递归:

auto factorial_tail_recursive(int n) {
  auto f = [&](int x, int y) -> std::pair<bool, int> {
    if (x == 0) {
      return {false, y};
    }
    return {true, y * x};
  };

  return tail_recursive(f, 1, n);
}
Salin selepas log masuk

在这个尾递归版本中,内部函数 f 返回一个元组,其中第一个元素表示是否进行尾递归调用,第二个元素是新状态值。每次调用 f 时,它都会更新状态 yrrreee

tail_recursive Fungsi menerima objek fungsi f, keadaan awal x dan parameter tambahanargs. Ia mengembalikan tuple di mana elemen pertama menunjukkan sama ada untuk membuat panggilan rekursif ekor dan elemen kedua ialah nilai keadaan baharu. Jika panggilan semasa bukan panggilan rekursif ekor, hasilnya dikembalikan jika tidak, panggilan rekursif dibuat dengan nilai keadaan baharu dan panggilan fungsi yang dikemas kini. Contoh Praktikal tuple di mana elemen pertama menunjukkan sama ada untuk membuat panggilan rekursif ekor dan elemen kedua ialah nilai keadaan baharu. Setiap kali f dipanggil, ia mengemas kini keadaan y dan mengembalikan boolean yang menunjukkan sama ada untuk membuat panggilan rekursif ekor.

Nota:

TCO tidak boleh digunakan untuk semua fungsi rekursif. Ia boleh digunakan hanya apabila panggilan rekursif adalah operasi terakhir fungsi. 🎜

Atas ialah kandungan terperinci Pelaksanaan rekursif fungsi C++: Bagaimana untuk menggunakan teknik pengoptimuman rekursif ekor?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:php.cn
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
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan