Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么我的递归函数先按降序打印,然后按升序打印?_C++ - Fatal编程技术网

C++ 为什么我的递归函数先按降序打印,然后按升序打印?

C++ 为什么我的递归函数先按降序打印,然后按升序打印?,c++,C++,我有一个简单的递归c++程序,我正试图准确地理解它是如何工作的。我明白为什么程序会打印出3 2 1,但我不明白为什么它会反过来打印1 2 3。我用了一个手模拟,一步一步地浏览了程序,但仍然不明白13是如何产生的。我在Geeksforgeks上找到了这篇文章,但仍然很难理解这个概念。任何解释都会很棒 #include <iostream> using namespace std; void test(int n) { if (n > 0) { cout <

我有一个简单的递归
c++
程序,我正试图准确地理解它是如何工作的。我明白为什么程序会打印出
3 2 1
,但我不明白为什么它会反过来打印
1 2 3
。我用了一个手模拟,一步一步地浏览了程序,但仍然不明白
13
是如何产生的。我在Geeksforgeks上找到了这篇文章,但仍然很难理解这个概念。任何解释都会很棒

#include <iostream>

using namespace std;

void test(int n)
{
  if (n > 0)
  {
    cout << n << " ";
    test(n - 1);
    cout << n << " ";
  }
}

int main()
{
  test(3);
  return 0;
} 
#包括
使用名称空间std;
无效测试(int n)
{
如果(n>0)
{

cout递归中函数调用的顺序如下所示:

test(3)
-- cout << 3 << " ";
-- test(2)
-- -- cout << 2 << " ";
-- -- test(1)
-- -- -- cout << 1 << " ";
-- -- -- test(0)
-- -- -- cout << 1 << " ";
-- -- cout << 2 << " ";
-- cout << 3 << " ";
测试(3)

--cout这是因为在if语句中调用“test”方法后,您就有了cout语句。在它遍历所有方法调用并命中基本情况后,它会从每个方法调用中返回,并按调用方法的相反顺序转到下一行(cout语句)。

将程序更改为

#include <iostream>

using namespace std;

void test(int n)
{
  if (n > 0)
  {
    cout << "enter" << n << " ";  // <- add "enter" here
    test(n - 1);
    cout << "exit" << n << " ";   // <- add "exit" here
  }
}

int main()
{
  test(3);
  return 0;
} 
您可以将递归调用视为具有堆栈的操作。 有两种操作:
push
pop
。 你的程序所做的是

push test 3
push test 2
push test 1
pop test 1
pop test 2
pop test 3
在每次
按下
pop
时,您都会执行
cout
,从而看到输出
3 2 1 2 3


您可以找到有关递归的更多信息。

为了清楚起见,请重写函数

void test( unsigned int n )
{
    if ( n )
    {
        std::cout << n << " ";
        test( n - 1 );
        std::cout << n << " ";
    }
}
对于修改后函数的调用
test(3);
,您将获得以下输出

3 3 2 2 1 1 
因此,函数的每个递归调用两次输出传递的值n。我希望这是清楚的,因为函数显式包含相同的语句两次

std::cout << n << " ";
std::cout << n << " ";

…等等。

问题是所有的答案对你都没有帮助,因为即使有人向你解释了,你也会陷入下一个算法

我提供了一个基本的方法,帮助我理解一些搜索算法、链表、二叉树等等,因为我是一个头脑简单的人

你要做的是找出用你能想到的最有创意的方式来表示数据的方法。因为编程就是用很多方式来翻转数据。我举了几个例子,就是用塑料罐,贴上它或葡萄和盘子,我见过一些印度视频人,他们用图表或圆圈来绘制数据流n如果需要,可以用一张不同颜色的纸 其工作原理如下:

  • 把数据放在post上,每轮一个。你有一个简单的算法,我会写一个“3”,因为它是通过函数传递的
  • jar表示函数调用,我会为每个调用使用一个jar
  • 一点一点地模拟算法。就像在jar上点击3->first cout“3”->test get called“n-1”,这样“2”进入一个新的jar(在post上写2) ->第二个cout“2”->测试名为“n-1”,因此1将再次放入新的jar中 ->第三个cout“1”->test get called“n-1”,所以0进入一个新的jar(在post-it上写入0)-但是等等!0不是比0大!所以jar不会通过if命令!所以测试不会再次被调用-函数结束。 现在看看你的位置!你还有4个罐子,函数中的第二个罐子甚至没有被调用一次-现在是时候了,因为每个罐子代表一个尚未完成且仍然打开的函数调用。你最后放入的罐子里是什么数字?对,a 1!所以“1”到达罐子。把它揉皱,放回罐子。下一个罐子里是什么?a“2”?宾果-通过第二个库特打印。最后一个杯子里有一个3?-对,用库特打印,然后把它弄皱。没有杯子了?没有数据要打印了?完成了! 这就是程序的工作原理! 恭喜你,因为我相信你现在已经掌握了
  • Btw.如果你遇到一个你不知道数据流的地方,每个好的IDE都有一个调试器,它可以让你精确地运行程序的步骤,并且在每一步之后都停止。这说明了如何在亚历克斯ALAN中使用一个“跳转到C++”的调试器。“他有一整章是关于如何读写程序的,也有一整章是关于递归的,我认为仅指针就有6个。他给出了寻找数据表示方法的技巧,我希望这对你和我都有帮助:)


    欢呼声是由第二个
    引起的。我是否可以用手模拟,一步一步地浏览程序,但仍然不明白123是如何产生的。--如果你做到了所有这些,那么也许你的漫游技能有所提高(或者告诉我们)你在哪里迷路了(在你阅读了给出的答案之后)?@PaulMcKenzie我在
    3 2 1
    之后迷路了。然后它如何从另一个方向运行它并打印
    1 2 3
    ?用手仔细检查函数。或者只尝试2个数字而不是3。我知道递归有时很棘手,但是如果你完全按照程序的状态执行并且不偏离(你现在是一台机器,而不是一个人),你应该明白为什么你会得到你看到的输出。@AlexLowe递归使用后进先出堆栈。后进先出意味着最后一次上下文输入保存,第一次上下文输出执行。当你打印:3,2,1?最后一次上下文添加是上下文1(测试(1);)所以它是第一次执行的上下文输出(这就是我们打印3211的原因),在上下文1之前,我们添加了上下文2(测试(2);)在堆栈中,这就是为什么有32112,…。为什么程序不在执行
    3 2 1
    后停止?@AlexLowe,因为您也在递归调用后打印。如果您不想这样做,请删除第二个
    cout
    。@AlexLowe,因为被调用的函数保持打开状态。这就好像您有3个单独的函数被调用,等待卸载一样如果if命令不再有效,测试不会调用自身。当这种情况发生时,第二个cout被调用,仍然打开的测试函数得到clos
    std::cout << n << " ";
    
    test( n - 1 );
    
    3 3 2 2 1 1 
    
    std::cout << n << " ";
    std::cout << n << " ";
    
    3         3
         |
    call itself for 2