99瓶啤酒递归似乎不起作用

好的,这是我在学习过程中编写的简单代码。

void SingTheSong (int NumOfBottles) { if (NumOfBottles == 0){ printf("there are simply no more bottles of beer on the wall. \n"); } else { printf("%d bottles of beer on the wall, %d bottles of beer.\n", NumOfBottles, NumOfBottles); int Bottleless = NumOfBottles - 1; printf("Take one down pass it around, %d bottles of beer on the wall. \n", Bottleless); SingTheSong(Bottleless); printf("Put a bottle in the recycling bin, there are now %d empty bottles in the bin.\n", NumOfBottles); } } int main(int argc, const char * argv[]) { SingTheSong(99); return 0; } 

我唯一不明白的是为什么SingTheSong(Botteless)function在程序运行时从1开始,为什么它在墙上有0瓶啤酒后显示printf()语句。 只是一个混乱,因为我认为大括号内的所有内容都在else语句中被删除,然后再次运行else语句。 为什么不是这样的?

例如:“墙上挂着99瓶啤酒,99瓶啤酒。把一个啤酒倒在墙上,墙上放了98瓶啤酒。把一个瓶放在回收箱里,现在柜子里有一个空瓶子” “墙上放着98瓶啤酒,98瓶啤酒。拿下一瓶啤酒,墙上传来97瓶啤酒。在回收箱里放一个瓶子,箱内现在有2个空瓶子”

我知道他是初学者,我是初学者。 有人可以向我解释这个,所以我不再进入圈子。 谢谢!

想象一下,你知道SingTheSong方法为N打印的是什么。 现在分别交易if语句的两个分支。 当NumOfBottles为零时,打印“无瓶子”消息,然后返回。 当NumOfBottles不为零时,我们执行以下三项操作:

  • 打印瓶数N
  • 打印SingTheSong方法为N-1打印的任何SingTheSong
  • 打印回收消息N

中间行是递归的 :它可以扩展为相同的三行,如下所示:

  • 打印瓶数N
  • 打印瓶数N-1
  • 打印SingTheSong方法为N-2打印的任何SingTheSong
  • 打印回收消息N-1
  • 打印回收消息N

你可以一次又一次地做到这一点,直到中间的线成为“啤酒之外”的消息。

嗯我不明白你在哪里遇到这个问题但是这里有解释:

对于NumOfBottles = 99:

 printf("%d bottles of beer on the wall, %d bottles of beer.\n", NumOfBottles, NumOfBottles); // = 99 bottles of beer on the wall, 99 bottles of beer. int Bottleless = NumOfBottles - 1; // 98 printf("Take one down pass it around, %d bottles of beer on the wall. \n", Bottleless); //98 bottles of beer on the wall. SingTheSong(98) 

对于NumOfBottles = 98:

 printf("%d bottles of beer on the wall, %d bottles of beer.\n", NumOfBottles, NumOfBottles); //= 98 bottles of beer on the wall, 98 bottles of beer int Bottleless = NumOfBottles - 1; // 97 printf("Take one down pass it around, %d bottles of beer on the wall. \n", Bottleless); //97 bottles of beer on the wall SingTheSong(97); 

最后当NumOfBottles = 0时:printf(“墙上根本没有啤酒瓶。\ n”); //墙上不再有啤酒瓶了。 //现在回来了!

现在,这将被打印99次:

 printf("Put a bottle in the recycling bin, there are now %d empty bottles in the bin.\n", NumOfBottles);//starting from 1 upto 99. 

这就是为什么它不是那样的,因为递归函数被称为BEFORE printf("Put a bottle...")

解:

 void SingTheSong (int NumOfBottles) { if (NumOfBottles == 0){ printf("there are simply no more bottles of beer on the wall. \n"); } else { printf("%d bottles of beer on the wall, %d bottles of beer.\n", NumOfBottles, NumOfBottles); int Bottleless = NumOfBottles - 1; printf("Take one down pass it around, %d bottles of beer on the wall. \n", Bottleless); printf("Put a bottle in the recycling bin, there are now %d empty bottles in the bin.\n", 99-Bottleless); SingTheSong(Bottleless); } } 

printf 之前,您正在使用SingTheSongfunctionSingTheSong回收箱中的瓶子数量。

回收站逻辑中还存在一个缺陷 – 您需要将回收站中当前数量的瓶子递归到您的function – 现在的方式,如果您按上述方法修改线路的顺序,它将总是打印比在垃圾箱中的瓶子总数少一个。

这里有一些伪代码来显示这种递归应该是什么样子:

 function singTheSong(bottlesOnWall,bottlesInBin) { if (bottlesOnWall == 0) { print("There are no more bottles.\n"); } else { printf("%d bottles of beer on the wall, %d bottles of beer.\n", bottlesOnWall, bottlesOnWall); bottlesOnWall--; bottlesInBin++; printf("Take one down pass it around, %d bottles of beer on the wall.\n", bottlesOnWall); printf("Put a bottle in the recycling bin, there are now %d empty bottles in the bin.\n", bottlesInBin); singTheSong(bottlesOnWall,bottlesInBin); } } singTheSong(99,0); 

不完整的答案。 只是展示你可能想要补充其他答案的内容。

 void SingTheSong (int bottlesOnWall, int bottlesInBin) { if (bottlesOnWall == 0){ printf("there are simply no more bottles of beer on the wall. \n"); } else { printf("%d bottles of beer on the wall, %d bottles of beer.\n",bottlesOnWall, bottlesOnWall); printf("Take one down pass it around, %d bottles of beer on the wall. \n", --bottlesOnWall); printf("Put a bottle in the recycling bin, there are now %d empty bottles in the bin.\n", ++bottlesInBin); SingTheSong(bottlesOnWall, bottlesInBin); } } 

你最初可以调用这个函数:

 SingTheSong(99, 0); 

此外,您可能想要阅读有关递归的更多信息。

这是一个函数递归,当你以99到1开始SingTheSong(Bottleless)forms时,它将调用函数与Bottleless一起作为99,98,97 …… 1.在SingTheSong(1)之后,然后继续printf

“printf(”将一个瓶子放入回收箱,现在箱子里有空瓶子。\ n“,NumOfBottles);”

然后回到SingTheSong(2),继续,最后回到SingTheSong(99)