[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

Re: [FWP] sorting text in human-order



Ian Phillipps <igp_list2@tesco.net> writes:

> On Thu, 30 Nov 2000 at 12:09:40 +0000, Piers Cawley wrote:
> > Ian Phillipps <igp_list2@tesco.net> writes:
> 
> > > 	s/\d+/ "\01".pack 'w',$& /ge
> > > where the "\01" serves to place the numbers before the sort; put in a
> > > big character to sort later.
> 
> > I have the distinct recollection that BER numbers didn't sort
> > correctly under ASCII. However, I may be completely and utterly mad.
> 
> The sanity is yours. As part of my road back to the light, here's an
> idea which (if I'm right this time) sorts all numbers up to 10E10-1
> correctly:
> 
> 	s/\d+/ length($&).$& /eg

Hmm... how about:

    sub convert {
        my $num = shift;
        my $tail = to_vec($num);
        return to_vec(length $tail) . $tail;
    }

    sub to_vec {
        my $num = shift;
        my @vec;
        
        do {
            push(@vec, pack("N",$num % 32));
            $num >>= 32;
        } while $num;

        my $vec = join '', reverse @vec;

        # Trim leading nulls
        $vec =~ s/^\0*(.+)$/$1/; 
        return $vec;
    }

    s/(\d+)/convert($1)/eg

I *think* that has no limits at all, beyond limitations in perl's
internal representation of integers. Actually, if we use binary coded
decimals we can probably get 'round that by always treating the
numbers as character strings:

    sub to_vec {
        my $num = shift;
        my @vec;

        do {
            $b = pack("C", chop $num);
            $a = pack("C", chop $num);
            push @vec, $a << 4 | $b;
        } while $num;
        return join '', reverse @vec;
    }

That should be limited by the possible length of a string and that's
it. But it won't be anything that could easily be described as
'quick'. 

-- 
Piers



==== Want to unsubscribe from Fun With Perl?  Well, if you insist...
==== Send email to <fwp-request@technofile.org> with message _body_
====   unsubscribe