qsort() 通过给它一个 N 项的线性列表来唱歌,其中任何给定的 item(n) 地址都可以使用基于地址 + 每个“item”的大小来计算。所以从一些简单的东西开始,我所说的简单是指一个指针列表。
首先,可以通过简单地将副本拼接到原始缓冲区来模拟缓冲区的循环性(理想情况下少一个字符,但我不会对一个字节争论不休)。IE
"qwer" ==> "qwerqwer"
这可以通过以下方式完成:
char *buff = malloc(2 * blocksize);
memcpy(buff, to_sort, blocksize);
memcpy(buff+blocksize, to_sort, blocksize);
现在你有偏移量 0..(blocksize-1),每个都是一个块大小的字符,可以在没有任何特殊指针数学的情况下相互比较。
接下来,构建要实际排序的指针列表,在这种情况下,
char** ptrs = malloc(sizeof(char*) * blocksize);
for (i=0;i<blocksize;i++)
ptrs[i] = buff+i;
接下来,一个比较两个“项目”的函数。我们通过地址传递给我们的项目是指向字符串的指针。同样,过去左右的地址是内存位置,我们将找到两个 char *。地址本身不是char *:
int block_compare(const void *left, const void *right)
{
// memcmp would work for most platforms, but not all, so...
return strncmp(*(char **)left, *(char **)right, blocksize);
}
最后,将其发送到 qsort() ,如下所示:
qsort(ptrs, blocksize, sizeof(char*), block_compare);
最终输出将是一个块大小的指针列表,指向制造的循环缓冲区,每个指针都引用一个块大小的块。上述所有内容的全文如下:
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
size_t blocksize = 0;
int block_compare(const void *left, const void *right)
{
// memcmp would work for most platforms, but not all, so...
return strncmp(*(char **)left, *(char **)right, blocksize);
}
int main(int argc, char* argv[])
{
char to_sort[] = "qwer";
size_t i = 0;
// set blockize
blocksize = strlen(to_sort);
char *buff = malloc(2 * blocksize);
memcpy(buff, to_sort, blocksize);
memcpy(buff+blocksize, to_sort, blocksize);
char ** ptrs = malloc(blocksize * sizeof(char*));
for (i=0;i<blocksize;++i)
ptrs[i] = buff+i;
// now send the pointer list to qsort()
qsort(ptrs, blocksize, sizeof(*ptrs), block_compare);
// ptrs is sorted. do with it what you will.
for (i=0;i<blocksize;i++)
{
fwrite(ptrs[i], sizeof(char), blocksize, stdout);
fwrite("\n", sizeof(char), 1, stdout);
}
fflush(stdout);
free(ptrs);
free(buff);
return EXIT_SUCCESS;
}
使用“qwer”会产生:
erqw
qwer
rqwe
werq
另一个示例,使用“asubstantiallylongerstringtest”
allylongerstringtestasubstanti
antiallylongerstringtestasubst
asubstantiallylongerstringtest
bstantiallylongerstringtestasu
erstringtestasubstantiallylong
estasubstantiallylongerstringt
gerstringtestasubstantiallylon
gtestasubstantiallylongerstrin
iallylongerstringtestasubstant
ingtestasubstantiallylongerstr
llylongerstringtestasubstantia
longerstringtestasubstantially
lylongerstringtestasubstantial
ngerstringtestasubstantiallylo
ngtestasubstantiallylongerstri
ntiallylongerstringtestasubsta
ongerstringtestasubstantiallyl
ringtestasubstantiallylongerst
rstringtestasubstantiallylonge
stantiallylongerstringtestasub
stasubstantiallylongerstringte
stringtestasubstantiallylonger
substantiallylongerstringtesta
tantiallylongerstringtestasubs
tasubstantiallylongerstringtes
testasubstantiallylongerstring
tiallylongerstringtestasubstan
tringtestasubstantiallylongers
ubstantiallylongerstringtestas
ylongerstringtestasubstantiall
伙计,我希望这就是你要找的。(哇)。