【问题标题】:How to merge sort struct with strings?如何将排序结构与字符串合并?
【发布时间】:2020-04-05 12:06:08
【问题描述】:

我正在尝试修改一个常见的归并排序,用于对字符串结构进行排序。但我不知道出了什么问题。带有 strcpy() 和 strcmp() 的每一行都会出现一条警告,告诉您:

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'|

它建议我把 * 放在 char L[n1] 和 R[n2]

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

它总是停在 strcpy() 甚至可能停在 strcmp() 。 . .我不明白为什么。有没有人知道如何 strcpy 和 strcmp 这两个?

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);
    }

}

【问题讨论】:

    标签: c mergesort


    【解决方案1】:

    您将字符串误认为是 char .here strcpy(L[i], keg[low + i].nama); 您没有将一个字符串复制到另一个字符串。您将一个字符串复制到数组 L 的一个元素。

    还要注意在printf 中你不应该在L[i] 中使用%s 并且不要在strcpy 中使用R[j](它是一个字符)。

    注意你在这里比较两个字符 if(strcmp(L[i], R[j]) ,所以不要使用 strcmp

    简而言之,当你声明char string[num]时,它是一个字符数组,但是这个string[i]不是一个数组,它只是数组的一个元素。所以不要把它当作一个数组。

    请注意,在您的所有 strcpy 中,您已经发送了一个字符串和一个字符串元素作为参数。

    【讨论】:

    • 嗯,在这种情况下,如果我声明 L[ j ] [50] ,用这个声明,L 会充当字符串数组吗?
    • @ChristianHalim 是的,现在调用l[i] 将在strcpy 中为真,因为它是一个字符串。
    • 非常感谢哈妮!为了启蒙,它也解决了我所有的其他问题,对于字符串搜索哈哈哈,Cheeersss
    • @ChristianHalim 随意,无需感谢,但如果这个答案有帮助,请接受答案。
    【解决方案2】:

    考虑使用来自&lt;stdlib.h&gt; 的内置qsort 函数。

    #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】:

      首先我在您的代码中看到:

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

      L[i] 是字符类型,而不是字符串作为@Hanie 的答案。这里的另一个错误是您将L[i] 打印出数组容量,因为在for 循环之后,i 等于n1。这就是为什么您的程序有时会停在这里的原因。如果你想一步一步看字符串'L[i]',把它放在for循环中。

      其次,在您的合并代码中,您忘记将L[] 的其余元素复制为以下代码。

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

      如果你使用声明

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

      你必须为strcpy之前的字符串分配(malloc)。或者你可以声明为char L[n1][50], L2[n2][50]

      完整代码:

      #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);
          }
      }
      

      结果:

      something1
      something2
      something3
      
      

      【讨论】:

      • 是的,我确实忘记了 L[ ],感谢您指出,我将在上面编辑我的代码 :)
      猜你喜欢
      • 2020-01-28
      • 1970-01-01
      • 2012-01-17
      • 2015-05-16
      • 2019-07-21
      • 2022-07-01
      • 2012-11-29
      • 2012-05-01
      • 1970-01-01
      相关资源
      最近更新 更多