简体   繁体   中英

String array Sorting C

I have been trying to make this program sort a 2d array of strings by column index.

I initialized this 2d array like this:

char *str[ROWS][COLS] = {{"Russia", "Boxing", "Mens", "Gold"},
                         {"America", "Cycling", "Mens", "Gold"}, 
                         {"New Zealand", "Swimming", "Womens", "Silver"},   
                         {"India", "Badminton", "Mens", "Bronze"}};

And if I wanted to sort this array by the first column, the country names, then it would look something like this:

char *str[ROWS][COLS] = {{"America", "Cycling", "Mens", "Gold"}, 
                         {"India", "Badminton", "Mens", "Bronze"}};
                         {"New Zealand", "Swimming", "Womens", "Silver"},   
                         {"Russia", "Boxing", "Mens", "Gold"}};

This is what I have done so far, and it is nearly correct, except for the sorting method. I am having trouble implementing that.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ROWS 4
#define COLS 4

void print_array(char *str[][COLS]);
void sort_array(char *str[][COLS], int nrows, int col);

int
main(void) {
    char *str[ROWS][COLS] = {{"Russia", "Boxing", "Mens", "Gold"},
                             {"America", "Cycling", "Mens", "Gold"}, 
                             {"New Zealand", "Swimming", "Womens", "Silver"}, 
                             {"India", "Badminton", "Mens", "Bronze"}};
    int col;

    /* array before sorting */
    printf("Before: \n");
    print_array(str);

    /*choosing column index to sort by*/
    printf("\nChoose which column index you wish to sort by: ");
    if (scanf("%d", &col) != 1) {
        printf("Invalid input\n");
        exit(EXIT_FAILURE);
    }

    sort_array(str, ROWS, col);

    /* array after sorting */
    printf("\nAfter: \n");
    print_array(str);

return 0;
}

void
print_array(char *str[][COLS]) {
    int i, j;

    for (i = 0; i < ROWS; i++) {
        for (j = 0; j < COLS; j++) {
            printf("%s  ", str[i][j]);
        }
        printf("\n");
    }
}

/*function used for sorting the array */
void
sort_array(char *str[][COLS], int nrows, int col) {
    int i, j;
    char *temp;

    for (i = 0; i < nrows; i++) {
        for (j = i; j < nrows; j++) {
            if(strcmp(str[i][col], str[j][col]) > 0) {
                temp = str[i][col];
                str[i][col] = str[j][col];
                str[j][col] = temp;
            }
        }
    }   
}

The issue I'm having is that my sorting algorithm is not swapping the rows, but the just strings in that column. I was also trying to use the insertion sort algorithm but I was not sure how to implement that with a 2d array of strings.

Any help would be appreciated :)

Using qsort , you need a comparator function taking as arguments pointers to two of the elements to be sorted. In this case the element to be sorted is an entire row in the 2D array. If you need to vary the sort column, you also need to make the variable holding it global (or else you need to create different comparators for each column).

static int sort_column = 0;

static int compare_rows(const void *a, const void *b) {
    return strcmp(((const char **)a)[sort_column], ((const char **)b)[sort_column]);
}

Then you simply call qsort with your array and the comparator function as arguments:

qsort(str, ROWS, sizeof(*str), (compare_rows));

Iterate through the rows. Compare the column for two rows, i and i + 1 . As needed iterate through columns and swap the two rows. Repeat until there were no swaps.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ROWS 4
#define COLS 4

void print_array(char *str[][COLS]);
void sort_array(char *str[][COLS], int nrows, int ncols, int col);

int
main(void) {
    char *str[ROWS][COLS] = {{"Russia", "Boxing", "Mens", "Gold"},
                             {"America", "Cycling", "Mens", "Gold"},
                             {"New Zealand", "Swimming", "Womens", "Silver"},
                             {"India", "Badminton", "Mens", "Bronze"}};
    int col;
    int result = 0;
    int clean = 0;
    /* array before sorting */
    printf("Before: \n");
    print_array(str);

    /*choosing column index to sort by*/
    do {
        printf("\nChoose which column index you wish to sort by 0 to %d: ", COLS - 1);
        if ( ( result = scanf("%d", &col)) != 1) {
            printf("Invalid input\n");
            if ( result == EOF) {
                fprintf ( stderr, "problem getting input\n");
                exit(EXIT_FAILURE);
            }
            //clean input stream
            while ( ( clean = getchar ()) != '\n' && clean != EOF) {}
        }
    } while ( result != 1 || col < 0 || col >= COLS);

    sort_array(str, ROWS, COLS, col);

    /* array after sorting */
    printf("\nAfter: \n");
    print_array(str);
    return 0;
}

void
print_array(char *str[][COLS]) {
    int i, j;

    for (i = 0; i < ROWS; i++) {
        for (j = 0; j < COLS; j++) {
            printf("%s  ", str[i][j]);
        }
        printf("\n");
    }
}

/*function used for sorting the array */
void
sort_array(char *str[][COLS], int nrows, int ncols, int col) {
    int i = 0, j = 0, swap = 0;
    char *temp;

    do {
        swap = 0;
        for ( i = 0; i < nrows - 1; i++) {//iterate through rows
            if ( strcmp( str[i][col], str[i + 1][col]) > 0) {//compare col for row i and i+1
                for ( j = 0; j < ncols; j++) {//iterate through cols and swap rows
                    temp = str[i][j];
                    str[i][j] = str[i + 1][j];
                    str[i + 1][j] = temp;
                }
                swap = 1;
            }
        }
    } while ( swap);//loop until no swaps
}

Since C11 you can do it as follows:

int compare_col(const void *a, const void *b, void *ctx) {
    int col = *(int*)ctx;
    return strcmp(((char**)a)[col], ((char**)b)[col]);
}

/*function used for sorting the array */
void sort_array(char *str[][COLS], int nrows, int col) {
    qsort_s(str, nrows, sizeof(char*)*COLS, compare_col, &col);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM