tôi đang học đệ quy và dưới đây trở lại là một ví dụ mà tôi đang truy tìm thông qua để hiểu rõ hơn về nóĐệ quy - tại sao sử dụng tuyên bố
public static void main(String []args) {
new TestRecursion().strRecur("abc");
}
public void strRecur(String s) {
if(s.length() < 6) {
System.out.println(s);
strRecur(s+"*");
}
}
Dưới đây là những gì tôi đã hiểu cho đến nay. - Trong cuộc gọi đầu tiên đến strRecur("abc")
, phương thức sẽ được thêm vào chồng thực thi. Nó in "abc" trước khi tạm dừng do một cuộc gọi đệ quy với tham số "abc *".
Cuộc gọi thứ hai với "abc *", phương thức đẩy
strRecur(abc*)
vào ngăn xếp và in "abc *" để điều khiển.Cuộc gọi thứ ba với "abc **", phương thức đẩy
strRecur(abc**)
vào ngăn xếp và in "abc **" để điều khiển.Cuộc gọi thứ tư với "abc ***", phương thức đẩy
strRecur(abc***)
vào ngăn xếp. Vì điều kiện cơ bản được đáp ứng, phương thức hoàn thành (không in bất kỳ thứ gì) và bật ra khỏi ngăn xếp.Cuộc gọi thứ ba có "abc **" đã hoàn tất và xuất hiện. Vì không có mã đang chờ xử lý nên không có gì xảy ra.
Cuộc gọi thứ hai với "abc *" đã hoàn tất và xuất hiện. Vì không có mã đang chờ xử lý nên không có gì xảy ra.
Cuộc gọi đầu tiên với "abc" đã hoàn tất và xuất hiện. Vì không có mã đang chờ xử lý nên không có gì xảy ra.
Prints sau vào giao diện điều khiển -
abc
abc*
abc**
Tôi nghĩ rằng tôi hiểu những gì đang xảy ra ở đây. Bây giờ, tôi muốn thử một biến thể nhỏ của mã này. Thay vì gọi strRecur(s+"*")
, tôi muốn làm return strRecur(s+"*")
public class TestRecursion {
public static void main(String []args) {
new TestRecursion().strRecur("abc");
}
public String strRecur(String s) {
if(s.length() < 6) {
System.out.println(s);
return strRecur(s+"*");
}
return "Outside If";
}
}
kỳ vọng của tôi là, một khi strRecur(abc***)
bật ra, đó là đầu ra (abc ***) sẽ được trả lại cho strRecur()
tiếp theo trên stack, vì vậy tôi sẽ xem abc **** được in trong bảng điều khiển. Tương tự cho các cuộc gọi đệ quy khác.
Tuy nhiên, đầu ra trong trường hợp này hoàn toàn giống như khi không có câu lệnh trả về. hiểu biết của tôi (trong đó tất nhiên là không đúng) bắt nguồn từ việc thực hiện thừa đệ quy, nơi chúng tôi làm điều gì đó như
return n * fact(n-1);
đây fact(n-1)
được giải quyết với giá trị trả về của n
, một khi phương pháp trước đó trên stack hoàn tất. Tại sao không trở lại hành xử theo cùng một cách trong ví dụ này?
[Ví dụ khả thi] (https://ideone.com/GTCArI) trong trường hợp ai đó muốn fiddle. – Michael
Chỉ cần một lời khuyên nhanh chóng: Tôi thấy rằng khi cố gắng hiểu đệ quy nó sẽ giúp nếu bạn in ra các chi tiết của mọi cuộc gọi. Ví dụ bắt đầu phương thức đệ quy của bạn với một cái gì đó như 'System.err.println ("> strRecur s = "+ s);' và trước khi trở về, bạn làm 'System.err.println ("
biziclop