30/09/2018, 16:22

Đệ quy thực hiện các lệnh như thế nào?

Trong video về phần đệ quy của @NguyenVietNamSon,mình thấy khi giải bài toán:
Tính tổng:S=1+2+3+4+5+6+7+…+N.thì anh Sơn code như sau:

int tinhtong(int N,int sum=0,int i=0){
    if(i>N)
        return sum;
    return tinhtong(N,sum+i,i+1);
}
int main(){
    int N=12;
    printf("Tong can tim bang: %d.
",tinhtong(N));
    return 0;
}

Nhưng mình code lại thế này vẫn nhận được kết quả như nhau.Ở đây mình bỏ lệnh return khi gọi lại hàm tinhtong.

int tinhtong(int N,int sum=0,int i=0){
    if(i>N)
        return sum;
    tinhtong(N,sum+i,i+1);
}
int main(){
    int N=12;
    printf("Tong can tim bang: %d.
",tinhtong(N));
    return 0;
}

Cụ thể:
INPUT:

N=12;

OUTPUT:

sum=78;

Nhờ mọi người giải thích giúp mình về tác dụng của lệnh return trong trường hợp này.

Quân viết 18:27 ngày 30/09/2018

return là để trả lại giá trị của 1 hàm nào đó.
Trong TH của bạn hay bài mẫu của bạn Sơn đều gọi đến hàm tinhtong(N, sum+i, i+1) nên nó đều thực hiện hàm đó. Nhưng khác nhau ở đâu?
Khác ở chỗ nếu không có return thì nó sẽ thực hiện tiếp các lệnh sau đó. Còn nếu có return thì các lệnh sau sẽ không được thực hiện.

Bạn thử chạy code này xem kết quả nhé.

#include <stdio.h>
int tinhtong(int N,int sum=0,int i=0){
    if(i>N)
        return sum;
    tinhtong(N,sum+i,i+1);
    printf("%d\t",i);
}

int main(){
    int N=12;
    printf("Tong can tim bang: %d.\n",tinhtong(N));
    return 0;
}
... viết 18:27 ngày 30/09/2018

Đệ quy là một kĩ thuật tương tự vòng lặp nhưng có lưu cấu hình ở từng thời điểm tự gọi hàm và có quay lui ở thời điểm return.

Thai Hoc Nguyen viết 18:36 ngày 30/09/2018

Cho mình hỏi tại sao đến khúc

tinhtong(N,sum+i,i+1);
printf("%d\t",i);

tinhtong(…); mà nó lại có thể thực hiện được dòng tiếp theo của nó là dòng printf . mặc dù nó phải chạy lại hàm đó ?? mà mình cũng chưa hiểu lắm về đoạn code trên nếu ta không có ’ return ’ tại hàm ’ kết quả của nó lại là ‘2’ ?

tinhtong(N,sum+i,i+1);

Mọi người có thể giúp mình giải thích nó được chứ .
Cảm ơn mọi người

*grab popcorn* viết 18:26 ngày 30/09/2018

Bổ sung thêm là hàm đệ quy trên khá phức tạp vì phải tính kq bài toán qua biến phụ là sum và i và nó khá giống 1 vòng for :c
Có 1 cách đệ quy tương tự nhưg đơn giản hơn ^^ Bạn xem tham khảo và tập debug nhé ^^

int A(int n) {
 if(n==1) return n;
 else return n+A(n-1);
}
int main() { printf("%d",A(5)); return 0; }
Thai Hoc Nguyen viết 18:35 ngày 30/09/2018

ý mình là tại sao sau cái hàm

tinhtong(N,sum+i,i+1);

nó lại chạy được cái printf ý @@

*grab popcorn* viết 18:35 ngày 30/09/2018

Sr bạn ~~
đọc ko kỹ rồi chém lung tung ~~
function trong C có thể coi là 1 biến đặc biệt ~~
Như ở Pascal sẽ thể hiện rõ điều này. Có thể gán function = 1 giá trị bất kì nào ở chương trình function ở Pascal.
C thì ko có gán trực tiếp đc, nó chỉ được gán gián tiếp qua hàm return.
Và ở post mình xóa đi có nói sai 1 chút rằng nếu ko return nó sẽ ko thực hiện đc. Đúng là sẽ in ra kq sai, nếu hàm đó ko lấy được giá trị nào từ hàm khác. ^^

Thai Hoc Nguyen viết 18:27 ngày 30/09/2018

Không có gì đâu bạn bạn onl giờ này trả lời cho mình là hay lắm rồi

Thai Hoc Nguyen viết 18:34 ngày 30/09/2018

mình cứ tưởng khi nó gọi hàm

tinhtong(N,sum+i,i+1);

là nó sẽ bỏ qua luôn printf chứ nhỉ @@ ai zè

Sáng Béo viết 18:30 ngày 30/09/2018

theo mình nghĩ là nó return sum xong lại quay ngược lại làm các lệnh tiếp theo. kiểu thoát khỏi vòng lặp ấy.

Tuấn Nguyễn viết 18:36 ngày 30/09/2018

Đây là đệ quy đuôi. Tốc độ của nó nhanh hơn nhiều với đệ quy tuyến tính . Trường hợp này hàm trả về kiểu int nhưng bạn đệ quy ko thực hiện return thì nó sẽ ko gọi lại chính nó. Kết quả là sai chư ko đúng. Đã test trên visual kết quả ra 2. Bạn kiểm tra xem có nhầm lẫn với void tinhtong(int N, int sum = 0, int i = 0) ko? vì hàm void ta gọi lại hàm thì ko có return như trên . !

... viết 18:26 ngày 30/09/2018

Mình vẫn hay lấy ví dụ này để giải thích đệ quy cho người khác:

#include <iostream>
using namespace std;

void recursion(int i)   {
    if(i == 10)
        return;

    cout << i << " ";

    recursion(i+1);

    cout << i << " ";
}

int main()  {
    recursion(1);
    return 0;
}
Bài liên quan
0