能否更高效地编写此图案打印算法?
Can this pattern printing algorithm be written more efficiently?
这是我的问题
//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;
}
现在我需要减少其中使用的循环数(不关心实际时间和 space 复杂性),我的目标是只减少循环数,任何人都可以建议如何或尝试减少循环次数并回答
谢谢!
您可以使用 min
函数将两个 'digit' 循环替换为一个:
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 == 4
、N == 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
然后打印 'min + 1' 对应的数字。这样做的成本是 min
函数中每次迭代的条件。
如果你真的坚持,你可以在一个更大范围的循环内做更多的条件计算,当索引低于一个阈值时打印空格,并使用基于 min
函数的公式在 min
之后打印数字阈值。
您可以将图像生成卸载到一个函数中,以将循环次数减少到两次:
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');
}
}
您可以使用 abs()
函数获取 increasing/decreasing 序列:
#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
这是我的问题
//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;
}
现在我需要减少其中使用的循环数(不关心实际时间和 space 复杂性),我的目标是只减少循环数,任何人都可以建议如何或尝试减少循环次数并回答
谢谢!
您可以使用 min
函数将两个 'digit' 循环替换为一个:
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 == 4
、N == 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
然后打印 'min + 1' 对应的数字。这样做的成本是 min
函数中每次迭代的条件。
如果你真的坚持,你可以在一个更大范围的循环内做更多的条件计算,当索引低于一个阈值时打印空格,并使用基于 min
函数的公式在 min
之后打印数字阈值。
您可以将图像生成卸载到一个函数中,以将循环次数减少到两次:
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');
}
}
您可以使用 abs()
函数获取 increasing/decreasing 序列:
#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