#!/usr/bin/perl -w # 演算法: radix sort # 作者: 洪朝貴 http://www.cyut.edu.tw/~ckhung # 授權: public domain (但如果您要將我的程式改寫成有用的大程式, # 強烈建議將您的版本施以 GPL) use Getopt::Std; use strict; my (%opts) = ( d => 3, # number of digits in each input value r => 10, # radix n => 8, # number of input values e => "ansi",# type of emphasis, either "ansi" or "html" ); getopts('d:e:n:r:', \%opts); my ($ES) = { ansi => { pre=>"\x1b[7m", post=>"\x1b[m", nl=>"\n" }, html => { pre=>"", post=>"", nl=>"

\n" }, }; sub ord2chr { return chr($_[0] + ord($_[0]<10 ? '0' : 'A')); } sub cntsort { my ($A, $wd) = @_; my ($B, $C, $i); $#$B = $#$A; $C->[0] = 0; foreach $i (@$A) { ++$C->[$i->[$wd]]; } for ($i=1; $i<$opts{r}; ++$i) { $C->[$i]+=$C->[$i-1]; } foreach $i (reverse @$A) { $B->[--$C->[$i->[$wd]]] = $i; } return $B; } sub print_array { my ($A, $emph) = @_; my ($x, $d); # prefix and postfix of emphasis strings if (not exists $ES->{$opts{e}} ) { $opts{e} = "ansi"; warn "-e must be followed by one of ", join(",",keys %$ES), "; assuming '-e ansi' now\n"; } foreach $x (@$A) { print " "; for ($d=0; $d<$opts{d}; ++$d) { if (defined $emph and $d == $emph) { print $ES->{$opts{e}}{pre}, ord2chr($x->[$d]), $ES->{$opts{e}}{post}; } else { print ord2chr($x->[$d]); } } } print $ES->{$opts{e}}{nl}; } my ($A, $x, $d); # 如果要測試自己設計出來的資料, 請: # 1. 更改下句陣列內容 # 2. 將 「*** 用亂數產生測試資料 ***」 註解下面那一句註解掉 $A = [ qw(326 506 496 583 625 320 531 406 491) ]; foreach $x (@$A) { $x = [ map { $_ le "9" ? $_ : $_ le "Z" ? ord($_)-ord("A")+10 : ord($_)-ord("a")+10 } split(//, $x) ]; } # *** 用亂數產生測試資料 *** $A = [ map { [map { int(rand()*$opts{r}) } 1..$opts{d}] } 1..$opts{n} ]; print_array($A); for ($d=$opts{d}-1; $d>=0; --$d) { print $ES->{$opts{e}}{nl} x 2; print_array($A, $d); $A = cntsort($A, $d); print_array($A, $d); }