递归打印星形图案

时间:2015-04-09 16:41:30

标签: c++ recursion printing

对于我的c ++数据结构类,我们的任务是打印这样的星星模式

*
* *
* * *
* * * *
* * * *
* * *
* *
*

使用用户输入确定的模式中的行数。因此,如果用户输入4,将打印上面的模式。

我们有一个先前的任务,我们必须打印相反的模式,一个像这样

* * * * *
* * * *
* * *
* *
*
*
* *
* * *
* * * *
* * * * *

如果用户输入5,则会打印上面的模式。这个模式,上面的那个,我没有问题。我使用for循环打印上半部分,然后再次递归调用函数,然后使用相同的for循环打印相反方向的下半部分。作为参考,这里是我用于上述模式的代码:

int main()
{
    int number;                                             
    cout << "Enter the number of lines in the grid: ";      

    cin >> number;                                          
    printStars(number);                                     
    cout << endl << "Grid Pattern Complete - End of Program.";
    return 0;
} // end of main 

void printStars(int num)                        
{
    if (num < 0) cout << endl << "Please enter a non negative number." << endl;

        else{

            if (num == 0) return;               

            else{
            for (int q = 1; q <= num; q++)      
            {cout << "*";}
            cout << endl;

            printStars(num - 1);        

            for (int q = 1; q <= num; q++)      
            {cout << "*";} 

            cout << endl;
        } 
    } 
} // end printStars

这个功能就像我想要的那样,所以我想我会用它作为参考来完成第二个任务。我遇到的问题是,虽然很容易完成第一个任务(打印4行的行,然后是3行,然后是2行,然后是1行,那么所有再次以相反的顺序),我似乎无法弄清楚如何格式化for循环来打印模式,从1星的行开始,然后是2行,然后是3行,依此类推,直到它被递归调用并以相反的顺序再次打印。

作为参考,这是我第二次作业的代码(到目前为止):

int main()
{
    int number;                                             
    cout << "Enter the number of lines in the grid: ";      
    cin >> number;
    printStars(number, 0);                                 

    cout << endl << "Grid Pattern Complete - End of Program.";

    return 0;
}

void printStars(int num, int num2)
{
  if (num2 <= num)
  {

      for (int e = num; e > num2; e--)
      {
          cout << "*";
      }

      cout << endl;

      printStars(num - 1, num2);

  }
}

唯一印刷的是模式的后半部分;

(如果用户输入5)

* * * * *
* * * *
* * *
* *
*

即使为了完成这项工作,我也必须在最后递归调用该函数,这是乱序的。

我想我只是对这种递归应该如何工作感到困惑,但是我已经玩了好几个小时,我似乎无法重新格式化或重新排列它或重组它,使其打印像我需要它。有人可以给我一些指导吗?只是写一些伪代码来帮助我。这是为了学校,所以我需要能够理解它,但我现在真的迷失了。

7 个答案:

答案 0 :(得分:1)

试试这个。它是代码的最低限度修改版本。上限传递给所有递归,递归函数调用使用以1开头的值(第一行中只有1个开始)执行:

void printStars(int num, int limit)                         
{
        if (num >limit) return;              
        else{
        for (int q = 1; q <= num; q++)      
        {cout << "*";}
        cout << endl;

        printStars(num +1, limit);        

        for (int q = 1; q <= num; q++)      
        {cout << "*";} 

        cout << endl;
    } 

}

int main()
{        
    int number=5;  
    cin>>number;                                
    printStars(1, number);                                     

    return 0;
} // end of main 

我测试了它,结果是正确的。链接是:

http://ideone.com/ez6pZ5

完美结果:

Success time: 0 memory: 3144 signal:0

*
**
***
****
*****
*****
****
***
**
*

答案 1 :(得分:0)

我建议使用两个递归函数,一个按递增顺序打印,另一个按递减顺序打印。

使两个功能正常工作后,保存该程序的副本。

然后,您可以尝试创建一个函数来执行恒星的递增和递减顺序。

答案 2 :(得分:0)

你的递归电话后你没有打印出星星:

void printStars(int num, int num2)
{
  if (num2 < num)
  {

      for (int e = num; e > num2; e--)
      {
          cout << "*";
      }

      cout << endl;

      printStars(num - 1, num2);

      for (int e = num; e > num2; e--)
      {
          cout << "*";
      }

        cout << endl;
  }
}

注意if条件也必须略有改变。我也同意托马斯的看法,以不同的方式构建你的递归可能更有意义:

void printStars(int num)
{
    for (int i = 1; i <= num; i++)
    {
        cout << "*";
    }

    cout << endl;
}

void printStarsRecursive(int stars)
{
    if (stars == 0)
        return;

    printStars(stars);
    printStarsRecursive(stars-1);
    printStars(stars);
}

int main()
{
    int number;                                             
    cout << "Enter the number of lines in the grid: ";      
    cin >> number;
    printStarsRecursive(number);                                 

    cout << endl << "Grid Pattern Complete - End of Program.";

    return 0;
}

答案 3 :(得分:0)

如果您想以递归方式执行此操作,则必须记住有多种状态:您计算到N的状态,以及您计算的状态回到1。因此,如果你必须递归地进行,你需要跟踪那些额外的东西:

void printStarsImpl(int count, int initial, int sign)
                    ↑          ↑            ↑
                    current    termination  next step

此功能只需知道要调用的下一个printStarsImpl()函数 - 我们是否只需使用count + sign调用,是否将sign翻转为-1,或者我们是否什么都不做......当然是打印count *后的所有内容。

然后是初始调用:

void printStars(int n) {
    printStarsImpl(1, n, +1);
}

答案 4 :(得分:0)

如果要使用声明为只有一个参数的函数,直接的方法如下,在函数中使用静态局部变量

#include <iostream>

void print_stars( size_t n )
{
    static size_t m;

    if ( m++ != n )
    {
        for ( size_t i = 0; i < m; i++ ) std::cout << '*';
        std::cout << std::endl;
        print_stars( n );
    }

    --m;
    for ( size_t i = 0; i < m; i++ ) std::cout << '*';
    std::cout << std::endl;
}

int main() 
{
    while ( true )
    {
        std::cout << "Enter a non-negative number (0-exit): ";

        size_t n = 0;
        std::cin >> n;

        if ( !n ) break;

        std::cout << std::endl;
        print_stars( n );
        std::cout << std::endl;
    }

    return 0;
}

程序输出看起来像

Enter a non-negative number (0-exit): 4

*
**
***
****
****
***
**
*


Enter a non-negative number (0-exit): 3

*
**
***
***
**
*


Enter a non-negative number (0-exit): 2

*
**
**
*


Enter a non-negative number (0-exit): 1

*
*


Enter a non-negative number (0-exit): 0

如果您不想在递归函数中使用静态变量,那么您可以使用标准流成员函数width来应用技巧。在这种情况下,递归函数将按以下方式显示

#include <iostream>
#include <iomanip>

void print_stars( size_t n )
{
    std::streamsize m = std::cout.width();

    if ( m++ != n )
    {
        std::cout.width( m );
        std::cout << std::setfill( '*' );
        std::cout << '*' << std::endl;
        std::cout.width( m );
        print_stars( n );
    }

    std::cout.width( m-- );
    std::cout << std::setfill( '*' );
    std::cout << '\n';
}

int main() 
{
    while ( true )
    {
        std::cout << "Enter a non-negative number (0-exit): ";

        size_t n = 0;
        std::cin >> n;

        if ( !n ) break;

        std::cout << std::endl;
        print_stars( n );
        std::cout << std::endl;
    }

    return 0;
}

输出与上面相同。

P.S。似乎唯一能够编写该功能的程序员就是我失业了。:)所有其他人都无法为初学者做这个任务。:)

答案 5 :(得分:0)

为了练习 - 如何使用递归函数打印星星,另一个函数来确定星星的数量:

string ReturnStars(int number)
{
  if (number > 1)
    return "*" + ReturnStars(number -1);

  return "*";
}

void PrintStars(int start, int lines)
{
  cout << ReturnStars(start) << endl;

  if (start < lines)
    PrintStars(start + 1, lines);

  cout << ReturnStars(start) << endl;
}

int main()
{
  int numberLines = 1;
  cout << "Please enter a positive number to print a star pattern for: ";
  cin >> numberLines;
  PrintStars(1, numberLines);

  return 0;
}

输出示例: enter image description here

答案 6 :(得分:0)

我认为最好的答案应该是仅使用一个递归函数-

#include <iostream>

using namespace std;

void recursive(int current, int lastEnter, int limit, bool isLimitReached) {
    cout << "*";
    if(current == lastEnter ) {
        cout << endl;
        current = 0;
        if(isLimitReached == false) 
            lastEnter++;
        else lastEnter--;
    }
    if(current + 1 == limit) {
        isLimitReached = true;
    }
    current++;
    if(!(isLimitReached == true && lastEnter == 0))
        recursive(current, lastEnter, limit, isLimitReached);
}

int main()
{
    int num = 0;
    cout << "Enter max number of stars to be generated : ";
    cin >> num;
    recursive(1, 1, num, false);
    return 0;
}

上面的代码仅使用一种递归函数,而没有for / while循环。 输出-

Enter max number of stars to be generated : 6 
*  
**       
***    
****    
*****   
******  
*****     
****    
***    
**   
*