首页 > 解决方案 > 打印此模式背后的逻辑

问题描述

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;
}

这是打印上述模式的代码我正在尝试调试和跟踪这些代码背后的主要逻辑是什么。我需要帮助,尤其是在这些方面

int min = i < j ? i : j;
min = min < len-i ? min : len-i-1;
min = min < len-j-1 ? min : len-j-1;

标签: cloops

解决方案


以下是一个几乎相同的版本,更容易理解。原始程序中的三个令人困惑的行被注释掉,下面给出了三个替换行。

#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是更靠近表格的顶部还是底部。基于此,它返回到最近边缘的距离。第二行非常相似,但适用于列 index j,因此它返回到最靠近左边缘或右边缘的距离。

第三行选择在前两行计算的值中较小的一个。

所有这些都类似于“距中心的距离”的原因是随后printf从 中减去计算值n,其中n是表格宽度的一半......并且索引与边缘的最大距离是中心(即,每个边缘之间的中间)。

因此,现在您可以将算法的原始版本解读为从第一行中较小的i或开始的任意选择。j然后接下来的两行和修订版的前两行做同样的事情,但是你必须发扬min要么 要么i的知识j

考虑这些行中的第一行:如果min == i那么该行实际上与修订版相同;但如果min == j,则情况(在修订版中)i < len-i没有实际意义,因为j已经小于 的结果值i。然而,仍然处理len-i-1小于min/的情况。j

简而言之,原文更难理解,因为它迫使读者进行逐案分析,并将所有结果牢记于心。修订后的版本计算简单的独立值,然后将它们组合成所需的结果。


推荐阅读