2014-11-19 2 views
3

알파벳 순으로 정렬되도록 단어에 대한 포인터 배열을 정렬 할 수 있습니다. 문제는 정수 배열 (특정 단어가 사용 된 횟수)을 정렬해야 정수가 동일한 위치에 정렬된다는 것입니다. 각각의 단어로 :두 배열을 동시에 정렬하려면 qsort를 사용합니까?

내 코드 :

for (i = 0; i < numWords; i++) { 
    // prints out the words and their frequency respectively 
    printf("%s - %d\n", dictionary[i], frequency[i]); 
} 

//sorts the dictionary so that the words are 'alphabetical' 
qsort(dictionary, numWords, sizeof(char *), rstrcmp); 
printf("\nafter qsort\n"); //checkmark 

for (i = 0; i < numWords; i++) { 
    // prints the word list alphabetically, but the frequencies are no longer matched 
    printf("%s - %d\n", dictionary[i], frequency[i]); 
} 

... 비교 기능 V

int rstrcmp(const void *p1, const void *p2) { 
    return strcmp(*(char * const *)p1, *(char * const *)p2); 
} 
+1

이 이상적으로 당신이 해시 테이블 /지도를 사용할 수 있습니다 예를 들어

값과 그냥 키를 기반으로 정렬 .. – bwegs

+2

할 간단한 일은 단어/주파수 쌍을 저장하고 다음 sor를 구조체를 사용하는 것입니다 이러한 구조체의 배열. – Turix

+0

@Turix 나는 약간의 문제가 있을지 모르지만, 나는 포인터와 포인터를 잘 사용하지 않는다. 간신히 얻을, 구조체의 배열을 초기화하는 방법의 예를 보여주의합니까? – nobodyImportant

답변

9

간단한 일은 구조체를 사용하여 단어/주파수 쌍을 저장 한 다음이 구조체의 배열을 정렬하는 것입니다.그런 다음

struct WordFrequency 
{ 
    const char * word; 
    int frequency; 
} wordFreqs[numWords];  // Assumes numWords is static/global and constant... 

:

for (i = 0; i < numWords; i++) { 
    printf("%s - %d\n", dictionary[i], frequency[i]); 
    wordFreqs[i].word = dictionary[i]; 
    wordFreqs[i].frequency = frequency[i]; 
} 

//sorts the dictionary so that the words are 'alphabetical' 
qsort(wordFreqs, numWords, sizeof(struct WordFrequency), wfcmp); 

for (i = 0; i < numWords; i++) { 
    printf("%s - %d\n", wordFreqs[i].word, wordFreqs[i].frequency); 
} 

그리고 : 단어가 핵심 주파수가 어디

int wfcmp(const void *p1, const void *p2) { 
    return strcmp(((const struct WordFrequency *)p1)->word, ((const struct WordFrequency *)p2)->word); 
} 
3

직접 원하는대로 표준 qsort() 기능을 할 수 없습니다. 다른 모든 것들은 병렬로 정렬 할 두 개의 배열을 어떻게 알 수 있습니까?

데이터 구조를 변경 (구조 유형의 배열 사용)하거나 고유 한 정렬 기능을 작성해야합니다. 둘 중 데이터 구조를 변경하는 것이 더 쉽습니다.

또 다른 옵션이 있습니다. 그러나 다소 휘어진 것입니다. 당신은 항목이 int의 배열을 만들 수 있도록 :

for (int i = 0; i < N; i++) 
    index[i] = i; 

당신은 다음 두 배열의 기본 주소를 알고 비교기와 함께, 정렬 기능이 배열을 전달합니다. qsort() 함수는 배열의 데이터를 변환합니다. 비교기는 다른 배열의 데이터를 봅니다. 다른 두 배열은 전역 (파일 범위 이상) 변수이거나 두 배열의 기본 주소로 초기화 할 수있는 포인터 인 전역 변수가 필요합니다.

정렬 한 후에는 array1[index[i]]array2[index[i]]가 정렬 된 배열의 i 번째 요소에 액세스하는 데 사용할 수 있습니다.

또 다른 옵션 당신은 BSD에 있다면 : 당신이 qsort_r() 기능을 사용할 수 있습니다

void qsort_r(void *base, size_t nel, size_t width, void *thunk, 
       int (*compar)(void *, const void *, const void *)); 

는 '했겠'첫 번째 인수로 비교기에 전달있어 포인터입니다. 이것을 인덱스 배열 스키마와 함께 사용하여 두 배열에 대한 포인터를 비교 자로 전달할 수 있으므로 파일 범위 변수가 전혀 필요하지 않습니다. 하지만 두 개의 독립적 인 스왑을 수행 할 수는 없으므로 색인 배열 체계를 사용해야합니다.

+0

GNU 시스템의 경우, 다른 프로토 타입으로'void qsort_r (void *, size_t, size_t, int (*) (const void *, const void *, void *), void * arg); – mafso

+1

@mafso : 흥미 롭습니다. 일관성 - 누가 일관성이 필요합니까? –

+2

FYI (나는보아야 만했다.) : GNU 버전이 단지 하나의 기능 만 구현할 필요가있는 것처럼 보인다 (cf. glibc [메일 링리스트] (https://sourceware.org/ml/libc-alpha/2008- 12/msg00007.html)) 및 ... 때문에, [일부 저작권 이유] (https://sourceware.org/ml/libc-alpha/2008-12/msg00006.html) (??). 아, 그리고 완성도를 위해 Microsoft CRT와 C11 Annex K는'qsort_s'를 지정합니다. 컨텍스트 포인터를 전자의 compare 함수와 후자의 compare 함수의 첫 번째 인수로 사용하는 것이 좋습니다. 당신 말이 맞습니다. 아무도 일관성을 필요로하지 않습니다! – mafso

2

병렬 배열을 정렬하는 데 유용한 한 가지 방법은 다음과 같습니다. 정수 배열 (정확히는 size_t)을 만들고 0 - numWords-1 값으로 초기화합니다. 그런 다음 qsort 배열은 비교 함수를 사용하여 strcmp(dictionary[*(int *)p1], dictionary[*(int *)p2]을 수행 한 다음 정렬 된 배열의 인덱스를 사용하여 dictionaryfrequency을 동시에 바꿉니다 (이 작업은 복사 또는 스왑을 통해 쉽게 수행 할 수 있습니다. here은 후자의 예입니다).

Turix는 아마도 더 나은 해결책을 가지고 있습니다. 두 개의 배열 대신 구조체의 배열을 사용하면 전체적인 문제를 피할 수 있습니다.

+0

내부 대체 스와핑 알고리즘에 대한 외부 참조는 +1입니다. –

+0

@hobbs 로컬 문자열 배열에 액세스 할 qsort에 사용 된 함수 정의를 표시 할 수 있습니까? –

관련 문제