【问题标题】:Rotate 90 degrees 2D char array旋转 90 度二维字符数组
【发布时间】:2017-09-16 20:05:21
【问题描述】:

我真的看不出这段代码有什么问题?

例如,我正在尝试获取:

w 3 l l  
d o n 3
g a m 3
o v 3 r 

来自:

l 3 3 r
l n m 3
3 0 4 v
w d g 0

这是我的代码:

int main() {
    printf("Size of array : ");
    int n;
    scanf("%d", &n);
    printf("Cases : \n");
    char **array = (char**)malloc(n * sizeof(char));
    for (i = 0; i < n; i++)
        array[i] = (char*)malloc(n * sizeof(char));
    int j;
    // Words input
    for (i = 0; i <= n; i++) {
        for (j = 0; j < n; j++) {
            scanf("%c", &array[i][j]);
        }
    }
    for (i = 0; i <= n; i++) {
        for (j = 0; j < n; j++) {
            printf("%c", array[i][j]);
        }
    }
    printf("\n\n");

    // Transpose of the array
    for (i = 0; i <= n; i++) {
        for (j = i + 1; j < n; j++) {
            char tmp = array[i][j];
            array[i][j] = array[j][i];
            array[j][i] = tmp;
        }
    }

    // Display the transposed array
    printf("Transposed array \n");
    for (i = 0; i <= n; i++) {
        for (j = 0; j < n; j++) {
            printf("%c", array[i][j]);
        }
    }
    printf("\n");
    printf("\n");
    // Swap the columns
    for (i = 0; i <= n; i++) {
        for (j = 0; j < n / 2; j++) {
            char tmp = array[i][j];
            array[i][j] = array[i][n - 1 - j];
            array[i][n - 1 - j] = tmp;
        }
    }
    // Display after rotation
    printf("After rotation\n");
    for (i = 0; i <= n; i++) {
        for (j = 0; j < n; j++) {
            printf("%c", array[i][j]);
        }
    }
    printf("\n");
    return 0;
}

语法有问题吗? 它似乎可以很好地处理整数......

int main() {
    printf("Size of array : ");
    int n;
    scanf("%d", &n);
    printf("Cases : \n");
    char **array = (char**)malloc(n * sizeof(char));
    for (i = 0; i < n; i++)
        array[i] = (char*)malloc(n * sizeof(char));
    int j;
    // Words input
    for (i = 0; i <= n; i++) {
        for (j = 0; j < n; j++) {
            scanf("%c", &array[i][j]);
        }
    }
    for (i = 0; i <= n; i++) {
        for (j = 0; j < n; j++) {
            printf("%c", array[i][j]);
        }
    }
    printf("\n\n");
    // Transpose of the array
    for (i = 0; i <= n; i++ ) {
        for (j = i + 1; j < n; j++ ) {
            char tmp = array[i][j];
            array[i][j] = array[j][i];
            array[j][i] = tmp;
        }
    }
    // Display the transposed array
    printf("Transposed array \n");
    for (i = 0; i <= n; i++) {
        for (j = 0; j < n; j++) {
            printf("%c", array[i][j]);
        }
    }
    printf("\n");
    printf("\n");
    // Swap the columns
    for (i = 0; i <= n; i++) {
        for (j = 0; j < n / 2; j++) {
            char tmp = array[i][j];
            array[i][j] = array[i][n - 1 - j];
            array[i][n - 1 - j] = tmp;
        }
    }
    // Display after rotation
    printf("After rotation\n");
    for (i = 0; i <= n; i++) {
        for (j = 0; j < n; j++) {
            printf("%c", array[i][j]);
        }
    }
    printf("\n");
    return 0;
}                                                                      

【问题讨论】:

  • 当你为array分配内存时,你分配了多少字节
  • 另外,n 元素数组的顶部索引是什么?一个循环,直到例如i &lt;= n 为真,i 的最后一个值是多少?这是一个有效的索引吗?
  • i 未声明
  • 最后,请阅读undefined behavior(这就是你所拥有的)。 UB 使您的整个程序格式错误且无效。 UB 的可能性之一是该程序可能看似工作正常(而实际上它通常不会)。
  • @J.Carter:感谢您展示了为什么投射malloc 的结果是一个非常糟糕的主意。您显示的定义非常错误。为什么要将指针转换为char

标签: c arrays memory multidimensional-array rotation


【解决方案1】:

正如@Some程序员老兄所指出的,有两个主要问题:

首先,您没有分配“n x n 字符矩阵”意义上的“二维数组”,但您似乎分配了一个由 n 个指针组成的数组,每个指针指向一个 n 个字符的序列。所以你应该首先分配n个指针,即char **array = malloc(n * sizeof(char*))

其次,您在整个过程中使用i &lt;= n 反复超出数组范围;请改用i &lt; n。顺便说一句:你没有声明ij...

解决了这个问题,你的程序就可以工作了:

int main()
{
    printf("Size of array : ");
    int n;
    scanf("%d", &n);
    printf("Cases : \n");
    char **array = malloc(n * sizeof(char*));
    for (int i = 0; i < n; i++)
        array[i] = malloc(n * sizeof(char));
    int j;
    // Words input
    for (int i = 0; i < n; i++)
    {
        for (j = 0; j < n; j++)
        {
            scanf("%c", &array[i][j]);
        }
    }
    for (int i = 0; i < n; i++)
    {
        for (j = 0; j < n; j++)
        {
            printf("%c", array[i][j]);
        }
        printf("\n");
    }
    printf("\n\n");

    // Transpose of the array
    for (int i = 0; i < n; i++ )
    {
        for (int j = i + 1; j < n; j++ )
        {
            char tmp = array[i][j];
            array[i][j] = array[j][i];
            array[j][i] = tmp;
        }
    }

    // Display the transposed array
    printf("Transposed array \n");
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            printf("%c", array[i][j]);
        }
        printf("\n");
    }
    printf("\n");
    printf("\n");
    // Swap the columns
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n / 2; j++)
        {
            char tmp = array[i][j];
            array[i][j] = array[i][n - 1 - j];
            array[i][n - 1 - j] = tmp;
        }
    }
    // Display after rotation
    printf("After rotation\n");
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            printf("%c", array[i][j]);
        }
        printf("\n");
    }
    printf("\n");
    return 0;
}

【讨论】:

    【解决方案2】:

    我建议使用临时表。代码会更容易看懂

    char **rotate(char **table, size_t size)
    {
        char *tmp = malloc(sizeof(char) * size * size);
    
        if (tmp != NULL)
        {
            for (size_t col = 0; col < size; col++)
                for (size_t row = size; row; row--)
                {
                    size_t rr = row - 1;
                    tmp[size - row + col * size] = table[rr][col];
                }
            for (size_t row = 0; row < size; row++)
            {
                memcpy(table[row], tmp + row * size, sizeof(char) * size);
            }
            free(tmp);
        }
        return tmp == NULL ? NULL : table;
    }
    

    【讨论】:

      【解决方案3】:

      您有许多超出其边界访问数组的实例:for (i = 0; i &lt;= n; i++) 应更改为

      for (i = 0; i < n; i++)
      

      还没有定义i...

      【讨论】:

      • 不使用临时表将不起作用,就像他用第一列更改第一行另一列将包含错误数据
      • @PeterJ_01:旋转可以在没有临时表的情况下实现,使用对角线和列+行转置。代码因多种原因而损坏。我只是暗示了最主要的问题,可能需要更多的修复。
      • 是的,但是算法更复杂(目前对于 OP 来说太复杂了 IMO)。让我们专注于简单的迭代和复制:)
      • @PeterJ_01:我同意,简单应该是目标。不幸的是,无论是间接矩阵还是具有动态大小的二维矩阵都不能以简单的方式处理。
      猜你喜欢
      • 2011-06-01
      • 2013-10-27
      • 1970-01-01
      • 2015-07-17
      • 2019-03-06
      • 2018-07-18
      • 2017-10-07
      • 2022-01-07
      • 1970-01-01
      相关资源
      最近更新 更多