The Svin Совершенно с Вами согласен (по поводу Дундука) ну вот.... как что - сразу обижатся. Чем вам не угодило программирование на Asmе? Ну разве так можно? Никто ваши тексты не заменял. Просто немного сдвинули систему отсчёта. И потом завтра вы и не заметите что тут что-то было. С первым апреля Вас )) Улыбнитесь
Не самое оптимальное решение, сложность N*log(N). Требует 8 проходов по исходным данным и возможность делать realloc для результирующего массива. Какие у кого идеи по поводу оптимизации будут? Код (Text): <?php function find(&$b,$s,$e,$v) { if($s==$e) return $s; $m=intval(($s+$e)/2); if($b[1+2*$m]>=$v) return find($b,$s,$m,$v); else return find($b,$m+1,$e,$v); } function calc1(&$a,&$b,$s) { //для каждого слова массива A ищем в массиве B ключ, учитывая только биты 31..(S+5) //и делаем пометку в соседнем слове, что нужно добавить ключ у которого первые биты V[31..S] foreach($a as $v) { $i=find($b,0,$b[0],$v); $b[1+$i*2+1]|=1<<(($v>>$s)&31); } $o=$b[0]; //Вычисляем новую длину массива статистики $n=0; for($i=0;$i<$o;$i++) { for($j=0;$j<32;$j++) $n+=($b[1+2*$i+1]>>$j)&1; } $k=$n; //А здесь расширяем массив B, записывая в него удлинённые на 5 бит ключи for($i=$o;--$i>=0;) { for($j=32;--$j>=0;) if($b[1+2*$i+1]&(1<<$j)) { --$k; $b[1+2*$k]=($b[1+2*$i]&-(1<<($s+5)))|($j<<$s)|((1<<$s)-1); $b[1+2*$k+1]=0; } } $b[0]=$n; } function calc(&$a) { $b=Array(1,0xFFFFFFFF,0); calc1($a,$b,30); calc1($a,$b,25); calc1($a,$b,20); calc1($a,$b,15); calc1($a,$b,10); calc1($a,$b,5); calc1($a,$b,0); foreach($a as $v) ++$b[1+2*find($b,0,$b[0],$v)+1]; return $b; } $a=Array(); for($i=0;$i<0x10;$i++) $a[$i]=rand(0,0xF)<<28; $b=calc($a); foreach($a as $v) echo("$v<br>"); echo("<br>"); for($i=0;$i<$b[0];$i++) echo("{$b[1+2*$i]} {$b[1+2*$i+1]}<br>"); ?>