这种图案打印算法可以更有效地编写吗?

时间:2015-06-21 16:08:06

标签: c algorithm loops printf time-complexity

这是我的问题

//to print this diamond
     /*
        1
       121
      12321
     1234321
      12321
       121
        1 

       */

这是我尝试的解决方案,我将问题视为6个直角三角形,并试图解决如下

    #include<stdio.h>

    int main()
    {

    //The number n is at the heart of the pattern ,4 in this case
    int i,j,k,l;
    int n=4;

    //do it in 2 steps top+bottom
    //consider we are in line 4 ie 1234321

        //top
        for(i=0;i<n;i++)
        {
        //print spaces
            for(j=0;j<(n-i-1);j++)
            {
            printf(" ");
            }
        //print first half ie 1234
            for(k=0;k<=i;k++)
            {
            printf("%d",(k+1));
            }
        //print the second haf ie 321
            for(l=i;l>0;l--)
            {
            printf("%d",l);
            }
        //next line
        printf("\n");
        }

    //consider we are in line 5 ie 12321

        //bottom
        for(i=(n-2);i>=0;i--)
        {
        //print spaces
            for(j=(n-1);j>i;j--)
            {
            printf(" ");
            }
        //print left half ie 123
            for(k=0;k<=i;k++)
            {
            printf("%d",(k+1));
            }
        //print right half
            for(l=i;l>0;l--)
            {
            printf("%d",l);
            }
        //next line
        printf("\n");
        }

    return 0;
    }

现在我需要减少使用的循环次数(不要太多关于实际的时间和空间复杂性),我的目标是只减少循环次数,任何人都可以建议如何或尝试减少数量循环和答案

谢谢!

3 个答案:

答案 0 :(得分:4)

您可以使用min功能替换这两个数字&#39;循环使用一个:

static inline int min(int x, int y) { return (x < y) ? x : y; }

int N = 2 * (n - 1);
for (int k = 0; k <= N; k++)
    putchar(min(k, N-k) + '0' + 1);

对于n == 4N == 6,您会得到:

k    0   1   2   3   4   5   6
N-k  6   5   4   3   2   1   0
min  0   1   2   3   2   1   0

然后打印对应于&#39; min + 1&#39;的数字。执行此操作的成本是每次迭代的min函数的条件。

如果你真的坚持,你可以在更大范围内的循环内进行更多的条件计算,在索引低于一个阈值时打印空格,并在阈值之后使用基于min函数的公式打印数字。

答案 1 :(得分:4)

您可以使用abs()函数来获取递增/递减序列:

#include <stdlib.h>
#include <stdio.h>

int main() {
  const int N = 5; /* center value = length of edge of diamond */
  int i, j, k;
  for( i=1 ; i<2*N ; ++i ) {
    j = N-abs(N-i); /* center value of row */
    printf( "% *d", N-j+2, 1 );
    for( k=2 ; k<2*j ; ++k ) putchar( j-abs(j-k)+'0' );
    putchar('\n');
  }
  return 0;
}

输出:

     1
    121
   12321
  1234321
 123454321
  1234321
   12321
    121
     1

答案 2 :(得分:3)

您可以将图像生成卸载到函数中以将循环计数减少到两个:

char diamondChar(int x, int y) {
    if(x < 0) x = -x;
    if(y < 0) y = -y;
    int value = 4 - x - y;
    return (value <= 0) ? ' ' : '0' + (char)value;
}

int main() {
    for(int y = -3; y <= 3; y++) {
        for(int x = -3; x <= 3; x++) {
            putchar(diamondChar(x, y));
        }
        putchar('\n');
    }
}