2014-01-24 44 views
1

我在C編程。我有一個結構數組。我需要基於結構的元素以排序順序打印數組。卡住的主要問題是我不想修改原始數組。數組的排序

例如: 我的數組是proctab [10]。 這是名爲pentry的結構數組。

struct pentry 
{ 
    int a; 
    int b; 
    char c; 
} 

我需要打印如下:

a = 1, b = 2, c = a 
a = 2, b = 1, c = d 
a = 3, b = 0, c = e 
a = 4, b = 1, c = a 
a = 4, b = 2, c = a 

等.. 即結果上的排序。但是如果a對於數組中的兩個結構具有相同的值,則數組也應該在b上排序。我想要原始數組proctab保持不變。

有沒有辦法做到這一點?

+0

如果有幫助,我知道在Java中你只是讓對象實現「Comparable」並實現'compareTo' - 我確定C中有類似的東西嗎? [這個問題](http://stackoverflow.com/questions/8838800/c-determine-if-class-is-comparable)似乎是相關的,也許它是有用的? – Krease

+2

製作副本('malloc','memcpy'),然後對副本('qsort')進行排序? – Heinzi

+0

string.h中的memcpy和stdlib.h中的qsort將解決您的問題。 – jfly

回答

2

爲了不影響原始數組搞亂對項目進行排序,創建引用的第二個數組:

struct pentry plist[]= { { 1, 2, 'a' }, { 4, 8, 'z' }, { 2, 7, 'c' }, { 2, 1, 'e' }, { 5, 6, 'b' } ; 
struct pentry (* pref)[5] ; 

int compare(const struct pentry ** px, const struct pentry ** py) 
{ 
    return ((** px).a == (** py).a) ? ((** py).b - (** px).a) : ((** py).a - (** px).a) ; 
} 

void dosort(struct pentry ** zdest, struct pentry * asrc, int n) 
{ 
    int i ; 
    struct pentry ** fill ; 

    for (i= n, fill= zdest ; (i --) ;) { *(fill ++)= asrC++ ; } 
    qsort(zdest, n, sizeof(* zdest), compare) ; 
} 

void show_sorted(struct pentry ** aref, int n) 
{ 
    while (n --) 
    { 
    printf("%d %d %c\n", (** aref).a, (** aref).b, (** aref).c) ; 
    ++ aref ; 
    } 
} 

int main() 
{ 
    dosort(pref, plist, sizeof(plist)/sizeof(* plist)) ; 
    show_sorted(pref, sizeof(plist)/sizeof(* plist)) ; 
    return 0 ; 
} 
4

您可以使用qsort

編輯爲包括對OP問題的更改。

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

typedef struct tagPentry 
{ 
    int a, b; 
    char c; 
} pentry; 

/* Function used to compare the structs via qsort in 
the main() method */ 
int compare(const void *a, const void *b) 
{ 
    pentry* p_a = (pentry*)a; 
    pentry* p_b = (pentry*)b; 

    /* Here, the compare function sorts based on the value of a 
    If p_a.a == p_b.a, then it will also sort by b*/ 
    if (p_a->a < p_b->a) 
     return -1; 
    if (p_a->a > p_b->a) 
     return 1; 
    else /* a is equal, so compare b */ 
    { 
     if (p_a->b < p_b->b) 
      return -1; 
     if (p_a->b > p_b->b) 
      return 1; 
     return 0; 
    } 
} 

int main(int argc, char** argv) 
{ 
    /* Original array */ 
    pentry p[5]; 
    p[0].a = 1; p[0].b = 2; p[0].c = 'a'; 
    p[1].a = 4; p[1].b = 8; p[1].c = 'z'; 
    p[2].a = 2; p[2].b = 7; p[2].c = 'c'; 
    p[3].a = 2; p[3].b = 1; p[3].c = 'e'; 
    p[4].a = 5; p[4].b = 6; p[4].c = 'b'; 

    /* Temp array for output */ 
    pentry ptemp[5]; 
    memcpy(ptemp, p, sizeof p); 

    /* Sort temp array */ 
    qsort(ptemp, 5, sizeof(pentry), compare); 

    /* Print output */ 
    for (int i = 0; i < 5; ++i) 
    { 
     printf("%d %d %c\n", ptemp[i].a, ptemp[i].b, ptemp[i].c); 
    } 

    return 0; 
} 

比較功能取決於結構內的數據的比較返回一個整數。在這個例子中,你可以簡單地減去每個結構的pentry.a值,以確定哪個值更低。由於我們想要比較pentry.b,如果兩個結構相同,且僅當pentry.a相同,我們使用條件if語句在必要時比較pentry.b值。

+0

我修改了一下這個問題,能否詳細說明一下?謝謝 –

+1

@ayushi當然,改變了。 – Inisheer

+0

儘管OP所提供的具體樣本數據並不是問題,但如果結構的成員被重視,則比較器通孔扣除會導致下溢(或溢出)。例如:「INT_MIN/2」和「INT_MAX/2 + 2」,或者「INT_MIN」和任何正數等等。出於這個原因,建議*不要*使用捷徑減法,而是使用真正的邏輯比較,強制一個嚴格的弱順序,並返回-1,0或1.更好地開始習慣,而不是後來發現缺陷。 – WhozCraig

1

,是希望你知道排序一個簡單的整數數組,

做出採取兩種結構的功能和自己的標準判斷哪個是最大的,或者換句話說應該是第一位的不是遍歷結構陣列以下碼,

if(priorityof(arr[j],arr[j+1]) ==0) 
SWAP 

你的函數應返回零,如果他們需要更換,否則返回1