如何在c编程中以优化的方式在10X10行和列中打印V ?



我使用*在特定的行和列中打印V。我有很多if语句。我在下面分享我的代码

是否有任何优化的方式在10X10行列中打印V图案?(没有很多if条件)?

#include <stdio.h>
int main() {
int row, column;
for (row = 1; row <= 10; row++) {
for (column = 1; column <= 10; column++) {
if (row == 1 && (column == 1 || column == 10)
|| row == 3 && (column == 2 || column == 9)
|| row == 5 && (column == 3 || column == 8)
|| row == 7 && (column == 4 || column == 7)
|| row == 10 && column == 5)
printf("*");
else
printf(" ");
}
printf("n");
}
return 0;
}

当您需要输出任意数量的空格时,一个合理的选择是使用printf字符串宽度指定符左加空格:

printf("%*s*", spaces, "");

上面将输出空字符串,填充到整数值spaces的宽度,然后输出*。请注意,格式字符串%*s意味着您既指定宽度,又指定字符串作为额外参数。该部分中的*实际的*无关。我们将添加到格式字符串的末尾。

因此,对于V形,除了最后一行(如果宽度为奇数)外,每一行都有两个*字符。直观地做到这一点的一种方法是跟踪每行V的左右部分的位置,然后进行数学计算以确定要添加多少填充。

的例子:

void v(int width)
{
int l = 0, r = width;
for (; l < r; l++, r--)
{
printf("%*s*%*sn", l, "", r-l, "*");
}
if (l == r)
printf("%*s*n", l, "");
}

如果您真的想要更精简的代码,您可以选择将最后一行滚动到循环中。在本例中,当l == r时,您只想输出单个星号。否则你需要两个。因此,您可以输出字符串&"*"[l==r]——这意味着当l==r为真时,您将跳过星号,它将看起来像一个空字符串(因为您落在NUL终止符上)。

注意,这不是很好的风格。它牺牲可读性换取紧凑性。

void v(int width)
{
for (int l = 0, r = width; l <= r; l++, r--)
{
printf("%*s*%*sn", l, "", r-l, &"*"[l==r]);
}
}

所以,这是"有效率"在紧凑的代码和没有太多的函数调用方面。如果您关心的是printf的格式解析,那么您可以完全避免它。下面,我们使用相同的左/右边界,并使用循环遍历每一行。这实际上做了我们的printf在内部做的事情,除了更明显的是发生了什么:

void v(int width)
{
int l = 0, r = width-1;
for (; l <= r; l++, r--)
{
int x = 0;
for (; x < l; x++) putchar(' ');
putchar('*');
if (x < r)
{
for (x++; x < r; x++) putchar(' ');
putchar('*');
}
putchar('n');
}
}

现在来点好玩的…

作为练习,下面是printf方法,但没有循环(使用递归):
void vv(int width, int row) {
if(width >= 0) {
printf("%*s*%*sn", row, "", width, &"*"[width==0]);
vv(width-2, row+1);
}
}
void v(int width) {
vv(width, 0);
}

这里是这个想法变成了一个看起来很酷的可怕的混乱。;)

#include <stdio.h>
#define VV int
#define vV "*%*s%*sn"
VV Vv( VV     v ,VV
vv){if(v    -->0){
printf     (vV+2,
vv++     ,vV,v
,vV+     !v);
Vv(--  v,vv
);}} VV V
(VV v){
Vv(v,
1);
}
int main() {
for (int v = 1; v < 12; v++) {
printf("size %dn", v);
V(v);
}
}

我不认为这是优化的,但将更简单和可扩展的大小。

#include <stdio.h>
#define SIZE 10
#define MID ((SIZE-1)/2)                // midst position of SIZE
#define ABS(x) ((x)<0?-(x):(x))         // absolute value of x
int main()
{
int i, j;
for (i = 0; i < SIZE; i++) {
for (j = 0; j < SIZE; j++) {
if (i % 2 == 0 && ABS(j - MID) == MID - i / 2) putchar('*');
else putchar(' ');
}
putchar('n');
}
return 0;
}

(解释)
假设SIZE= 10,则计算出MID的值为4。然后,v形状的星号将被对称地放置在第四列。
让我们按照如下方式在列(j)和行(i)中放置数字:

012345678
*       * 0   ABS(0 - 4) == 4 - 0, ABS(8 - 4) == 4 - 0
1   skipped as i & 2 != 0
*     *  2   ABS(1 - 4) == 4 - 1, ABS(7 - 4) == 4 - 1
3   skipped
*   *   4   ABS(2 - 4) == 4 - 2, ABS(6 - 4) == 4 - 2
5   skipped
* *    6   ABS(3 - 4) == 4 - 3, ABS(5 - 4) == 4 - 3
7   skipped
*     8   ABS(4 - 4) == 4 - 4

上面的方程式是加星号的条件。例如,在第0行中,我们想把它放在第0列和第8列。条件j - 4 == +/- 4ABS(j - 4) == 4将表示由于对称性而产生的条件。如果我们把这个条件推广到行上,我们可以把它描述为i % 2 == 0 && ABS(j - MID) == MID - i / 2.

这段代码考虑了行和*的位置之间的关系,如果您在第一行,那么我们希望第0列和第9列打印*,然后是第二行,我们希望第1列和第8列,以此类推。因此,我使用了行迭代器和列迭代器来知道在具体的行中打印的是哪一列。

#include <stdio.h>
int main()
{
int matrix_size = 10; //Assuming is squared matrix 10x10
int counter = 0;
int i,j;
for(i=0;i<(int)(matrix_size/2);i++) {
for(j=0;j<matrix_size;j++) {
if(j==i || j==(matrix_size-1-i)) {
printf("*");
}else{
printf(" ");
}
}
printf("n");
}

return 0;
}

编辑:与tshiono的解决方案相比,我只写了5行V,他打印了10行,但假设每行之间有一个空格行。这两种解决方案都是可以的,这取决于你想要什么。

对于对称的V形,行数和列数应该是奇数。下面是一个更简单的方法:

#include <stdio.h>
#include <stdlib.h>
int main() {
for (int n = 11, row = 0; row < n; row++) {
for (int column = 0; column < n; column++)
putchar(" *"[2 * abs(column - n / 2) == n - 1 - row]);
printf("n");
}
return 0;
}

输出:

*         *
*       *
*     *
*   *
* *
*

对于较粗的V形:

#include <stdio.h>
#include <stdlib.h>
int main() {
for (int n = 11, row = 0; row < n; row++) {
for (int column = 0; column < n; column++)
putchar(" *"[abs(2 * abs(column - n / 2) - (n - 1 - row)) <= 1]);
printf("n");
}
return 0;
}

输出:

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

其他答案考虑到V的特定形状并围绕它进行优化。

对于任何形状,我都有一个优化的解决方案。

这涉及到一个查找表,其中包含构成该形状的*字符的所有位置。

struct { int row,col; } shape[] = {
{1,1}, {1,10}, {3,2}, {3,9}, {5,3}, {5,8}, {7,4}, {7,7}, {10,5},
{-1,-1}
};

最后一个位置({-1,-1})与终止字符串的''的目的相同。

相关内容

  • 没有找到相关文章

最新更新