我需要使用嵌套的for循环制作由星形“ *”制成的螺旋图案。我设法做出外线,现在我不知道如何在同一位置重复较小的漩涡。 我应该拥有的东西:
*********
*
******* *
* * *
* *** * *
* * * *
* ***** *
* *
*********
任何帮助将不胜感激。
答案 0 :(得分:3)
彻底nerd-sniped之后,我想到了这一点:
#include <stdio.h>
void print_spiral(int size)
{
for (int y = 0; y < size; ++y)
{
for (int x = 0; x < size; ++x)
{
// reflect (x, y) to the top left quadrant as (a, b)
int a = x;
int b = y;
if (a >= size / 2) a = size - a - 1;
if (b >= size / 2) b = size - b - 1;
// calculate distance from center ring
int u = abs(a - size / 2);
int v = abs(b - size / 2);
int d = u > v ? u : v;
int L = size / 2;
if (size % 4 == 0) L--;
// fix the top-left-to-bottom-right diagonal
if (y == x + 1 && y <= L) d++;
printf((d + size / 2) % 2 == 0 ? "X" : " ");
}
printf("\n");
}
}
正如其他人所提到的,分配一个代表网格的数组,然后将螺旋线绘制到该数组中(您可以在其中自由移动),然后打印该数组可能更直观。但是,此解决方案使用O(1)内存。
几乎可以肯定的是,它可以进行一些优化和简化,但是我会把它“留给读者练习”,因为我已经花了太多时间了;-)
我不会再花时间在此上,但是我有第二次尝试,可能会 使用更简单的代码。如果您以越来越大的尺寸检查输出,就会出现一种模式:
在每个象限内,模式是规则的,可以轻松编码。我想您只需要将( x , y )坐标仔细地分类为四个象限之一,然后应用适当的模式即可。
答案 1 :(得分:0)
最明智的方法是创建2d数组,然后在其中填充所需的*
。
或者,您可以尝试提出一些“及时”逻辑以避免缓冲。这更加复杂。
我想出了一种方法,将螺旋线看作是四个不同的三角形,形成一个正方形。在这里,我为四个三角形分别打印了“ a,b,c,d”,以显示我的意思:
aaaaaaaaaac
c
baaaaaac c
b c c
b baac c c
b b dd c c
b b c c
b dddddd c
b c
dddddddddd
有两个棘手的部分。一种是正确对齐对角线。反复尝试并不难。另一个棘手的问题是,并非所有正方形都以相同的方式分成交替的线。您可以在示例上方的正方形n=11
中看到,左侧偏移了一个。也许有更好的解决方案,但这会尝试创建交替的行和列。
n = 11;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
// top
if (j > i - 2 && j < n - i && i % 2 == (n&1)) printf("a");
// left
else if (j < i - 1 && j < n - i && j % 2 == (n & 1)) printf("b");
// right
else if (j > n - i -1&& j > i && j % 2 == ((n+1) & 1)) printf("c");
// bottom
else if (j < i + 1 && j > n - i - 1 && i % 2 == ((n + 1) & 1)) printf("d");
else printf(" ");
}
printf("\n");
}
答案 2 :(得分:-1)
我建议您看一下 NCurses 库。它包含许多用于在终端窗口中移动光标的方法,例如mvaddch()
和curs_set()
。
Here是一个文档,其中包含您需要了解如何使用 NCurses 的所有信息。
但是,如果您不想使用外部库,则可以定义int
或bool
的2D数组,然后打印{{ 1}},其中索引分别为*
或1
。
后者的示例:
true