【问题标题】:Function to print a 2d array centred around an element x打印以元素 x 为中心的二维数组的函数
【发布时间】:2021-11-03 23:08:24
【问题描述】:

我想要打印这个数组,它是一个 8x10 数组,但我想将它打印为一个以元素 x 为中心的 5x5 数组。

例如

char array[8][7] = {['a','b','c','d','e','f','g','h']
['q','w','e','r','t','y','u','i']
['k','j','h','g','f','d','s','a']
['z','x','c','v','b','n','m','q']
['g','z','p','l','k','h','n','a']
['q','e','m','a','c','t','u','p']
['r','b','l','t','k','f','b','z']}

i = 5 j = 2 
for(k = 0; k < 5; k++) 
{ 
    for(j = 0; j < 5; j++) 
    { 
        print("%c",array[i][j]); 
    }    
    printf("\n"); 
    
}

我试过这个,它给我左边 2 和右边 2,但它打印了 5 次,它没有打印上面和下面的 2。

如果我想打印一个数组中心为 m ([6][3]) 的 5x5 数组,我该怎么做

输出:

ema
ema
ema
ema
ema

【问题讨论】:

  • 你试过什么?不要忘记 C 中的数组是从零开始索引的?
  • 所以我试过这个,它给了我 2 到左边和 2 到右边,但它打印了 5 次,它不打印上面和下面的 2,其中 i = 5 和 j = 2 for(k = 0; k
  • 将其添加到您可以格式化代码的问题中。
  • 你知道如何打印整个数组吗?让i 从 0 运行到 N-1,j 从 0 运行到 M-1,然后打印 array[i][j]? (当然,其中 N 和 M 是整个数组的大小。)因此,如果您想打印以元素 x,y 为中心的 5×5 子数组,在我看来,您将希望 i 从 @ 运行987654332@ 到 x+2jy-2 运行到 y+2。但是对于一个健壮的程序,您还必须仔细检查以确保 i 永远不会小于 0 或大于 N-1,并且您必须确保 j 永远不会小于 0 或大于 M- 1.
  • 是的,我可以打印整个数组,但是每次我去执行 x+2 x-2 和 y-2 y+2 时,边界检查都会给我 seg 错误跨度>

标签: arrays c multidimensional-array


【解决方案1】:

这是一个可能的实现,它也执行正确的边界检查(希望我没有对它进行很多测试)。你可以试试here:

#include <stdio.h>

int min(int x, int y) { return x < y ? x : y; }
int max(int x, int y) { return x > y ? x : y; }

void print_5(int at_y, int at_x, char *array, int dim_y, int dim_x) {
    int from_y = max(0, at_y - 2);
    int to_y = min(at_y + 2, dim_y - 1);

    int from_x = max(0, at_x - 2);
    int to_x = min(at_x + 2, dim_x - 1);

    for(int y = from_y; y <= to_y; y++) {
        for(int x = from_x; x <= to_x; x++)
            printf("%c", array[x + y * dim_x]);
        printf("\n");
    }

}

int main() {
    char array[7][8] = {
        {'a','b','c','d','e','f','g','h'},
        {'q','w','e','r','t','y','u','i'},
        {'k','j','h','g','f','d','s','a'},
        {'z','x','c','v','b','n','m','q'},
        {'g','z','p','l','k','h','n','a'},
        {'q','e','m','a','c','t','u','p'},
        {'r','b','l','t','k','f','b','z'},
    };

    print_5(5, 2, (char*)array, 7, 8);
}

关于array[x + y * dim_x]。首先,请记住数组从0 开始。因此,如果您希望它以靠近左下角的“m”为中心,那将是索引array[5][2]。其次,二维数组int[y][x] 的第一维是行('y'),第二维是列('x')。在内存中,这些行只是一个接一个地存储,也就是

int array[4][2] = {
    {1, 2},
    {3, 4},
    {5, 6},
    {7, 8}
};

the same as

int array[8] = {1, 2, 3, 4, 5, 6, 7, 8};

因此,m-th 行的n-th 列元素的索引公式为n + m * number_of_columns(其中number_of_columns = dim_x 以上)。

因为 C 中的数组(至少在传递给函数时)只是一个指向内存块的指针,所以我们需要将数组的 y 和 x 维度传递给函数。此外,通常情况下,您会为维度定义常量并在整个代码中使用这些常量而不是整数文字,但上面的函数应该只是一个简单的实现。

另外,作为旁注,C 中的数组文字使用 {} 而不是 [] :)

【讨论】:

    【解决方案2】:

    问题中的代码无法编译,并且似乎显示出各种误解。例如:

    char array[8][7] = {['a','b','c','d','e','f','g','h']
    ['q','w','e','r','t','y','u','i']
    ['k','j','h','g','f','d','s','a']
    ['z','x','c','v','b','n','m','q']
    ['g','z','p','l','k','h','n','a']
    ['q','e','m','a','c','t','u','p']
    ['r','b','l','t','k','f','b','z']}
    

    方括号应该是大括号,右括号后面应该跟逗号。定义的末尾需要有一个分号。有7行数据,每行8个元素,所以数组维度应该是array[7][8]。问题文本提到了一个 8x10 数组;它没有显示出来。

    问题还说(或多或少)“我想打印一个 5x5 数组,数组的中心是'm'(元素array[6][3])”——但是有一个@ 987654325@array[3][6] 和另一个array[6][2]。对于这两个位置,以这些位置为中心的 5x5 阵列在阵列边界之外运行。代码应避免此类访问。

    C99 及更高版本支持可变长度数组(在 C99 中无条件;在 C11 或 C17 中有条件)。除非您遇到不支持它的编译器,否则应该在现代代码中使用它。主要基于 Unix 的桌面系统上的编译器确实支持它们(GCC、Clang 等)。

    下面是一些似乎可以工作的代码:

    /* SO 6908-1666 */
    
    #include <stdio.h>
    
    static void print_submatrix(int nrows, int ncols, char matrix[nrows][ncols],
                                int crow, int ccol, int rsize, int csize)
    {
        int min_row = crow - (rsize / 2);
        int max_row = min_row + rsize;
        int min_col = ccol - (csize / 2);
        int max_col = min_col + csize;
    
        /* Array bounds? */
        if (min_col < 0)
            min_col = 0;
        if (min_row < 0)
            min_row = 0;
        if (max_col > ncols)
            max_col = ncols;
        if (max_row > nrows)
            max_row = nrows;
    
        printf("R = %d, C = %d, Centre (%d, %d), Size (%d, %d) ",
                nrows, ncols, crow, ccol, rsize, csize);
        printf("Columns [%d..%d), Rows [%d..%d)\n", min_col, max_col, min_row, max_row);
        for (int i = min_row; i < max_row; i++)
        {
            for (int j = min_col; j < max_col; j++)
                putchar(matrix[i][j]);
            putchar('\n');
        }
    }
    
    int main(void)
    {
        char array[7][8] =
        {
            { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' },
            { 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i' },
            { 'k', 'j', 'h', 'g', 'f', 'd', 's', 'a' },
            { 'z', 'x', 'c', 'v', 'b', 'n', 'm', 'q' },
            { 'g', 'z', 'p', 'l', 'k', 'h', 'n', 'a' },
            { 'q', 'e', 'm', 'a', 'c', 't', 'u', 'p' },
            { 'r', 'b', 'l', 't', 'k', 'f', 'b', 'z' },
        };
    
        print_submatrix(7, 8, array, 6, 2, 5, 5);
        print_submatrix(7, 8, array, 3, 6, 5, 5);
        print_submatrix(7, 8, array, 3, 3, 5, 5);
        /* Print whole matrix, but it isn't a good use of the interface */
        print_submatrix(7, 8, array, 3, 4, 7, 8);
    
        return 0;
    }
    

    样本输出:

    R = 7, C = 8, Centre (6, 2), Size (5, 5) Columns [0..5), Rows [4..7)
    gzplk
    qemac
    rbltk
    R = 7, C = 8, Centre (3, 6), Size (5, 5) Columns [4..8), Rows [1..6)
    tyui
    fdsa
    bnmq
    khna
    ctup
    R = 7, C = 8, Centre (3, 3), Size (5, 5) Columns [1..6), Rows [1..6)
    werty
    jhgfd
    xcvbn
    zplkh
    emact
    R = 7, C = 8, Centre (3, 4), Size (7, 8) Columns [0..8), Rows [0..7)
    abcdefgh
    qwertyui
    kjhgfdsa
    zxcvbnmq
    gzplkhna
    qemactup
    rbltkfbz
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-30
      • 2020-07-01
      • 1970-01-01
      • 2022-12-04
      相关资源
      最近更新 更多