【问题标题】:How to sort based on columns in 2 dimensional arrays in C?如何根据C中二维数组中的列进行排序?
【发布时间】:2020-04-14 14:56:57
【问题描述】:

我刚刚开始学习 C。我正在尝试在 C 中对二维数组中的列进行排序。

问题来了

编写一个程序来输入一个 m x n 的数组。奇数列升序排序,偶数列降序排序

我的想法是使用递归函数。在数组的每一行,我会将元素推送到一个新数组中,对其进行排序,然后重新分配给旧数组。递归循环,直到我们到达列的末尾。

这是我的 C 代码:


#include <stdio.h>

int j = 0, temp[] = {}, sizeTemp = 0; // The size of temp, change overtime in loop()
int arr[4][3] = {
    {1,2,3},
    {4,8,6},
    {2,1,5},
    {3,7,4}
};

void pushToArray(int arr[], int currentEl, int addEl){  // Push an element into an array
    arr[currentEl] = addEl;
}

void bubbleSort(int arr[], int size, int inc_dec){  
// Using bubble sort to sort the temporary array, which is then reassigned to the old array
    int temp;

    for(int i = 0; i < size; i++){
        for(int j = 0; j < size - 1;j++){
            if(inc_dec == 1){
                // Increasing
                if(arr[j] > arr[j+1]){
                    temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }else{
                // Decreasing
                if(arr[j] < arr[j+1]){
                    temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
    }
}
int justForReturnSomething(){ 
// void function can't return a value, so I use this just for returning something
    return 1;
}
void loop(){
    int temp2;
    for(int i = 0; i < 4; i++){
        if(j > 2){
            return justForReturnSomething();
        }
        temp2 = arr[i][j];
        pushToArray(temp,sizeTemp,temp2);
        sizeTemp++;
        if(j % 2 != 0){
            bubbleSort(temp,sizeTemp,1);
        }else{
            bubbleSort(temp, sizeTemp,-1);
        }

    }

    for(int k = 0; k < 4; k++){
        arr[k][j] = temp[k];
    }

    if(j > 2){
        return justForReturnSomething();
    }else{
        j++;
        for(int m = 0; m < sizeTemp; m++){ // Reassign the temp to empty
            temp[m] = 0;
        }
        sizeTemp = 0; // reassign the size of temp to 0
        loop();    
    }

}

int main(){

    loop();
    printf("Your sorted array: \n");
    for(int i = 0; i < 4; i++){
        for(int j = 0; j < 3; j++){
            printf("%d,",arr[i][j]);
        }
        printf("\n");
    }

    return 0;
}

结果:

Your sorted array:                                                                                                            
5,0,7,                                                                                                                        
4,0,6,                                                                                                                        
3,0,4,

只是为了DEMONSTRATING解决问题的思路,我用Javasript试了一下,结果还不错:

let arr = [
    [1,2,3],
    [4,8,6],
    [2,1,5],
    [3,7,4]
]; 
let temp = [], j=0;
function bubbleSort( arr,  size,  inc_dec){
    let temp;

    for(let i = 0; i < size; i++){
        for(let j = 0; j < size - 1;j++){
            if(inc_dec == 1){
                // Increasing
                if(arr[j] > arr[j+1]){
                    temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }else{
                // Decreasing
                if(arr[j] < arr[j+1]){
                    temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
    }
}

function loop(){
    for(let i = 0; i < 4; i++){
        if(j > 2){
            return;
        }
        temp.push(arr[i][j]);
        if(j % 2 !== 0){
            bubbleSort(temp,temp.length,1);
        }else{
            bubbleSort(temp, temp.length,-1);
        }

    }

    for(let k = 0; k < 4; k++){
        arr[k][j] = temp[k];
    }

    if(j > 2){
        return;
    }else{
        j++;       
        temp = [];
        loop();    
    }

}
loop();
console.log(arr);

由于我尝试用自己的想法解决这个问题,并且没有在谷歌上搜索就想出了一个解决方案,如果你能指导我用这种方法引入 C 的解决方案,我会很高兴。但是,我们非常感谢其他方法。

【问题讨论】:

  • Javascript 是按引用传递的,而 C 是按值传递的。
  • 想想如何编写可测试的代码是件好事——也就是说,我怎样才能分解我的代码,以便每个函数都能做到其测试用例所要求的最低限度?这有助于简化代码。例如,我们可以使用 sortColumn 函数重构上面的示例,该函数具有单一职责(给定矩阵、columnIndex 和排序方向,对矩阵中该列的值进行排序)。这个功能可能更容易实现,之后添加基于列索引排序的逻辑是微不足道的。
  • 比如我们可以用javascript写一个简单的表达式来实现sortColumn:function sortColumn(matrix, columnIndex, desc) { let sortFn = desc ? (a, b) =&gt; b - a : (a, b) =&gt; a - b; matrix .map(row =&gt; row[columnIndex]) .sort(sortFn) .forEach((columnValue, rowIndex) =&gt; matrix[rowIndex][columnIndex] = columnValue); return matrix; }
  • 感谢布赖恩的评论。我会尽力。但据我所知,我们无法在 C 中返回数组。
  • 这是一个 C 语言的快速演示:repl.it/repls/ArcticFavorableRoot

标签: javascript c arrays sorting


【解决方案1】:

这是来自@Brian 的答案。非常感谢布赖恩

#include <stdio.h>

void bubbleSort2D(int numRows, int numCols, int arr[][numCols], int col, int incDec) {
  // Using bubble sort to sort a column in the matrix
  for (int i = 0; i < numRows; i++) {
    for (int j = 0; j < numRows - 1; j++) {
      int a = arr[j][col];
      int b = arr[j + 1][col];
      if ((incDec && a > b) || (!incDec && a < b)) {
        arr[j][col] = b;
        arr[j + 1][col] = a;
      }
    }
  }
}

int main() {

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

  for (int i = 0; i < 3; i++) {
    // sort "odd" columns in descending order, "even" columns in ascending order
    bubbleSort2D(4, 3, arr, i, i % 2 == 0);
  }

  printf("Your sorted array: \n");
  for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 3; j++) {
      printf("%d,", arr[i][j]);
    }
    printf("\n");
  }

  return 0;
}

这里是repl链接:

Srort columns in 2D array

【讨论】:

    【解决方案2】:

    不是一个完整的答案,因为看起来你想自己解决这个问题。

    这里的技巧是按列排序,当 C 以行优先顺序存储数组时。您可以通过定义一个步幅(对于具有 M 列和 N 行的数组,这将是 sizeof a[0],即单行的大小)并以该步幅的倍数执行所有索引来做到这一点。或者您可以转置数组,按行排序,然后将结果转置回来。

    我建议就地排序以提高性能,但编写执行往返转置的代码可能会更简单。将整个数组复制两次是昂贵的,但并非如此:它与数组的大小成正比。

    如果您编写函数以升序和降序排序,并且您有int[M][N],则可以酌情调用sort_ascending( int[i], N )sort_descending( int[i], N )。你可以看看标准库中的qsort()。如果您想尝试就地排序,则需要传递行数、列数和要排序的列。列数将是您关心的元素之间的步幅。

    控制向上还是向下排序的几种不同方法:总是先递减排序,然后递增再递增 2,保留一个标志以记住您是对最后一行进行升序还是降序排序,或者检查 1%2,它会优化到一个非常便宜的按位或指令。

    【讨论】:

    • 感谢戴维斯勒的帮助。我去看看
    • @Darwin 应该多说一些让问题变得不那么简单的事情:您正在对列进行排序,而不是对行进行排序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-09
    • 2015-06-08
    • 2018-08-17
    • 1970-01-01
    • 2022-01-10
    • 2013-12-16
    相关资源
    最近更新 更多