使用qsort同时对两个数组进行排序?

时间:2014-11-19 03:50:56

标签: c arrays 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);
}

3 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分:3)

标准qsort()功能无法直接执行。 除此之外,它如何知道(或者你怎么告诉它)哪两个数组并行排序?

您必须更改数据结构(使用结构类型的数组),或者您必须编写自己的排序函数。在这两者中,更改数据结构可能更容易。

还有另一种选择 - 但有点扭曲。您可以使用以下条目创建int数组:

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

然后将此数组与一个知道两个数组的基地址的比较器一起传递给sort函数。 qsort()函数置换数组中的数据;比较器查看其他数组中的数据。其他两个数组必须是全局(至少是文件范围)变量,或者您需要全局变量,这些变量是可以使用两个数组的基地址初始化的指针。

排序后,您可以使用array1[index[i]]array2[index[i]]访问已排序数组的i th 元素。

如果您使用BSD,还有另外一个选择:您可以使用qsort_r()功能:

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

&#39; thunk&#39;是一个指针,作为第一个参数传递给比较器。您可以将其与索引数组方案一起使用,将指针传递给比较器中的两个数组,因此您根本不需要文件范围变量。但是,您仍然无法进行两次独立交换,因此您必须使用索引数组方案。

答案 2 :(得分:2)

您可能会发现一种对并行数组进行排序有用的方法:创建一个整数数组(size_t s严格正确)并使用值0到numWords-1初始化它。然后qsort该数组使用strcmp(dictionary[*(int *)p1], dictionary[*(int *)p2]的比较函数,然后使用排序的索引数组同时置换dictionaryfrequency(这很容易通过复制完成,或者使用互换进行一些不那么容易的实现:here是后者的一个例子。

Turix可能有更好的解决方案 - 使用结构数组而不是两个数组可以避免整个问题。