#include int main(void) { int strnum; //Počet řetězců int alpha; //Počet znaků v abecedě int* str[strnum]; //Pole řetězců (řetězce uvažujeme abstraktně, takže jsou z čísel) int len[strnum]; //Pole délek řetězců //Řekněme, že nám obsahy těchto čtyř proměnných někdo naplní (a udělá to správně :) ) int lensum = 0,maxlen = 0; //součet délek řetězců, délka nejdelšího for(int i = 0; i < strnum; i++) { lensum += strlen[i]; if(maxlen < len[i]) maxlen = len[i]; } //Teď si roztřídíme řetězce podle jejich délky int lencnt[maxlen + 2], lens[maxlen + 2]; //mapování přihrádek, přihrádky for(int i = 0; i <= maxlen; i++) //inicializace lencnt[i] = 0; lencnt[maxlen + 1] = strnum; // <- trik pro zjednodušení dalšího počítání for(int i = 0; i < strnum; i++) lencnt[len[i]]++; for(int i = 1; i <= maxlen; i++) lencnt[i] += lencnt[i-1]; for(int i=0; i < strnum; i++) { lencnt[len[i]]--; lens[lencnt[len[i]]]=i; } int _bucks[alpha + 1]; //Mapovací pole přihrádek - aktuální int _prevbucks[alpha + 1]; //Mapovací pole přihrádek - předchozí int _bstr[strnum], _prevbstr[strnum]; // Přihrádky - opět aktuální a předchozí int *bucks = _bucks; //tohle nám pomůže, int *prevbucks = _prevbucks; //abychom mohli aktuální a předchozí int *bstr = _bstr, *prevbstr = _prevbstr; //snadno zaměňovat for(int i = 0; i <= alpha; i++) bucks[i] = 0; for(int i = maxlen; i>0; i--) { int *tmp; tmp = bucks; bucks = prevbucks; prevbucks = tmp; //zaměníme mapovací pole tmp = bstr; bstr = prevbstr; prevbstr = tmp; //a přihrádky for(int j = 0; j <= alpha; j++) bucks[j] = 0; for(int j = 0; j < prevbucks[alpha]; j++) //napočítáme, kolik bude v bucks[str[prevbstr[j]][i - 1]]++; //přihrádkách řetězců z předchozího třídění for(int j = lencnt[i]; j < lencnt[i + 1]; j++) //a ještě připočteme bucks[str[lens[j]][i - 1]]++; //řetězce délky i for(int j = 1; j < alpha; j++) bucks[j] += bucks[j - 1]; bucks[alpha] = bucks[alpha - 1]; //opět oblíbený trik for(int j = 0; j < alpha; j++) for(int k=prevbucks[j + 1] - 1; k >= prevbucks[j]; k--) //Abychom zachovali uspořádání z předchozího třídění u těch řetězců, které skončí ve stejné přihrádce, musíme je //procházet odzadu, stejně jako se odzadu přidávájí; protože se přihrádky plní odzadu int c = str[prevbstr[k]][i - 1]; //roztřídíme do nich nejprve řetězce bucks[c]--; //z předchozího třídění, protože jsou bstr[bucks[c]] = prevbstr[k]; //delší než i } for(int j = lencnt[i]; j < lencnt[i + 1]; j++) { int c = str[lens[j]][i - 1]; //A teď můžeme do předních částí přihrádek bucks[c]--; // Dát řetězce délky i bstr[bucks[c]] = lens[j]; } } //Vypíšeme výsledek, aby to vypadalo, že jsme opravdu něco udělali... for(int i = lencnt[0]; i < lencnt[1]; i++) //všechny prázdné řetězce přijdou printf("\n"); //na začátek (ani jsme je netřídili) for(int k = 0; k < bucks[alpha]; k++) { //a teď vypíšeme ty neprázdné for(int i = 0; i < len[bstr[k]]; i++) printf("%d ",str[bstr[k]][i]); printf("\n"); } return 0; }