【问题标题】:Sorting a 2D array with qsort使用 qsort 对二维数组进行排序
【发布时间】:2015-09-16 13:16:04
【问题描述】:

我正在尝试对二维数组进行排序。首先我按列排序,然后按行排序。逐列有效,但逐行无效。这段代码有什么问题?

int scmpr (const void *a, const void *b){ 
return strcmp((const char*)a, (const char*)b);
}

int main(void){
  int i,j;

  char **tab;
  tab=(char**)malloc(sizeof(char*)* 10); 

  for(i=0; i<10; i++){
    tab[i]=(char*)malloc(sizeof(char)*15);
  }

  for(i=0; i<10; i++){
    for(j=0; j<15; j++){
      tab[i][j]=rand()%20+'b';
      printf("%c ", tab[i][j]);
    }
    puts("");
  }
  for (i = 0; i<10; i++){
    qsort(&tab[i][0], 15, sizeof(char), scmpr); 
  }
  qsort(tab, 10, sizeof(char), scmpr); //<-- doesn't work

    for(i=0; i<10; i++){
      for(j=0; j<15; j++){
        printf("%c ", tab[i][j]);
      }
    puts("");
    } 
  puts("");
  return 0;
  }

【问题讨论】:

  • 停止转换为 malloc 这不是 C++。
  • 每一行在这里排序:ideone.com/IhUAFV
  • @Krasnal 首先,数组中的所有字符串都不是以零结尾的,这个调用 qsort(&tab[i][0], 15, sizeof(char), scmpr);没有意义。

标签: c sorting quicksort ansi qsort


【解决方案1】:

qsort

对数组元素进行排序

对base指向的数组的num个元素进行排序,每个元素的大小 字节长,使用比较函数确定顺序。

此函数使用的排序算法比较元素对 通过使用指向它们的指针调用指定的比较函数 论据。

该函数不返回任何值,而是修改了 base 指向的数组重新排序其元素,定义为 比较。

等价元素的顺序是不确定的。

因此,它将 i 列表中的每组 15 个元素排序,作为一个普通数组,它会给你你看到的结果。但是,由于“j”是分开的。您需要做的是为组中的每一行为 i 的每个值创建一个单维数组表。然后在对每个单维度行进行 qsort 之后,将它们适当地移动到原始 2D 表中。

qsort(tab, 10, sizeof(char*), scmpr);//element is char*

将 qsort 的前 10 个(字符)元素而不是您想要的行。

【讨论】:

    【解决方案2】:

    我认为你的意思是以下

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <time.h>
    
    #define M   10
    #define N   15
    
    int ccmp( const void *lhs, const void *rhs )
    {
        unsigned char c1 = *( const unsigned char *)lhs;
        unsigned char c2 = *( const unsigned char *)rhs; 
    
        if ( c1 < c2 ) return -1;
        else if ( c2 < c1 ) return 1;
        else return 0;
    }
    
    int scmp( const void *lhs, const void *rhs )
    {
        return strcmp( *( const char ** )lhs, *( const char ** )rhs );
    }
    
    int main( void ) 
    {
        char **tab;
        tab = ( char** )malloc( M * sizeof( char* ) ); 
    
        for ( size_t i = 0; i < M; i++ )
        {
            tab[i] = ( char* )malloc( N * sizeof( char ) );
        }
    
        srand( ( unsigned int )time( NULL ) );
    
        for ( size_t i = 0; i < M; i++ )
        {
            for ( size_t j = 0; j < N - 1; j++ )
            {
                tab[i][j] = rand() % ( 'Z' - 'A' + 1 ) + 'A';
            }
            tab[i][N-1] = '\0';
        }
    
        for ( size_t i = 0; i < M; i++ )
        {
            printf( "%s\n", tab[i] );
        }
    
        printf( "\n" );
    
        for ( size_t i = 0; i < M; i++ )
        {
            qsort( tab[i], N - 1, sizeof( char ), ccmp ); 
        }
        qsort( tab, M, sizeof( char * ), scmp );
    
        for ( size_t i = 0; i < M; i++ )
        {
            printf( "%s\n", tab[i] );
        }
    
        printf( "\n" );
    
        for ( size_t i = 0; i < M; i++ ) free( tab[i] );
        free( tab );
    
        return 0;
    }
    

    程序输出可能如下所示

    DJSKLJOHGHEANW
    ZSDZJZXCKGYOVF
    LHEOQYAEHOLPYR
    PLORDTQOSNQFVP
    TQUEYAVQYVUHKH
    WIZOVPHYKXPEMF
    JHUFARLARGQSEN
    BOWYYXOTMVTYUI
    DIOOPKVPDHPXPI
    PTXQJVQHTGCHDY
    
    AAEFGHJLNQRRSU
    ADEGHHJJKLNOSW
    AEEHHLLOOPQRYY
    AEHHKQQTUUVVYY
    BIMOOTTUVWXYYY
    CDFGJKOSVXYZZZ
    CDGHHJPQQTTVXY
    DDHIIKOOPPPPVX
    DFLNOOPPQQRSTV
    EFHIKMOPPVWXYZ
    

    【讨论】:

      【解决方案3】:
      #include <stdio.h>
      #include <string.h>
      #include <stdlib.h>
      
      int scmpr (const void *a, const void *b){//receive char **
          return strcmp(*(const char**)a, *(const char**)b);
      }
      int ccmpr (const void *a, const void *b){//compare one char
          unsigned char x = *(unsigned char *)a;
          unsigned char y = *(unsigned char *)b;
          return (x > y) - (x < y);
      }
      
      int main(void){
          int i,j;
      
          char **tab;
          tab=(char**)malloc(sizeof(char*)* 10); 
      
          for(i=0; i<10; i++){
              tab[i]=(char*)malloc(sizeof(char)*16);//+1 for NUL char to use strcmp
          }
      
          for(i=0; i<10; i++){
              for(j=0; j<15; j++){
                  tab[i][j]=rand()%20+'b';
                  printf("%c ", tab[i][j]);
              }
              tab[i][j] = 0;//set NUL
              puts("");
          }
          for (i = 0; i<10; i++){
              qsort(&tab[i][0], 15, sizeof(char), ccmpr); 
          }
          qsort(tab, 10, sizeof(char*), scmpr);//element is char*
      
          puts("");
      
          for(i=0; i<10; i++){
              for(j=0; j<15; j++){
                  printf("%c ", tab[i][j]);
              }
              puts("");
          }
          //deallocate
          return 0;
      }
      

      【讨论】:

        最近更新 更多