4 4 4 4 4 4 4
4 3 3 3 3 3 4
4 3 2 2 2 3 4
4 3 2 1 2 3 4
4 3 2 2 2 3 4
4 3 3 3 3 3 4
4 4 4 4 4 4 4
我们必须为上述模式编写程序
#include <stdio.h>
int main()
{
int n;
scanf("%d", &n);
int len = n*2 - 1;
for(int i=0;i<len;i++){
for(int j=0;j<len;j++){
int min = i < j ? i : j;
min = min < len-i ? min : len-i-1;
min = min < len-j-1 ? min : len-j-1;
printf("%d ", n-min);
}
printf("\n");
}
return 0;
}
这是打印上面的图案的代码,我得到的主要是 这些代码背后的逻辑是我试图从4小时开始调试和跟踪此代码。请问有谁能仅帮助我理解此代码的逻辑,这将对您有所帮助(我是编程新手) 尤其是在这些行中
int min = i < j ? i : j;
min = min < len-i ? min : len-i-1;
min = min < len-j-1 ? min : len-j-1;
答案 0 :(得分:0)
以下是几乎相同的版本,更容易理解。 注释掉了原始程序中的三行令人困惑的行,并在下面给出了三行替换行。
#include <stdio.h>
int main()
{
int n;
scanf("%d", &n);
int len = n*2 - 1;
for(int i=0;i<len;i++){
for(int j=0;j<len;j++){
// int min = i < j ? i : j;
// min = min < len-i ? min : len-i-1;
// min = min < len-j-1 ? min : len-j-1;
int min_dist_top_or_bottom = i < len-i ? i : len-i-1;
int min_dist_left_or_right = j < len-j ? j : len-j-1;
int min = min_dist_top_or_bottom < min_dist_left_or_right ? min_dist_top_or_bottom : min_dist_left_or_right;
printf("%d ", n-min);
}
printf("\n");
}
return 0;
}
在注释版本中,它执行相同的计算,但是以一种奇怪的增量方式进行构建。修订版试图使计算独立,直到必须将它们组合起来才能得出答案。了解修订版本后,原始版本更容易分拆。
在修订版中,第一行计算当前行索引i
是更接近表的顶部还是底部。基于此,它会将距离返回到最近的边。第二行非常相似,但是适用于列索引j
,因此它将距离返回到最接近左边缘或右边缘的距离。
第三行选择在前两行中计算出的较小的值。
所有这些之所以类似于“距中心的距离”,是因为后续的printf
从n
中减去计算值,其中n
是表格宽度的一半...并且索引距边缘的最大距离是中心(即,每个边缘之间的中点)。
因此,您现在可以阅读该算法的原始版本,可以做出相当随意的选择,以第一行中的i
或j
中较小的一个开始。接下来的两行与修订版的前两行做相同的事情,但是您必须发扬min
是i
或j
的知识。
请考虑以下几行的第一行:如果min == i
,则该行在字面上与修订版完全相同;但如果是min == j
,则{修订版本中)i < len-i
毫无意义,因为j
已经小于i
的结果值。但是,仍然可以处理len-i-1
小于min
/ j
的情况。
简而言之,原件很难理解,因为它迫使读者进行个案分析,并将所有结果掌握在脑海中。修订版计算简单的独立值,然后将它们组合为所需的结果。
答案 1 :(得分:0)
int min = i < j ? i : j;
如果此语句为真,则 min=i
否则 min=j
。
同样的逻辑适用于:
min = min < len-i ? min : len-i-1;
min = min < len-j-1 ? min : len-j-1;