在C中递归绘制沙漏
Draw hourglass recursively in C
我需要在 C 中递归地绘制沙漏。我需要 1 个辅助函数加上实际函数。以下是函数签名:
void helper(unsigned int height, unsigned int offset)
void real(unsigned int height)
其中height描述的是要绘制的行数,offset是每行开头的空格数。对于每一行,星星的数量应减少 2,偏移量应增加 1,高度应减少 1,直到到达沙漏的中间。之后,高度应继续降低,但星数应增加 2,偏移量应减少 1。如果输入高度为偶数,则第一行应有 height - 1 星。此外,中间应该有两排只有 1 颗星。如果输入的高度是奇数,那么第一行应该有高度星。
Ex) height = 6
*****
***
*
*
***
*****
Ex) height = 5
*****
***
*
***
*****
我必须使用递归,不允许循环。
这是我的辅助函数。我在弄清楚主要功能时遇到了麻烦。
void draw_hourglass_rec_helper(unsigned int height, unsigned int offset)
{
if (height == 0) {
printf("\n");
} else if (offset == 0) {
printf("*");
draw_hourglass_rec_helper(height-1, 0);
} else {
printf(" ");
draw_hourglass_rec_helper(height, offset-1);
}
}
最佳尝试:
void draw_hourglass_rec(unsigned int height)
{
if(height < 1)
{
return;
}
{
draw_hourglass_rec_helper(height, ((-0.5 * height) + (9.0/2.0)));
draw_hourglass_rec(height-2);
}
}
打印:
**********
********
******
****
**
对于 draw_hourglass_rec(10)
夫妻问题
1)我无法打印沙漏的下半部分
2)星星的数量应该总是奇数
3)我不知道如何表达偶数输入情况,其中应该有 2 行,每行 1 星
4) 如果我在奇数高度上使用此代码,我将陷入无限循环。
这是我用 C 语言编码的第一周。我真的很难用这种语言表达我的逻辑。
提前谢谢你。
给你。
#include <stdio.h>
void draw_hourglass_rec_helper( unsigned int n, int offset )
{
const char c = '*';
if ( n )
{
printf( "%*c", offset + 1, c );
unsigned int k = n % 2 == 0 ? n - 1 : n;
for ( unsigned int i = 0; i < k - 1; i++ ) putchar( c );
putchar( '\n' );
if ( ! ( n < 2 ) ) draw_hourglass_rec_helper( n - 2, offset + 1 );
if ( n != 1 )
{
printf( "%*c", offset + 1, c );
for ( unsigned int i = 0; i < k - 1; i++ ) putchar( c );
putchar( '\n' );
}
}
}
void draw_hourglass_rec( unsigned int n )
{
if ( n )
{
draw_hourglass_rec_helper( n, 0 );
}
}
int main(void)
{
while ( 1 )
{
printf( "Enter a non-negative number (0 - exit): " );
unsigned int n;
if ( scanf( "%u", &n ) != 1 || n == 0 ) break;
putchar( '\n' );
draw_hourglass_rec( n );
putchar( '\n' );
}
return 0;
}
程序输出可能看起来像
Enter a non-negative number (0 - exit): 10
*********
*******
*****
***
*
*
***
*****
*******
*********
Enter a non-negative number (0 - exit): 9
*********
*******
*****
***
*
***
*****
*******
*********
Enter a non-negative number (0 - exit): 8
*******
*****
***
*
*
***
*****
*******
Enter a non-negative number (0 - exit): 7
*******
*****
***
*
***
*****
*******
Enter a non-negative number (0 - exit): 6
*****
***
*
*
***
*****
Enter a non-negative number (0 - exit): 5
*****
***
*
***
*****
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
如果辅助函数的第二个参数是unsigned int类型,那么你可以使用循环来输出初始空格,例如
void draw_hourglass_rec_helper( unsigned int n, unsigned int offset )
{
const char c = '*';
if ( n )
{
for ( unsigned int i = 0; i < offset; i++ ) putchar( ' ' );
unsigned int k = n % 2 == 0 ? n - 1 : n;
for ( unsigned int i = 0; i < k; i++ ) putchar( c );
putchar( '\n' );
if ( ! ( n < 2 ) ) draw_hourglass_rec_helper( n - 2, offset + 1 );
if ( n != 1 )
{
for ( unsigned int i = 0; i < offset; i++ ) putchar( ' ' );
for ( unsigned int i = 0; i < k; i++ ) putchar( c );
putchar( '\n' );
}
}
}
另一种方法是使用静态变量作为输出偏移量,而不是使用辅助函数。
#include <stdio.h>
void draw_hourglass_rec( unsigned int n )
{
static int offset = 0;
const char c = '*';
if ( n )
{
++offset;
printf( "%*c", offset, c );
unsigned int k = n % 2 == 0 ? n - 1 : n;
for ( unsigned int i = 0; i < k - 1; i++ ) putchar( c );
putchar( '\n' );
if ( ! ( n < 2 ) ) draw_hourglass_rec( n - 2 );
if ( n != 1 )
{
printf( "%*c", offset, c );
for ( unsigned int i = 0; i < k - 1; i++ ) putchar( c );
putchar( '\n' );
}
--offset;
}
}
int main(void)
{
while ( 1 )
{
printf( "Enter a non-negative number (0 - exit): " );
unsigned int n;
if ( scanf( "%u", &n ) != 1 || n == 0 ) break;
putchar( '\n' );
draw_hourglass_rec( n );
putchar( '\n' );
}
return 0;
}
程序输出将与上面的程序相同。
除了 @Vlad from Moscow 提供的选择之外,您还可以采用另一种方法,它使用相同的辅助函数进行递归,但将初始高度设置为负值,当高度更大时递归结束比输入的原始值,例如
#include <stdio.h>
#include <stdlib.h>
void hghelper (int h, int current)
{
if (current > h)
return;
int ac = abs(current);
if (ac == 1)
current = 1;
if (ac != 0) {
int stars = ac;
int indent = (h - stars) / 2;
while (indent--)
putchar (' ');
while (stars--)
putchar ('*');
putchar ('\n');
}
hghelper (h, current + 2);
}
void hourglass (int h)
{
int negh = -h;
hghelper (h, negh);
}
int main (int argc, char **argv) {
int height;
if (argc > 1) {
if (sscanf (argv[1], "%d", &height) != 1 || height < 0)
return 1;
}
else
height = 5;
hourglass (height);
}
例子Use/Output
请注意,对于此算法,底部(宽度)始终具有与高度相同的星星数。您可以根据需要进行调整。
默认height = 5
:
$ ./bin/hourglass_recursive
*****
***
*
***
*****
height = 6
:
$ ./bin/hourglass_recursive 6
******
****
**
**
****
******
height = 7
:
$ ./bin/hourglass_recursive 7
*******
*****
***
*
***
*****
*******
height = 21
:
$ ./bin/hourglass_recursive 21
*********************
*******************
*****************
***************
*************
***********
*********
*******
*****
***
*
***
*****
*******
*********
***********
*************
***************
*****************
*******************
*********************
我需要在 C 中递归地绘制沙漏。我需要 1 个辅助函数加上实际函数。以下是函数签名: void helper(unsigned int height, unsigned int offset) void real(unsigned int height)
其中height描述的是要绘制的行数,offset是每行开头的空格数。对于每一行,星星的数量应减少 2,偏移量应增加 1,高度应减少 1,直到到达沙漏的中间。之后,高度应继续降低,但星数应增加 2,偏移量应减少 1。如果输入高度为偶数,则第一行应有 height - 1 星。此外,中间应该有两排只有 1 颗星。如果输入的高度是奇数,那么第一行应该有高度星。
Ex) height = 6
*****
***
*
*
***
*****
Ex) height = 5
*****
***
*
***
*****
我必须使用递归,不允许循环。
这是我的辅助函数。我在弄清楚主要功能时遇到了麻烦。
void draw_hourglass_rec_helper(unsigned int height, unsigned int offset)
{
if (height == 0) {
printf("\n");
} else if (offset == 0) {
printf("*");
draw_hourglass_rec_helper(height-1, 0);
} else {
printf(" ");
draw_hourglass_rec_helper(height, offset-1);
}
}
最佳尝试:
void draw_hourglass_rec(unsigned int height)
{
if(height < 1)
{
return;
}
{
draw_hourglass_rec_helper(height, ((-0.5 * height) + (9.0/2.0)));
draw_hourglass_rec(height-2);
}
}
打印:
**********
********
******
****
**
对于 draw_hourglass_rec(10) 夫妻问题 1)我无法打印沙漏的下半部分 2)星星的数量应该总是奇数 3)我不知道如何表达偶数输入情况,其中应该有 2 行,每行 1 星 4) 如果我在奇数高度上使用此代码,我将陷入无限循环。
这是我用 C 语言编码的第一周。我真的很难用这种语言表达我的逻辑。
提前谢谢你。
给你。
#include <stdio.h>
void draw_hourglass_rec_helper( unsigned int n, int offset )
{
const char c = '*';
if ( n )
{
printf( "%*c", offset + 1, c );
unsigned int k = n % 2 == 0 ? n - 1 : n;
for ( unsigned int i = 0; i < k - 1; i++ ) putchar( c );
putchar( '\n' );
if ( ! ( n < 2 ) ) draw_hourglass_rec_helper( n - 2, offset + 1 );
if ( n != 1 )
{
printf( "%*c", offset + 1, c );
for ( unsigned int i = 0; i < k - 1; i++ ) putchar( c );
putchar( '\n' );
}
}
}
void draw_hourglass_rec( unsigned int n )
{
if ( n )
{
draw_hourglass_rec_helper( n, 0 );
}
}
int main(void)
{
while ( 1 )
{
printf( "Enter a non-negative number (0 - exit): " );
unsigned int n;
if ( scanf( "%u", &n ) != 1 || n == 0 ) break;
putchar( '\n' );
draw_hourglass_rec( n );
putchar( '\n' );
}
return 0;
}
程序输出可能看起来像
Enter a non-negative number (0 - exit): 10
*********
*******
*****
***
*
*
***
*****
*******
*********
Enter a non-negative number (0 - exit): 9
*********
*******
*****
***
*
***
*****
*******
*********
Enter a non-negative number (0 - exit): 8
*******
*****
***
*
*
***
*****
*******
Enter a non-negative number (0 - exit): 7
*******
*****
***
*
***
*****
*******
Enter a non-negative number (0 - exit): 6
*****
***
*
*
***
*****
Enter a non-negative number (0 - exit): 5
*****
***
*
***
*****
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
如果辅助函数的第二个参数是unsigned int类型,那么你可以使用循环来输出初始空格,例如
void draw_hourglass_rec_helper( unsigned int n, unsigned int offset )
{
const char c = '*';
if ( n )
{
for ( unsigned int i = 0; i < offset; i++ ) putchar( ' ' );
unsigned int k = n % 2 == 0 ? n - 1 : n;
for ( unsigned int i = 0; i < k; i++ ) putchar( c );
putchar( '\n' );
if ( ! ( n < 2 ) ) draw_hourglass_rec_helper( n - 2, offset + 1 );
if ( n != 1 )
{
for ( unsigned int i = 0; i < offset; i++ ) putchar( ' ' );
for ( unsigned int i = 0; i < k; i++ ) putchar( c );
putchar( '\n' );
}
}
}
另一种方法是使用静态变量作为输出偏移量,而不是使用辅助函数。
#include <stdio.h>
void draw_hourglass_rec( unsigned int n )
{
static int offset = 0;
const char c = '*';
if ( n )
{
++offset;
printf( "%*c", offset, c );
unsigned int k = n % 2 == 0 ? n - 1 : n;
for ( unsigned int i = 0; i < k - 1; i++ ) putchar( c );
putchar( '\n' );
if ( ! ( n < 2 ) ) draw_hourglass_rec( n - 2 );
if ( n != 1 )
{
printf( "%*c", offset, c );
for ( unsigned int i = 0; i < k - 1; i++ ) putchar( c );
putchar( '\n' );
}
--offset;
}
}
int main(void)
{
while ( 1 )
{
printf( "Enter a non-negative number (0 - exit): " );
unsigned int n;
if ( scanf( "%u", &n ) != 1 || n == 0 ) break;
putchar( '\n' );
draw_hourglass_rec( n );
putchar( '\n' );
}
return 0;
}
程序输出将与上面的程序相同。
除了 @Vlad from Moscow 提供的选择之外,您还可以采用另一种方法,它使用相同的辅助函数进行递归,但将初始高度设置为负值,当高度更大时递归结束比输入的原始值,例如
#include <stdio.h>
#include <stdlib.h>
void hghelper (int h, int current)
{
if (current > h)
return;
int ac = abs(current);
if (ac == 1)
current = 1;
if (ac != 0) {
int stars = ac;
int indent = (h - stars) / 2;
while (indent--)
putchar (' ');
while (stars--)
putchar ('*');
putchar ('\n');
}
hghelper (h, current + 2);
}
void hourglass (int h)
{
int negh = -h;
hghelper (h, negh);
}
int main (int argc, char **argv) {
int height;
if (argc > 1) {
if (sscanf (argv[1], "%d", &height) != 1 || height < 0)
return 1;
}
else
height = 5;
hourglass (height);
}
例子Use/Output
请注意,对于此算法,底部(宽度)始终具有与高度相同的星星数。您可以根据需要进行调整。
默认height = 5
:
$ ./bin/hourglass_recursive
*****
***
*
***
*****
height = 6
:
$ ./bin/hourglass_recursive 6
******
****
**
**
****
******
height = 7
:
$ ./bin/hourglass_recursive 7
*******
*****
***
*
***
*****
*******
height = 21
:
$ ./bin/hourglass_recursive 21
*********************
*******************
*****************
***************
*************
***********
*********
*******
*****
***
*
***
*****
*******
*********
***********
*************
***************
*****************
*******************
*********************