我正在为Java应用程序编写一个函数,该应用程序使用StringBuilder
生成字符串的所有排列。
每当运行该函数时,程序立即终止,并且DDMS(Dalvic虚拟机调试工具)在我的函数中声明堆栈溢出。
private void reorder(String reorder_this, StringBuilder in_this){
for(int i = 0; i < reorder_this.length(); i++)
{
if(i == reorder_this.length())
{
in_this.append(System.getProperty("line.separator"));
}
else
{
in_this.append(reorder_this.charAt(i));
reorder(reorder_this.substring(0, i) + reorder_this.substring(i), in_this);
}
}
}
你可以看到我已经对这个问题采取了递归方法,我相信最终会填充字符串生成器,其中包含输入字符串的所有可能排列,每个排列后跟换行字符。
有没有人知道可能导致堆栈溢出的原因?
答案 0 :(得分:5)
简而言之,除非字符串的长度为0,否则您的函数无法终止。
您的方法首先将i
设置为0并测试i
是否小于第一个参数的长度。如果是(除了空字符串之外的所有情况),你立即递归,因为你不能严格地小于长度和等于长度。在递归调用中,传入一个完全相同长度的字符串(实际上,与Thilo指出的完全相同的字符串)。这表明该算法的第二个问题:递归算法应该对每个递归调用的“较小”参数进行操作。
在这里获得StackOverflowException
不会花费很长时间。每个递归调用都会推送一个新的堆栈帧。
答案 1 :(得分:2)
Java中任何堆栈溢出的原因都是无限递归。
private void reorder(String reorder_this, StringBuilder in_this){
for(int i = 0; i < reorder_this.length(); i++)
{
if(i == reorder_this.length())
{
通过构造无法访问此块。所以你的终止条件永远不会得到满足。
答案 2 :(得分:0)
我认为问题在于这一行:
reorder(reorder_this.substring(0, i) + reorder_this.substring(i), in_this);
reorder_this.substring(0, i) + reorder_this.substring(i)
将生成相当于reorder-this