我正在阅读我的教科书,而我无法真正理解这是如何以递归的方式生成字符串的排列
class PermutationIterator
{
private String wrd;
private int current;
private PermutationIterator Iter;
private String tl;
// Constructor
public PermutationIterator(String s)
{
wrd = s;
current = 0;
if (wrd.length() > 0)
Iter = new PermutationIterator(wrd.substring(1));
}
public String nextPermutation()
{
if(wrd.length() == 0)
{
current++;
return "";
}
char c = wrd.charAt(current);
String nextPermut = Iter.nextPermutation();
if(!Iter.hasMorePermutations())
{
System.out.println("Current value is " + current + " word length is " + wrd.length());
current++;
if (current >= wrd.length()) {
Iter = null;
}
else
{
if (current + 1 >= wrd.length())
tl = wrd.substring(0,current);
else
//System.out.println("Reached");
tl = wrd.substring(0,current) + wrd.substring(current + 1, wrd.length());
Iter = new PermutationIterator(tl);
}
}
return c + nextPermut;
}
public boolean hasMorePermutations()
{
System.out.println("Inside this method we have current= " + current + " with wrdlength " + wrd.length() +"with the word " + wrd);
return current < wrd.length();
}
}
由
调用public static void main(String [] args)
{
PermutationIterator iter = new PermutationIterator("eat");
while(iter.hasMorePermutations())
{
System.out.println(iter.nextPermutation());
}
}
对于eat
,这将输出
eat
eta
aet
ate
tea
tae
我的尝试
在尝试理解所有内容之前,过去三天我一直在努力弄清楚到达!Iter.hasMorePermutations()
的确切程度。这可能是假的唯一方法是return current < wrd.length();
不成立。即wrd.length() <= current
。
现在这里真的开始失去我。我尝试在!Iter.hasMorePermutations()
分支内打印出word.length和current的值,只是为了看看发生了什么。
Current value is 0 word length is 1
Current value is 0 word length is 2
eat
等等..这怎么可能?不是我们达到这个分支的条件,当前值大于我们的字长吗?我们是如何到达这个分支的?
感谢您阅读本文!
答案 0 :(得分:1)
对于每个字长,一次有4个迭代器处于活动状态。它们都有自己的current
值,对hasMorePermutations
的调用是检查下一个迭代器上current
和length
的值,而不是自身。所以你可能想输出:
System.out.println("Current value is " + Iter.current + " word length is " + Iter.wrd.length());
首先,他们所有的当前值都是0,所以我们必须“吃”:
(word = 'eat', current = 0, length = 3)
(word = 'at', current = 0, length = 2)
(word = 't', current = 0, length = 1)
(word = '', current = 0, length = 0)
每个迭代器在下一个迭代器上调用nextPermutation
,直到我们到达最后一个迭代器,其current
值递增,因为wrd.length() == 0
。所以我们得到:
(word = 'eat', current = 0, length = 3)
(word = 'at', current = 0, length = 2)
(word = 't', current = 0, length = 1)
(word = '', current = 1, length = 0)
这是在第三个迭代器Iter.hasMorePermutations()
中检测到的,然后它将递增自己的current
值并重置最后一个迭代器:
(word = 'eat', current = 0, length = 3)
(word = 'at', current = 0, length = 2)
(word = 't', current = 1, length = 1)
(word = '', current = 0, length = 0)
第二个迭代器也会类似地检测到它,它会重置最后两个迭代器:
(word = 'eat', current = 0, length = 3)
(word = 'at', current = 1, length = 2)
(word = 'a', current = 0, length = 1)
(word = '', current = 0, length = 0)
第一个迭代器对Iter.hasMorePermutations()
的调用将返回false,因此它不会递增其当前值,从而提供下一个字符串&#39;。
答案 1 :(得分:0)
您要打印的内容是wrd
对象的current
和this
的值,而不是评估Iter
的对象!Iter.hasMorePermutations()
的值。< / p>
要了解发生了什么,您应该打印Iter.wrd.length()
和Iter.current
。
答案 2 :(得分:0)
我猜你所缺少的是测试不是this.hasMorePermutations()
,而是Iter.hasMorePermutations()
,可能会被Iter
看起来像一个类名而不是一个字段名称......
所以,在你的第3点返回之前,它有字长0和当前1,也就是说,不再有迭代,当它返回到父节点时它就是被测试的对象,所以你输入if语句。
答案 3 :(得分:0)
它属于这个if分支
if(wrd.length() == 0)
{
current++;
return "";
}
执行此分支后,现在wrd.length()
为0且current
为1,
因此,在nextPermutation
点击此if分支后,下一次立即调用hasMorePermutations
将返回false
答案 4 :(得分:-1)
什么这么复杂?我阅读代码并翻译成英文的方式是:
for(current=0 to string_len)
在current
从字符串中提取出来(创建一个缺少该字母的字符串)。 (这将减少一个长度;我在这里陈述明显的吗?)
递归地生成在prev步骤中构造的字符串的排列(称之为tl
),注意将提取的字母添加为每个字母的第一个字母。在缩短的tl
字符串
当current
到达string_len
时,没有更多的字母要提取,这意味着你已经完成了。
这是一个海龟一直向下的情况&#34; - 一个3个字母的迭代器将使用一个2个字母的迭代器,它将使用一个单字符迭代器,它将使用一个空字符串迭代器。
在每个级别,迭代器将提取current
个字母,创建一个level-1
迭代器,然后将其压缩干净&#39;当它没有任何东西可以提供时丢弃它。一旦current
达到最大值,此迭代器将向level+1
报告&#34;我干涸&#34;并被解雇。
-
"Rubber duck debugging"了解如何达到!Iter.hasMorePermutations()
:
空字符串
current == len
,因此:
见
if(wrd.length() == 0)
{
current++;
return "";
}
带有1个字母的字 - 使其成为&#34; t&#34;
tl
=&#34;&#34; 使用空字符串置换迭代器生成tl
(空字符串)的第一个排列(参见上文)
String nextPermut = Iter.nextPermutation();
只有一种可能,因为它是一个空字符串。当我,单字母迭代器,得到我的子迭代器(空字符串一)&#34;你有更多的排列&#34;答案将出现否定
if(!Iter.hasMorePermutations())
// this is true immediately for my empty-str subiterator
那么,我,单字母迭代器会做什么?
将增加我的current
然后......
因为下次我会被问到,我不能再生成一个,我将解雇我的(零长度)迭代器
if (current >= wrd.length()) {
Iter = null;
}
然后将提取的字母(我唯一的一个)返回到我的(已经被解雇的)迭代器生成的排列之前:从而返回一个&#34; t&#34;前面是一个空字符串。
我,单字母迭代器下次我会问hasMorePermutations
时会回答什么?好吧,false
,因为我将current
增加到字符串的长度(1)
你真的希望我继续吗,或者你是否已经看到使用迭代器的迭代器用于一个不用字母的单词,每个迭代器都有自己的current
和单词&#39; ?