How to merge sort struct with strings?

安稳与你 提交于 2020-05-16 03:15:42

问题


I'm trying to modify a common mergesort, for sorting a struct of strings. But I can't figure out what's wrong. A warning appears on every line with strcpy() & strcmp() that tells:

warning: passing argument 1 of 'strcpy' makes pointer from integer without a cast [-Wint-conversion]|
C:\Program Files (x86)\CodeBlocks\MinGW\include\string.h|45|note: expected 'char *' but argument is of type 'char'|

And it recommends me to put * on char L[n1] and R[n2]

But even if i declare 
char *L[n1] 
char *R[n2]

It always stops at strcpy() or maybe even at strcmp() . . . i can't understand why. Does anybody have any ideas how to strcpy and strcmp these two?

struct kegiatan{

     char nama[50];
};

void merge(struct kegiatan *keg, int low, int mid, int high){

    int i, j, k;

    int n1 = mid - low + 1;
    int n2 = high - mid;
    char L[n1];
    char R[n2];

    for(i = 0; i < n1; i++){
        strcpy(L[i], keg[low + i].nama);        // the program always stops here.
    }
    printf("L = %s", L[i]);
    printf("keg = %s", keg[low + i].nama);
    system("pause");
    for(j = 0; j < n2; j++){
        strcpy(R[j], keg[mid + 1 + j].nama);
    }

    i = 0;
    j = 0;
    k = low;

    while(i < n1 && j < n2){
        if(strcmp(L[i], R[j]) < 0){
            strcpy(keg[k].nama, L[i]);
            i++;
        } else{
            strcpy(keg[k].nama, R[j]);
            j++;
        }
        k++;
    }
     while (i < n1) { 
        strcpy(keg[k].nama, L[I]); 
        i++; 
        k++; 
     }

    while(j < n2) {
        strcpy(keg[k].nama, R[j]);
        j++;
        k++;
    }

}

void mergesort(struct kegiatan *keg, int low, int high){

    if(low < high){
        int mid = (low + high) / 2;

        mergesort(keg, low, mid);
        mergesort(keg, mid + 1, high);
        merge(keg, low, mid, high);
    }

}

回答1:


you are mistaking string with char .here strcpy(L[i], keg[low + i].nama); you are not copying one string to another .you are copying one string to one element of array L.

also note in printf you shouldn't use %s for L[i] and don't use R[j] in strcpy(it's a char).

note you are comparing two char here if(strcmp(L[i], R[j]) , so don't use strcmp.

in short when you declare char string[num], it's an array of characters ,but this string[i] is not an array , it's just one element of array.so don't treat it like an array.

note in all of your strcpy you have send a string and one element of string as arguments.




回答2:


Consider using the built-in qsort function from <stdlib.h>.

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

struct sample {
    char *word;
};

int comparator(const struct sample *a, const struct sample *b) {
    return strcmp(a->word, b->word);
}

int main() {
    struct sample s[] = {{"n"},
                         {"b"},
                         {"a"}};
    int elements = sizeof(s) / sizeof(struct sample);
    qsort(s, elements, sizeof(struct sample), (__compar_fn_t) comparator);
    for (int i = 0; i < elements; ++i) {
        printf("%s\n", s[i].word);
    }
    return 0;
}



回答3:


First i see in your code:

printf("L = %s", L[i]);
printf("keg = %s", keg[low + i].nama);

L[i] is the character type, not string as the answer of @Hanie. One more error here is you print L[i] out of the array capacity because after the for loop, i is equal to n1. This is reason why your program stops here sometime. If you want to see the string 'L[i]' step by step, put it in the for loop.

Secondly, in your merge code, you forget to copy the remaining elements of L[] as the code below.

 while (i < n1) 
 { 
     strcpy(keg[k].nama, L[i]); 
     i++; 
     k++; 
 }

If you use the declaration

char *L[n1] 
char *R[n2]

you have to allocate (malloc) for the string before strcpy. Or you can declare as char L[n1][50], L2[n2][50]

The complete code:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
struct kegiatan{

     char nama[50];
};

void merge(struct kegiatan *keg, int low, int mid, int high){

    int i, j, k;

    int n1 = mid - low + 1;
    int n2 = high - mid;
    char L[n1][50];
    char R[n2][50];

    for(i = 0; i < n1; i++){
        strcpy(L[i], keg[low + i].nama); 
        //printf("L[%d] = %s\n", i, L[i]); 
    }
    for(j = 0; j < n2; j++){
        strcpy(R[j], keg[mid + 1 + j].nama);
    }

    i = 0;
    j = 0;
    k = low;

    while(i < n1 && j < n2){
        if(strcmp(L[i], R[j]) <= 0){
            strcpy(keg[k].nama, L[i]);
            i++;
        } else{
            strcpy(keg[k].nama, R[j]);
            j++;
        }
        k++;
    }

     // Copy the remaining elements of L[]. Here you have to add
     while (i < n1) 
    { 
        strcpy(keg[k].nama, L[i]); 
        i++; 
        k++; 
    } 

    while(j < n2){
        strcpy(keg[k].nama, R[j]);
        j++;
        k++;
    }

}

void mergesort(struct kegiatan *keg, int low, int high){

    if(low < high){
        int mid = (low + high) / 2;

        mergesort(keg, low, mid);
        mergesort(keg, mid + 1, high);
        merge(keg, low, mid, high);
    }

}

int main () {
    struct kegiatan st[3];
    strcpy(st[0].nama,"something2");
    strcpy(st[1].nama,"something1");
    strcpy(st[2].nama,"something3");
    mergesort(st, 0, 2);

    for (int i = 0; i < 3; i++) {
        printf("%s\n", st[i].nama);
    }
}

The result:

something1
something2
something3



来源:https://stackoverflow.com/questions/61042309/how-to-merge-sort-struct-with-strings

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!