2013-11-28 3 views
0

오름차순으로 이름별로 레코드를 정렬하도록 내 레코드를 정렬하려고합니다. 이름이 같은 이름이있는 경우, 그것은 예를 들어 순서C - Qsort : 오름차순으로 이름 정렬 및 내림차순으로 등급 지정

내림차순으로 자신의 성적을 정렬합니다 : 원래 TEXTFILE을

simpson bart 25 
simpson bart 35 
simpson lisa 90 
simpson bart 34 

원하는 출력 :

simpson bart 35 
simpson bart 34 
simpson bart 25 
simpson lisa 90 

이 내가 가진 것입니다 :

int sort_nameasc_gradedes(const void *p, const void *q) 
{ 
    const record *pp = p; 
    const record *qq = q; 

    int n1 = strcmp(pp->name.first, qq->name.first); 
    int n2 = strcmp(pp->name.last, qq->name.last); 

    if (n2 == 0 && n1 != 0) { 
     return n1; 
    } else if (n2 != 0 && n1 == 0) { 
     return n2; 
    } else { 
     return (pp->score - qq->score); 
    } 
} 

이것은 제대로 작동하지 않습니다.

미리 감사드립니다.

+0

을하지만, 여기에 문제가있을 가능성이있는 동안 당신의 설명은 당신이 '사용하지 말아야합니다 일반적으로 약 2 – woolstar

+0

을 이야기 :

는 다음과 같은

뭔가 작동 할 수 반환 값 (pp-> score - qq-> score);'값이 오버플로를 일으킬 정도로 크면 정의되지 않은 동작을합니다. –

답변

1

찾고 계신 것이 틀림 없습니다.

int sort_nameasc_gradedes(const void *p, const void *q) 
{ 
    const record *pp = p; 
    const record *qq = q; 

    int n1 = strcmp(pp->name.first, qq->name.first); 
    int n2 = strcmp(pp->name.last, qq->name.last); 

    if (n1 != 0) { 
     return n1; 
    } else if (n2 != 0) { 
     return n2; 
    } else { 
     return (qq->score - pp->score); 
    } 
} 

먼저 첫 번째와 두 번째 조건에서 수행 한 작업을 생각해보십시오. 당신이 쓴이 입력

simpson bart 25 
taufique hussain 30 

의사가 처음으로 이름을 기반으로해야하지만, 당신의 코드에서 마지막 else 상태에서 결정된다 그리고 그것은 만들 것 :

if (n2 == 0 && n1 != 0) { 
     return n1; 
} 

입력이있는 경우는 어떻게 출력

taufique hussain 30 
simpson bart 25 

대신

simpson bart 25 
taufique hussain 30 
,

이제 마지막 상태가됩니다. ppsimpson bart 25이고 qqsimpson bart 30 인 경우 pp->score - qq->score 값은 얼마입니까? -5 맞습니까? 그런 다음 정렬 된 배열에 해답이 될 것이다 다음

대신 원하는의
simpson bart 25 
simpson bart 30 

: 당신은 단지를 확인해야

int sort_nameasc_gradedes(const void *p, const void *q) 
{ 
    const record *pp = p; 
    const record *qq = q; 

    int n2 = strcmp(pp->name.last, qq->name.last); 

    if (n2 != 0) 
    { 
     return n2; 
    } 
    else 
    { 
     int n1 = strcmp(pp->name.first, qq->name.first); 

     if (n1 != 0) 
     { 
      return n1; 
     } 
     else 
     { 
      return qq->score - pp->score; 
     } 
    } 
} 
1

당신이 원하는 무엇인가 필드를 한 번에 하나씩 선택하고 한 쌍의 필드가 같지 않으면 즉시 리턴합니다. 따라서 먼저 name.last을 비교하고 strcmp 결과를 유지하십시오. 0이 아니면 리턴하고, 그렇지 않으면 다음 필드로 진행하십시오. 그런 다음 name.first을 같은 방법으로 비교하십시오 ... strcmp 결과가 0이 아닌 경우 반환하십시오. 마지막으로 score을 비교하십시오.

score에 서명되어 사용 된 데이터 유형의 극한에 근접하지 않을 경우와 마찬가지로 빼기를 테스트로 사용할 수 있지만 서명이 없거나 빼기가 랩핑 될 수있는 경우 다른 정렬이 필요할 수 있습니다 시험.당신은 세 가지 필드에 정렬되어

int sort_nameasc_gradedes(const void *p, const void *q) 
{ 
    const record *pp = p; 
    const record *qq = q; 
    int r; 

    if ((r = strcmp(pp->name.last, qq->name.last)) != 0) 
     return r; 
    if ((r = strcmp(pp->name.first, qq->name.first)) != 0) 
     return r; 
    /* return pp->score - qq->score; */ 
    return (pp->score < qq->score) ? 1 : ((pp->score > qq->score) ? -1 : 0); 
} 
+0

"pp-> score - qq-> score"부분은 어떻게됩니까? 당신이 옳다고 생각 했습니까? 나는 그의 요구에 따라 그것이 "qq-> score - pp-> score"이어야한다고 생각한다. – taufique

+0

좋은 점, 위의 예제를 업데이트했습니다. (필자는 요구 사항이 아닌 OP 코드에 있었던 것과 함께 가고있었습니다) – Baldrick

2

: 더이 같은

simpson bart 30 
simpson bart 25