递归计划

时间:2012-07-03 21:39:48

标签: java recursion

我被困在这段代码中:

  

问题:孩子可以一次跳过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

部分即将到来。我绘制了递归树,树甚至建议第一部分不在输出中。

但是,必须从地面开始指导用户。我尝试过很多东西,但没有用。有人可以帮我解决这个问题吗?

4 个答案:

答案 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

原因我提供了完全解决方案,而不像上面的Gareth

这个问题确实看起来像家庭作业,因此我想分享它。家庭作业旨在开辟新的视野。所以有时候,当我没有解决方案的时候,我会用我当前的技能/心态来强迫它,这可能永远不会让我到处都是。最终,当我看到解决方案并反向工作时,它只是为我的技能/心态添加了一个新的方面&#34;。这就是为什么我不喜欢看到解决方案说'#34;我不会填写太多的细节,因为它似乎是家庭作业&#34;。因为这导致唯一的学习方法 - 让问题变得错误,然后我们愚蠢的评分系统给我们一个不好的成绩,然后&#34;从我们的错误中学习&#34;。如果可以避免,我讨厌从错误中吸取教训。我也不愿被归类为&#34; Wrong&#34; /&#34; F&#34;作为一个年级,特别是如果我付出努力。我们并不总是从错误和错误中吸取教训,尤其是当你被我们的评分系统作为一个&#34;失败&#34; /&#34;错误&#34;