问题描述
所以,我的问题是编写一个 C++ 程序来使用递归打印给定字符串的所有子字符串。这是在一个免费的youtube课程中,老师只是在没有详细解释的情况下讲述问题和答案。因此,我复制了该代码并执行了它,它正在运行,但我想检查堆栈是如何管理的,因此我创建了堆栈并发现了一个问题。
您可以在此图中查看问题的详细信息,例如问题陈述、C++ 代码、输出、解释、堆栈等:https://photos.app.goo.gl/yQuiSFwfVB4GnDGg9
我也在此处附上代码:
#include<iostream>
using namespace std;
void sub( string s,string ans="")
{
if(s.length()==0)
{
cout<<ans<<endl;
return;
}
char ch = s[0];
string ros = s.substr(1); //ros- Rest of the string
sub(ros,ans);
sub(ros,ans+ch);
}
int main()
{
sub("ABC","");
return 0;
}
C
B
BC
A
交流
AB
ABC
编辑:很难用语言来说明问题,但我会尝试。堆栈不断调用该函数,直到它达到基本条件并返回。因此,根据代码,每个函数调用都会调用该函数两次,并且这种情况会一直发生,直到达到基本条件。因此,它看起来类似于二叉树(如图所示)。现在,问题是编译器没有执行该树的最后 2 个节点。
让我试着详细说明一下。我将尝试说明函数如何执行和创建堆栈,但我将主要关注第二个调用 sub(ros,ans+ch) 并忽略第一个调用 sub(ros,ans) 因为问题是没有执行 sub(ros,ans+ch) 的倒数第二个调用。
因此,主函数将调用 sub("ABC","") ,后者将调用 2 个函数 sub("BC","") 和 sub("BC","A")。让我们忽略 sub("BC","").
sub("BC","A") 将调用两个函数,即 sub("C","A") 和 sub("BC","AB")。让我们再次忽略第一个调用。
sub("BC","AB") 将调用 sub("C","AB") 和 sub("C","ABB")。再次忽略第一个调用意味着:
sub("C","ABB") 将调用 sub("","ABB") 和 sub("","ABBC")。
这 2 个调用将达到基本情况,应该在程序结束时打印 ABB 和 ABBC,但它没有发生。
根据堆栈,输出是正确的,但它应该有另外 2 行包含字符串 ABB 和 ABBC 的输出,但没有发生。自过去 24 小时以来,我已多次检查堆栈执行,但没有发现任何问题。感谢任何帮助,谢谢。
解决方法
您可以检测函数以更清楚地看到发生了什么:
#include<iostream>
using namespace std;
void sub( string s,string ans="",int stack_counter =0)
{
std::cout << "\n";
std::cout << stack_counter << " inp " << s << " " << ans << "\n";
if(s.length()==0)
{
cout<<ans<<endl;
return;
}
char ch = s[0];
string ros = s.substr(1); //ros- Rest of the string
std::cout << stack_counter << " call sub(" << ros << "," << ans << ")";
std::cout << " and sub(" << ros << "," << (ans+ch) << ")\n";
sub(ros,ans,stack_counter+1);
sub(ros,ans+ch,stack_counter+1);
}
int main()
{
sub("ABC","");
return 0;
}
输出为:
0 inp ABC
0 call sub(BC,) and sub(BC,A)
1 inp BC
1 call sub(C,) and sub(C,B)
2 inp C
2 call sub(,) and sub(,C)
3 inp
3 inp C
C
2 inp C B
2 call sub(,B) and sub(,BC)
3 inp B
B
3 inp BC
BC
1 inp BC A
1 call sub(C,A) and sub(C,AB)
2 inp C A
2 call sub(,A) and sub(,AC)
3 inp A
A
3 inp AC
AC
2 inp C AB
2 call sub(,AB) and sub(,ABC)
3 inp AB
AB
3 inp ABC
ABC
sub("ABC","") 将调用 2 个函数 sub("BC","") 和 sub("BC","A")。让我们忽略 sub("BC","").
正确。
0 inp ABC
0 call sub(BC,A)
sub("BC","A") 将调用两个函数,即 sub("C","A") 和 sub("BC","AB")。
错了。
1 inp BC A
1 call sub(C,AB)
sub("BC","A")
调用 sub("C","A")
和 sub("C","AB")
。