qsort() は、N 個のアイテムの線形リストを指定することで歌います。ここで、任意のアイテム (n) アドレスは、各「アイテム」のベース アドレス + サイズを使用して計算できます。簡単なものから始めましょう。簡単とは、ポインターのリストを意味します。
まず、バッファの循環性は、コピーを元のバッファに接合するだけでエミュレートできます (理想的には 1 文字未満ですが、1 バイトについては言いません)。いえ
"qwer" ==> "qwerqwer"
これは次の方法で実行できます。
char *buff = malloc(2 * blocksize);
memcpy(buff, to_sort, blocksize);
memcpy(buff+blocksize, to_sort, blocksize);
これで、オフセット 0..(blocksize-1) が得られました。それぞれが char のブロックサイズであり、特別なポインター計算なしで相互に比較できます。
次に、実際にソートするためのポインターのリストを作成します。この場合は、
char** ptrs = malloc(sizeof(char*) * blocksize);
for (i=0;i<blocksize;i++)
ptrs[i] = buff+i;
次に、2つの「アイテム」を比較する機能。アドレスによって渡される項目は、文字列へのポインターです。繰り返しますが、左と右のように過去のアドレスは、2 つの 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
「asubstantallylongerstringtest」を使用した別のサンプル
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
男私はそれがあなたが探していたものであることを願っています. (うわー)。