我被困在这段代码中:
问题:孩子可以一次跳过1,2或3步的n阶梯。给定n的值,打印他爬楼梯的顺序的所有排列。
这是我的代码:
public class HoppingLad
{
int count;
void hop(int n,int present)
{
if(n==present)
{
count++;
System.out.println("\nFinished type "+count+" climbing.\n");
}
else
{
if((n-present)>=1)
{
System.out.print("\nClimbed 1 step.\nReached "+(present+1)+" ");
hop(n,present+1);
}
if((n-present)>=2)
{
System.out.print("\nClimbed 2 step. \nReached "+(present+2)+" ");
hop(n,present+2);
}
if((n-present)>=3)
{
System.out.print("\nClimbed 3 step. \nReached "+(present+3)+" ");
hop(n,present+3);
}
}
}
public static void main(String [] args)
{
HoppingLad hl=new HoppingLad();
hl.hop(3, 0);
System.out.println("There are "+hl.count+" ways to climb.");
}
}
输出结果为:
Climbed 1 step.
Reached 1
Climbed 1 step.
Reached 2
Climbed 1 step.
Reached 3
Finished type 1 climbing.
Climbed 2 step.
Reached 3
Finished type 2 climbing.
Climbed 2 step.
Reached 2
Climbed 1 step.
Reached 3
Finished type 3 climbing.
Climbed 3 step.
Reached 3
Finished type 4 climbing.
There are 4 ways to climb.
我得到的输出部分正确,部分不完整。爬楼梯的方法是正确的,但正如您所注意到的那样,
爬2 达到3
输出的一部分来自没有
部分即将到来。我绘制了递归树,树甚至建议第一部分不在输出中。攀登1 达到1
但是,必须从地面开始指导用户。我尝试过很多东西,但没有用。有人可以帮我解决这个问题吗?
答案 0 :(得分:1)
您正在将解决方案打印为部分结果,因此当您获得基于该部分解决方案的新解决方案时,不会重复这些解决方案。
换句话说,你做(对于n = 3)
--> state 0
hop(1) --> state 1 --> print "1"
hop(1) --> state 2 --> print "1"
hop(1) --> state 3 --> print "1" --> print "solution";
然后你回到状态2(没有进一步的解决方案)并回到状态1,然后你
hop(2) --> state 3 --> print "2" --> print "solution"
不打印允许你进入状态1的“1”
解决方案是通过实现状态所需的步骤列表,并在达到解决方案时打印所有列表。当然,由于您将使用数组或列表,因此当您返回到先前的状态时,您将需要删除这些步骤。
更新:替代方案(基于更改输出)可以根据所需步骤的数量将答案制成表格。即,输出将是类似的(对于与上面相同的解决方案):
Climbed 1
-> Climbed 1
-> Climbed 1. Solution Found!
-> Climbed 2. Solution Found!
这将允许用户自己重建路径。然后,您需要一个新参数来了解当前的步数。
如果你想要数组/列表版本但不想删除项目,你可以克隆列表并将副本传递给下一个函数调用,但这样效率很低。
答案 1 :(得分:1)
我已经实施了这个解决方案。只有在你完成作业后我才会给你发电子邮件。
您可以做的是保持String
并继续协调当前所采取的步骤,并在达到条件时打印整个String
,不要打印单个步骤。这样,您将减少在每个递归步骤检查您与解决方案的距离。只有当前步骤导致解决方案时,您才能确保打印路径。
例如(假设n = 3)
3,0,"" -> 3,1,"1" -> 3,2,"11" -> 3,3,"111"
(一个解决方案,打印" 111")
在这些问题(通常)中,您需要执行一系列步骤来达到阈值,最有效的解决方案(通常)是存储步骤列表,然后打印整个解决方案而不是打印个别步骤。你知道你可以确定你得到了所有解决方案,并且当前步骤没有导致解决方案时你不打印。
答案 2 :(得分:0)
你的问题 - 如果我已经正确地理解了这个问题 - 那么,当你考虑从第0步到第1步攀登的可能性时,你只需打印出“从0爬到1”< em>一次然后显示从步骤1开始的所有可能性。(其中,通常会有很多。)
相反,您需要安排在递归过程中跟踪完整路线,然后当您到达楼梯顶部时,打印出整条路线。
例如,您可以通过为HoppingLad
类提供一个数组来执行此操作,该数组在hop(n,k)
调用开始时描述了该小伙子如何进行步骤k
。然后,在n==present
的情况下,您可以查看该数组,以输出小伙子从0到n
的完整描述。
有几种不同的方法来组织这个,问题看起来比较功课 - 所以我宁愿不填写太多的细节。我希望尽管如此,上述内容仍然有用。
答案 3 :(得分:0)
所以这是我的解决方案,它使用javascript,它使用ES6(对于数组上的传播操作,默认参数,这将在当前版本的Firefox中正常运行,我在Firefox 50中这样做):
function getHopPathsCnt(totalsteps, maxhopability, curstep = 0, taken = [], total={count:0}) {
if (totalsteps === curstep) {
total.count++;
console.log('A possible hop path:', taken.join(' '));
} else {
for (let hopped = 1; hopped <= maxhopability; hopped++) {
if (totalsteps - curstep >= hopped)
getHopPathsCnt(totalsteps, maxhopability, curstep + hopped, [...taken, hopped], total);
}
}
if (curstep === 0) {
console.error('Total ways to climb', totalsteps, 'steps with up to', maxhopability, 'hops at a time:', total.count);
return total.count;
}
}
使用它:
getHopPathsCnt(3, 3);
输出:
可能的跳跃路径:1 1 1
可能的跳跃路径:1 2
可能的跳跃路径:2 1
可能的跳跃路径:3
一次攀爬3步的总方式,最多3次跳跃:4
4
这个问题确实看起来像家庭作业,因此我想分享它。家庭作业旨在开辟新的视野。所以有时候,当我没有解决方案的时候,我会用我当前的技能/心态来强迫它,这可能永远不会让我到处都是。最终,当我看到解决方案并反向工作时,它只是为我的技能/心态添加了一个新的方面&#34;。这就是为什么我不喜欢看到解决方案说'#34;我不会填写太多的细节,因为它似乎是家庭作业&#34;。因为这导致唯一的学习方法 - 让问题变得错误,然后我们愚蠢的评分系统给我们一个不好的成绩,然后&#34;从我们的错误中学习&#34;。如果可以避免,我讨厌从错误中吸取教训。我也不愿被归类为&#34; Wrong&#34; /&#34; F&#34;作为一个年级,特别是如果我付出努力。我们并不总是从错误和错误中吸取教训,尤其是当你被我们的评分系统作为一个&#34;失败&#34; /&#34;错误&#34;