使用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]); }
…比较functionV.
int rstrcmp(const void *p1, const void *p2) { return strcmp(*(char * const *)p1, *(char * const *)p2); }
一个简单的事情是使用结构来存储字/频率对,然后对这些结构的数组进行排序。
例如:
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); }
标准qsort()
函数无法直接执行。 除此之外,它如何知道(或者你怎么告诉它)哪两个数组并行排序?
您要么必须更改数据结构(使用结构类型的数组),要么必须编写自己的排序函数。 在这两者中,更改数据结构可能更容易。
还有另一种选择 – 但有点扭曲。 您可以使用以下条目创建一个int
数组:
for (int i = 0; i < N; i++) index[i] = i;
然后,您将此数组与一个知道两个数组的基址的比较器一起传递给sort函数。 qsort()
函数置换数组中的数据; 比较器查看其他数组中的数据。 另外两个数组必须是全局(至少是文件范围)变量,或者您需要全局变量,这些变量是可以使用两个数组的基地址初始化的指针。
排序后,您可以使用array1[index[i]]
和array2[index[i]]
来访问已排序数组的第 i
个元素。
如果您使用的是另一个选项:您可以使用qsort_r()
函数:
void qsort_r(void *base, size_t nel, size_t width, void *thunk, int (*compar)(void *, const void *, const void *));
'thunk'是一个指针,作为第一个参数传递给比较器。 您可以将此与索引数组方案一起使用,将指针传递给比较器中的两个数组,因此您根本不需要文件范围变量。 但是,您仍然无法进行两次独立交换,因此您必须使用索引数组方案。
您可能会发现一种对并行数组进行排序有用的方法:创建一个整数数组( size_t
s严格正确)并使用值0到numWords-1
初始化它。 然后使用执行strcmp(dictionary[*(int *)p1], dictionary[*(int *)p2]
的比较函数对该数组进行qsort
,然后使用排序的索引数组同时置换dictionary
和frequency
(这很容易通过复制来完成,或者用交换就地不那么容易完成: 这是后者的一个例子。
Turix可能有更好的解决方案 – 使用结构数组而不是两个数组避免了整个问题。