vinoth.ree has asked for the wisdom of the Perl Monks concerning the following question:

I was doing insertion sort and I was facing a problem, in the below code I used the 'lt' instead of '<' in for loop So I did not get the output properly, in this array first two elements 8 and 5 getting swapped and the for loop not proceed further When I used the '<' symbol in for its working fine but my question is for while loop this 'gt' working fine why not for?

use Data::Dumper; my ($i,$n,$j,@a,$temp); @a=(8,5,2,4,88,1,5,4,3,2); $n=10; for ($i=1; $i lt $n; $i++){ # print $i; $j=$i; $temp=$a[$j]; while ($j gt 0 and $a[$j-1] gt $temp) { $a[$j]=$a[$j-1]; $j--; } $a[$j]=$temp; } print Dumper(\@a);
Vinoth,G

Replies are listed 'Best First'.
Re: Insertion sort in perl
by almut (Canon) on Apr 25, 2009 at 11:07 UTC

    ...because in a string comparison, '2' is not less than '10'  (comparison happens character-wise, and '2' is not smaller than '1' (ascii-betically))

    my $n = 10; for my $i (1..$n) { printf "'%s lt %s' is %s\n", $i, $n, $i lt $n ? "true":"false"; } __END__ '1 lt 10' is true '2 lt 10' is false '3 lt 10' is false '4 lt 10' is false '5 lt 10' is false '6 lt 10' is false '7 lt 10' is false '8 lt 10' is false '9 lt 10' is false '10 lt 10' is false

    (Tip: change $n to 11 in the above snippet and note that '10 lt 11' is true in contrast to most others...)

      And as an example of the two different types of ordering (i.e., the default lexicographic-ascending of sort vs. numeric ascending), consider:
      >perl -wMstrict -le "my @unsorted = (1, 10, 100, 11, 9, 3, 5, 2); my @lexic_sorted = sort @unsorted; print qq{@lexic_sorted}; my @numeric_sorted = sort { $a <=> $b } @unsorted; print qq{@numeric_sorted}; " 1 10 100 11 2 3 5 9 1 2 3 5 9 10 11 100
Re: Inertion sort in perl
by Marshall (Canon) on Apr 25, 2009 at 15:44 UTC
    First, Perl is not C or FORTAN or ASM.
    This kind of thing:
    for ($i=1; $i lt $n; $i++){....}
    is an extremely "rare duck" in Perl!
    These i-n (INteger) variables just aren't needed in most cases.

    Perl uses a variant of QuickSort and for almost all of your sorting, you should too! This is normally faster than SelectSort. Use the power of the language!

    Re-coding your program,

    @a = (8,5,2,4,88,1,5,4,3,2); @a = sort @a; #same as @a = sort{$a <=> $b}@a; #because only digits not alpha/digits print "@a","\n"; #prints: 1 2 2 3 4 4 5 5 8 88

      Close, but not entirely true:

      >perl -le "print for sort @ARGV" 1 10 2 20 1 10 2 20

      But with an explicit comparison, it works:

      >perl -le "print for sort{ $a <=> $b } @ARGV" 1 10 2 20 1 2 10 20
        Yes, we are on the same page here!
        Thanks for emphasizing the difference between ASCII vs numeric sort order!

        Corion is completely correct about this...there is a difference.

        I attach some code that I use for a GUI sort gizmo that doesn't know if it is sorting numbers or alpha-number strings. It uses normal string compare unless both items are strictly numeric and in that case, it uses the "spaceship" operator "<=>" for the compare.

        sub alpha_num_cmp { my($a, $b) = @_; if (( $a =~ m/\D/) || ($b =~ m/\D/) ) { #look for a non-digit return ($a cmp $b); #if so, then use string compare } return ($a <=> $b); #otherwise straight numeric comparison }
        Ok, a cut-n-paste goof...The above code was one level down in the GUI..Ooops!

        That code compares "columns" of similar things. Here is more code...

        #!usr/bin/perl -w use strict; my @a=(8,5,2,4,88,1,10,20,5,4,3,2); my @b = sort @a; print "alpha sort\n"; print "@b\n"; @b = sort {$a<=>$b}@a; print "numeric sort\n"; print "@b\n"; @b = sort alpha_num_cmp @a; print "an any sort\n"; print "@b\n"; sub alpha_num_cmp { if ( ( $a =~ m/\D/) || ($b =~ m/\D/) ) { #look for a non-digit return ($a cmp $b); #if so, then use string compare } return ($a <=> $b); #otherwise straight numeric comparison } __END__ prints: alpha sort 1 10 2 2 20 3 4 4 5 5 8 88 numeric sort 1 2 2 3 4 4 5 5 8 10 20 88 an any sort 1 2 2 3 4 4 5 5 8 10 20 88