C 如何使用mergesort对具有相同姓氏的名称进行排序?

C 如何使用mergesort对具有相同姓氏的名称进行排序?,c,mergesort,C,Mergesort,我们的老师给了我们一个csv文件,我们应该根据姓氏按字母顺序对名字进行排序。 但也有同名同姓的名字 我的代码只适用于他们的姓氏。 我不知道当他们有相同的姓氏时,应该添加什么来按他们的名字排序 这是我的代码: #包括 #包括 #包括 #定义人11 结构列表\u人{ charfirstname[20]; char LastName[20]; 字符名[20]; 炭龄[5]; }; 类型定义结构列表\人员详细信息; int merge_sort(); 整数合并(细节*[11],整数,整数,整数); in

我们的老师给了我们一个csv文件,我们应该根据姓氏按字母顺序对名字进行排序。 但也有同名同姓的名字 我的代码只适用于他们的姓氏。 我不知道当他们有相同的姓氏时,应该添加什么来按他们的名字排序

这是我的代码:

#包括
#包括
#包括
#定义人11
结构列表\u人{
charfirstname[20];
char LastName[20];
字符名[20];
炭龄[5];
};
类型定义结构列表\人员详细信息;
int merge_sort();
整数合并(细节*[11],整数,整数,整数);
int main(){
文件*信息;
int i,j;
细节A[人];
详细信息*单元[人];
对于(i=0;i<(人+1);i++){
单元[i]=&A[i];
}
info=fopen(“people.csv”、“r”);
对于(i=0;i而(leftIndex LastName))您可以使用如下方式比较元素:

        int cmp;
        // compare the last names
        cmp = strcasecmp( ( A[leftIndex]->LastName), ( A[rightIndex]->LastName) );
        if (cmp == 0)
        {
            // last names are identical so compare the first names
            cmp = strcasecmp( ( A[leftIndex]->FirstName), ( A[rightIndex]->FirstName) );
        }
        if (cmp <= 0)
        {
            // ...
        }
        else
        {
            // ...
        }
int-cmp;
//比较姓氏
cmp=strcasecmp((A[leftIndex]>LastName),(A[rightIndex]>LastName));
如果(cmp==0)
{
//姓氏是相同的,所以比较一下名字
cmp=strcasecmp((A[leftIndex]->FirstName),(A[rightIndex]->FirstName));
}

if(cmp如果您有两个相同的姓氏,则需要与另一个属性进行比较,并使用该属性确定排序方式

首先,为了让事情更清晰,我们将从条件表达式中调用
stracecmp
,并将其结果保存到某个变量中:

while ( leftIndex <= mid  &&  rightIndex <= high )
{
  int lastNameResult = strcasecmp( A[leftIndex]->LastName, A[rightIndex]->LastName );

如果遇到两个同名的条目,则需要选择另一个要比较的属性(例如
Age
),并将其放入
中,否则(firstnamesult==0)
分支。或者,您可以合并
代码中存在多个问题:

  • 数组大小为
    people
    ,因此初始化循环应排除索引值
    people
    。而不是(i=0;i<(people+1);i++)的
    您应该编写:

      for (i = 0; i < people; i++)
    
    您还应该检查
    fscanf()
    的返回值以检测无效输入

  • 要订购具有相同姓氏的项目,应使用比较功能,比较
    LastName
    ,然后比较
    FirstName
    ,然后比较
    Age
    ,返回第一个不相等的结果

以下是一个例子:

int compareDetails(const Details *a, const Details *b) {
    int res, age_a, age_b;
    if ((res = strcasecmp(a->LastName, b->LastName)) != 0)
        return res;
    if ((res = strcasecmp(a->FirstName, b->FirstName)) != 0)
        return res;
    age_a = atoi(a->Age);
    age_b = atoi(a->Age);
    return (age_a > age_b) - (age_a < age_b);
}

您可以通过单击分数下方的灰色复选标记来接受答案。
while ( leftIndex <= mid  &&  rightIndex <= high )
{
  int lastNameResult = strcasecmp( A[leftIndex]->LastName, A[rightIndex]->LastName );
  int firstNameResult = strcasecmp( A[leftIndex]->FirstName, A[rightIndex]->FirstName );

  /**
   * Yes, you can use logical expressions outside of an if condition.  The
   * parentheses aren't necessary in this case, but it should make the
   * expression easier to understand.  The result of this expression
   * will either be 0 or 1.  
   */
  int mergeLeft = lastNameResult < 0 || (lastNameResult == 0 && firstNameResult < 0);
  if ( mergeLeft )
  {
    tempA[combinedIndex++] = *A[leftIndex++];  // I've combined the updates
  }                                            // of combinedIndex and leftIndex
  else                                         // within these statements, 
  {                                            // just to save a little space
    tempA[combinedIndex++] = *A[rightIndex++]; // I also replaced pointer
  }                                            // notation with array notation
}                                              // because it's less eye-stabby
  for (i = 0; i < people; i++)
  fscanf(info," %19[^,], %19[^,], %4s", A[i].LastName, A[i].FirstName, A[i].Age);
int compareDetails(const Details *a, const Details *b) {
    int res, age_a, age_b;
    if ((res = strcasecmp(a->LastName, b->LastName)) != 0)
        return res;
    if ((res = strcasecmp(a->FirstName, b->FirstName)) != 0)
        return res;
    age_a = atoi(a->Age);
    age_b = atoi(a->Age);
    return (age_a > age_b) - (age_a < age_b);
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define PEOPLE 11

struct list_people {
    char FirstName[20];
    char LastName[20];
    char Name[20];
    char Age[5];
};

typedef struct list_people Details;

int merge_sort(Details A[], int low, int high);

int main() {
    FILE *info;
    int i, j, n;
    Details A[PEOPLE];
    
    info = fopen("people.csv", "r");
    if (info == NULL)
        return 1;

    for (n = 0; n < PEOPLE; n++) {
       if (fscanf(info," %19[^,], %19[^,], %4s", A[n].LastName, A[n].FirstName, A[n].Age) != 3)
           break;
    }
    fclose(info);
    
    merge_sort(A, 0, n);
    for (i = 0; i < n; i++) {
        printf( "\t %-20s %-20s Age:%-20s \n", A[i].FirstName, A[i].LastName, A[i].Age);
    }
    return 0;
}
    
int compareDetails(const Details *a, const Details *b) {
    int res, age_a, age_b;

    if ((res = strcasecmp(a->LastName, b->LastName)) != 0)
        return res;
    if ((res = strcasecmp(a->FirstName, b->FirstName)) != 0)
        return res;
    age_a = atoi(a->Age);
    age_b = atoi(a->Age);
    return (age_a > age_b) - (age_a < age_b);
}

void merge(Details A[], int low, int mid, int high) {
    int leftIndex = low;
    int rightIndex = mid;
    int combinedIndex = 0;
    int i, j;
    Details tempA[high - low];
    
    while (leftIndex < mid && rightIndex < high) {
        if (compareDetails(&A[leftIndex], &A[rightIndex]) <= 0) {
            tempA[combinedIndex] = A[leftIndex];
            combinedIndex++;
            leftIndex++;
        } else {
            tempA[combinedIndex] = A[rightIndex];
            combinedIndex++;
            rightIndex++;
        }
    }
    while (leftIndex < mid) {
        tempA[combinedIndex] = A[leftIndex];
        combinedIndex++;
        leftIndex++;
    }
    while (rightIndex < high) {
        tempA[combinedIndex] = A[rightIndex];
        combinedIndex++;
        rightIndex++;
    }
    for (i = low; i < high; i++) {
        A[i] = tempA[i - low];
    }
}

int merge_sort(Details A[], int low, int high) {
    if (high - low >= 2) {
        int mid = low + (high - low) / 2;
        merge_sort(A, low, mid);
        merge_sort(A, mid, high);
        merge(A, low, mid, high);
    }
    return 0;
}