2013-11-28 153 views
0

我想排列我的記錄,以便按名稱按升序對記錄進行排序。如果有名稱以相同的名稱,它會他們的成績降序排列C - Qsort:按升序排序並按年降序排列

例如排序:原來的文本文件

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

首先想想你在第一和第二個條件下所做的。您寫道:

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

如果什麼輸入是:

此輸入
simpson bart 25 
taufique hussain 30 

決定應基於第一個名字,但在你的代碼,它會在最後else條件來決定的,它將使代替輸出

taufique hussain 30 
simpson bart 25 

simpson bart 25 
taufique hussain 30 

現在來到最後一個條件。如果ppsimpson bart 25qqsimpson bart 30,那麼pp->score - qq->score的值是多少? -5對不對?然後排序數組中的下將答案:

simpson bart 25 
simpson bart 30 

,而不是你想要的:

simpson bart 30 
simpson bart 25 
1

你想要更多的東西是這樣的:

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; 
     } 
    } 
} 
+0

那麼「pp-> score - qq-> score」部分呢?你認爲它是正確的嗎?根據他的要求,我認爲它應該是「qq-> score - pp-> score」。 – taufique

+0

好點,我已經更新了上面的例子。 (我正在使用OP的代碼而不是要求) – Baldrick

2

你只需要檢查一次填寫一個字段,並在一對字段不相等時立即返回。所以首先比較name.last並保留strcmp結果;如果它不是零,則返回它,否則繼續下一個字段。然後,以相同的方式比較name.first ...如果strcmp結果不爲零,則返回。最後,比較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); 
}