递归打印星形图案
Recursively printing a star pattern
对于我的 C++ 数据结构 class 我们的任务是打印这样的星星图案
*
* *
* * *
* * * *
* * * *
* * *
* *
*
模式中的行数由用户输入确定。因此,如果用户输入 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)
* * * * *
* * * *
* * *
* *
*
甚至为了完成这项工作,我必须在最后递归调用该函数,这是乱序的。
我想我只是对这个递归应该如何工作感到困惑,但我已经玩了几个小时,我似乎无法重新格式化它、重新排列它或重组它,以便它打印出来我需要它。有人可以给我一些指导吗?也许只是写一些伪代码来帮助我。这是为学校准备的,所以我需要能够理解它,但我现在真的迷路了。
我建议使用两个递归函数,一个按升序打印,另一个按降序打印。
使这两个功能正常运行后,保存该程序的副本。
然后您可以尝试创建一个函数来执行星星的升序和降序。
您在递归调用后没有打印出星星:
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 条件也必须稍微改变。我也同意 Thomas 的观点,以不同的方式构建递归可能更有意义:
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;
}
如果你想递归地做,你必须记住有多个状态:你数到 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);
}
试试这个。它是您的代码的最小修改版本。上限传递给所有递归,递归函数调用以 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
我测试了一下,结果是正确的。 link 是:
ideone 结果:
Success time: 0 memory: 3144 signal: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。看来能写出功能的程序员只有我失业了。:) 其他人都做不了这个初学者的作业。:)
为了练习 - 打印星星的递归函数和确定星星数量的递归函数如何:
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;
}
输出示例:
我认为最佳答案应该是如果只使用一个递归函数 -
#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
*
**
***
****
*****
******
*****
****
***
**
*
对于我的 C++ 数据结构 class 我们的任务是打印这样的星星图案
*
* *
* * *
* * * *
* * * *
* * *
* *
*
模式中的行数由用户输入确定。因此,如果用户输入 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)
* * * * *
* * * *
* * *
* *
*
甚至为了完成这项工作,我必须在最后递归调用该函数,这是乱序的。
我想我只是对这个递归应该如何工作感到困惑,但我已经玩了几个小时,我似乎无法重新格式化它、重新排列它或重组它,以便它打印出来我需要它。有人可以给我一些指导吗?也许只是写一些伪代码来帮助我。这是为学校准备的,所以我需要能够理解它,但我现在真的迷路了。
我建议使用两个递归函数,一个按升序打印,另一个按降序打印。
使这两个功能正常运行后,保存该程序的副本。
然后您可以尝试创建一个函数来执行星星的升序和降序。
您在递归调用后没有打印出星星:
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 条件也必须稍微改变。我也同意 Thomas 的观点,以不同的方式构建递归可能更有意义:
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;
}
如果你想递归地做,你必须记住有多个状态:你数到 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);
}
试试这个。它是您的代码的最小修改版本。上限传递给所有递归,递归函数调用以 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
我测试了一下,结果是正确的。 link 是:
ideone 结果:
Success time: 0 memory: 3144 signal: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。看来能写出功能的程序员只有我失业了。:) 其他人都做不了这个初学者的作业。:)
为了练习 - 打印星星的递归函数和确定星星数量的递归函数如何:
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;
}
输出示例:
我认为最佳答案应该是如果只使用一个递归函数 -
#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
*
**
***
****
*****
******
*****
****
***
**
*