Hỏi/ Thắc mắc - Cách gom 2 đệ quy thành 1 đệ quy | VN-Zoom | Cộng đồng Chia Sẻ Kiến Thức Công Nghệ và Phần Mềm Máy Tính

Adblocker detected! Please consider reading this notice.

We've detected that you are using AdBlock Plus or some other adblocking software which is preventing the page from fully loading.

We need money to operate the site, and almost all of it comes from our online advertising.

If possible, please support us by clicking on the advertisements.

Please add vn-z.vn to your ad blocking whitelist or disable your adblocking software.

×

Hỏi/ Thắc mắc Cách gom 2 đệ quy thành 1 đệ quy

boyfriend

Búa Gỗ Đôi
Xin chào mọi người,
Mình đang trong quá trình học C/C++. Tuy nhiên, mình gặp phải một số vướng mắc. Mong các bạn có thể hỗ trợ mình.

Đề bài:
7JxJRi9.png


2 vòng đệ quy:
QmSVal3.png


Trong đó, Tinh là dùng để tính phép nhân. Còn Tinh2 dùng để tính tổng.

Giờ mình muốn gom lại 1 đệ quy thôi nhưng mình không suy nghĩ ra, không biết các bạn có suy nghĩ nào không ?
 

boyfriend

Búa Gỗ Đôi
Nếu bạn muốn nó trong một hàm thì đây:

Mã:
function dq(N,a)
{
  if (N<1){
    if (a < 2) return 1;
    else return a*dq(N,a-1);
  }
  else if (N < 2)
    return 1
  return dq(0,N) + dq(N-1,0);
}
Nếu muốn tính S(5) thì :
alert(dq(5,0));

@dongle905 em còn cách nào khác không ngoài vòng lặp
Mình cũng chưa nghĩ ra ngoài vòng lặp ở trong hàm đệ quy.
Cám ơn 2 bạn nhiều.
Học kĩ thuật lập trình thì nên chia để trị để tìm đệ quy, cớ sao bạn lại tìm cách gom vào 1 thế
Đúng là mình đang học kỹ thuật lập trình, mình muốn gom làm 1 để nhìn cho nó gọn, với lại có lẽ nó sẽ nhanh hơn. Code của bạn mình đọc chưa hiểu lắm, cơ mà code của bạn là cần lên một trình độ cao hơn mới viết được hả bạn.
 

dammage

Rìu Chiến
Xin chào mọi người,
Mình đang trong quá trình học C/C++. Tuy nhiên, mình gặp phải một số vướng mắc. Mong các bạn có thể hỗ trợ mình.

Đề bài:
7JxJRi9.png


2 vòng đệ quy:
QmSVal3.png


Trong đó, Tinh là dùng để tính phép nhân. Còn Tinh2 dùng để tính tổng.

Giờ mình muốn gom lại 1 đệ quy thôi nhưng mình không suy nghĩ ra, không biết các bạn có suy nghĩ nào không ?
bài này tui xài đệ quy đuôi (tail recursive), bạn mới học nếu chưa biết đệ quy đuôi là gì thì google tìm hiểu thêm (dễ hiểu lắm), ở đây tui giải thích đại khái thôi, đó là truyền kết quả tính được từ lần gọi trước cho lần gọi sau thông qua tham số hàm, hàm lúc này sẽ có thêm 1 tham số phụ, giống cái dq(n, a) của bạn ở trên thì a chính là tham số phụ để truyền giữa các lần gọi đệ quy đó

giờ phân tích thử bài này, tui thử cách đặt nhân tử chung để coi có thể tính được các cụm nhân theo từng bước hay không
s = 1 + 1.2 + 1.2.3 + 1.2.3......n

nếu đặt 1 là nhân tử chung thì sẽ được
1(1 + 2 + 2.3 + 2.3......n)

tiếp tục đặt 2 là nhân tử chung thì được
1(1 + 2(1 + 3 + 3......n))

tiếp tục đặt 3 là nhân tử chung
1(1 + 2(1 + 3(1 + ......n)))

cứ đặt như vậy cuối cùng sẽ thành ra
1(1 + 2(1 + 3(1 + ............ (n - 1).(1 + n)

xong, quy luật giờ quá dễ thấy, nếu viết hàm đệ quy có n giảm dần thì
1/tại mỗi lần gọi ta tính 1 + n*kết quả từ lần gọi trước, xong truyền cái kết quả này cho lần gọi sau, tiếp tục như vậy cho tới khi n <= 1
2/ở lần gọi đầu tiên, do kết quả trước đó chưa có nên chỉ là 1 + n thôi

viết thành code
C:
unsigned int tinh(int n, unsigned int kq_tu_lan_goi_truoc = 1)
{
    if(n <= 1)
        return kq_tu_lan_goi_truoc;

    tinh(n - 1, n*kq_tu_lan_goi_truoc + 1);
}
vài lưu ý
1/ở lần gọi đầu tiên thì kết quả trước đó chưa có nên phải gán giá trị mặc định cho biến kq_tu_lan_goi_truoc là 1
2/kết quả thường rất lớn nên bạn nhớ cho kiểu trả về của hàm lớn lớn chút, chẳng hạn như long long int hay gì đó

xong rồi, test thôi, ở đây tui viết luôn 1 cái hàm thường tính bằng vòng lặp để so sánh
Untitled.jpg

thử n = 5, kết quả = 153
thử n = 8, kết quả = 46233

tạm như vậy, chưa nghĩ ra cách nào hay hơn
 

boyfriend

Búa Gỗ Đôi
bài này tui xài đệ quy đuôi (tail recursive), bạn mới học nếu chưa biết đệ quy đuôi là gì thì google tìm hiểu thêm (dễ hiểu lắm), ở đây tui giải thích đại khái thôi, đó là truyền kết quả tính được từ lần gọi trước cho lần gọi sau thông qua tham số hàm, hàm lúc này sẽ có thêm 1 tham số phụ, giống cái dq(n, a) của bạn ở trên thì a chính là tham số phụ để truyền giữa các lần gọi đệ quy đó

giờ phân tích thử bài này, tui thử cách đặt nhân tử chung để coi có thể tính được các cụm nhân theo từng bước hay không
s = 1 + 1.2 + 1.2.3 + 1.2.3......n

nếu đặt 1 là nhân tử chung thì sẽ được
1(1 + 2 + 2.3 + 2.3......n)

tiếp tục đặt 2 là nhân tử chung thì được
1(1 + 2(1 + 3 + 3......n))

tiếp tục đặt 3 là nhân tử chung
1(1 + 2(1 + 3(1 + ......n)))

cứ đặt như vậy cuối cùng sẽ thành ra
1(1 + 2(1 + 3(1 + ............ (n - 1).(1 + n)

xong, quy luật giờ quá dễ thấy, nếu viết hàm đệ quy có n giảm dần thì
1/tại mỗi lần gọi ta tính 1 + n*kết quả từ lần gọi trước, xong truyền cái kết quả này cho lần gọi sau, tiếp tục như vậy cho tới khi n <= 1
2/ở lần gọi đầu tiên, do kết quả trước đó chưa có nên chỉ là 1 + n thôi

viết thành code
C:
unsigned int tinh(int n, unsigned int kq_tu_lan_goi_truoc = 1)
{
    if(n <= 1)
        return kq_tu_lan_goi_truoc;

    tinh(n - 1, n*kq_tu_lan_goi_truoc + 1);
}
vài lưu ý
1/ở lần gọi đầu tiên thì kết quả trước đó chưa có nên phải gán giá trị mặc định cho biến kq_tu_lan_goi_truoc là 1
2/kết quả thường rất lớn nên bạn nhớ cho kiểu trả về của hàm lớn lớn chút, chẳng hạn như long long int hay gì đó

xong rồi, test thôi, ở đây tui viết luôn 1 cái hàm thường tính bằng vòng lặp để so sánh
Untitled.jpg

thử n = 5, kết quả = 153
thử n = 8, kết quả = 46233

tạm như vậy, chưa nghĩ ra cách nào hay hơn
cách của bác dễ hiểu quá, cảm ơn bác nhiều.
 

dammage

Rìu Chiến
Bạn coi thử cách của mình xem sao nhé.
C:
// Recursion.c
#include <stdio.h>

int tong(int n) {
    if (n == 1) {
        return 1;
    }
    int sum = 1;
    for(int i = 1; i <= n; i++) {
        sum *= i;
    }
    return tong(n-1) + sum;
}

int main() {
    int n;
    printf("Nhap n:");
    scanf("%d",&n);
    printf("Tong S la: %d",tong(n));
    return 0;
}
cách này là đơn giản dễ hiểu nhất
 


Top