Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello!
I have a string, eg:
$my_string="CCCAAAAACCCAAAAAAACCCCBBBCCAAACCBBACBBAAAAAAAAAAACAAAAAAAA +AA";

I want to find out which letter (A, B or C) is the most abundant in the string.
I can go the classic way, ie count how many 'A', 'B' and 'C' I have and then compare each number to the other two and see which one is bigger, but I was wondering if there is a quicker way that would save me a number of lines in my program.

Replies are listed 'Best First'.
Re: Quick way to find the letter with the most occurences in a string
by Marshall (Canon) on May 19, 2010 at 17:14 UTC
    With a problem like this where you know the 3 possibilities, tr is usually the way to go for speed. Splitting and making hashes and such will usually be slower than 3 very fast trips through the string. "save me a number of lines" would normally be the last thing I would be thinking about, ranking way below: clarity, speed, memory usage. Its hard to argue with clearly written fast code.
    #!/usr/bin/perl -w use strict; my $string="CCCAAAAACCCAAAAAAACCCCBBBCCAAACCBBACBBAAAAAAAAAAACAAAAAAAA +AA"; my $nA = $string =~ tr/A//; my $nB = $string =~ tr/B//; my $nC = $string =~ tr/C//; print "A=$nA B=$nB C=$nC"; #A=37 B=7 C=16 #compare these 3 as you will to handle cases like #all are the same, etc
Re: Quick way to find the letter with the most occurences in a string
by kennethk (Abbot) on May 19, 2010 at 16:36 UTC

    What have you tried? We generally appreciate a show-of-effort here - see How do I post a question effectively?.

    There is no way to determine the most frequent letter without counting and comparing, and brevity of source code is generally not a good goal in and of itself (unless you are golfing).

    That said, one way (TIMTOWTDI) to accomplish the counting with very little code is using inline Foreach Loops and split with a hash. You can then use sort with the numerical comparison operator (<=>) to find the key with the maximum value:

    my $my_string="CCCAAAAACCCAAAAAAACCCCBBBCCAAACCBBACBBAAAAAAAAAAACAAAAA +AAAAA"; my %count; $count{$_}++ foreach split //, $my_string; print Dumper \%count; print my ($most_common) = sort {$count{$b} <=> $count{$a}} keys %count +;
      Modified to handle cases with several characters with the maximal number of occurences:
      my %count; $count{$_}++ foreach split //,$string; my $max = (sort {$a<=>$b} values %count)[-1]; print $max,' ',grep $count{$_} == $max,keys %count;
Re: Quick way to find the letter with the most occurences in a string
by JavaFan (Canon) on May 19, 2010 at 16:26 UTC
    Untested:
    use List::Util 'reduce'; use 5.010; my %hash; $hash{$_}++ for split //, $my_string; say "Most frequent: ", reduce {$hash{$a} > $hash{$b} ? $a : $b} keys % +hash;
      If there are several characters with most occurences, this code will report just one of them.
        this code will report just one of them
        Indeed. As specified. Notice the title: ...find the letter.... It did not say ...find the letters....
Re: Quick way to find the letter with the most occurences in a string
by wanna_code_perl (Friar) on May 19, 2010 at 16:43 UTC

    You have to count, unless you're OK with an approximation.

    print chr(rand(3)+65);

    It's short, runs in constant time, and is right 1/3 of the time. :-)