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

I have a problem. I try myself in writing it but its not succeed. It is because i am a new user of Perl. Can anyone who can teach me how to solve this problem in a detail way because i am a new user and therefore i do not know some of the complicated method to solve the problem. Simple but slow or long method is fine for me. thanks SweetCandy
  • Comment on How to find the most frequent in a file?

Replies are listed 'Best First'.
Re: How to find the most frequent in a file?
by runrig (Abbot) on Jan 29, 2003 at 01:11 UTC
    I try myself in writing it but its not succeed

    Show us what you have written and how it does not work. We don't just do your homework for you.

      #! /usr/local/bin/perl -w use strict ; my $file = $ARGV[0] ; open TEXT, "<$file"; my %frequency = () ; while ( my $line = <TEXT> ) { my(@words) = split /\W/, $line ; foreach my $word ( @words ) { $frequency{$word} = $frequency{$word} + 1 ; } } foreach my $word ( keys %frequency ) { my $count = $frequency{$word} ; print "$word\t\t$count\n"; }
      this is what i write. but i dunno how to made it into finding the most frequent word.

      Added code tags - dvergin 2003-01-28

        Three comments on what you have already (which is 90% of the way there).

        In your split, you can avoid getting blank matches by using \W+ instead of \W. This will match a sequence of non-word characters instead of matching each and will keep your code from getting an empty string between consecutive non-word characters in the input text.

        When you increment the entry in the hash, use $frequency{$word}++; instead of $frequency{$word} = $frequency{$word} + 1 ; which gives warnings about using uninitialized values the first time any word is seen.

        Since you are going through the entire hash and collecting both keys and values, you could use each instead of keys to get them both at once.

        To finish this off, all you need to do is to keep track of the highest count seen while in the last loop.

        #! /usr/local/bin/perl -w use strict; my $file = $ARGV[0]; open TEXT, "<$file"; my %frequency = (); while ( my $line = <TEXT> ) { my(@words) = split /\W+/, $line ; foreach my $word ( @words ) { $frequency{$word}++; } } my @most; my $cnt; while (my ($word,$freq) = each %frequency ) { if (! @most) { push @most,$word; $cnt = $freq; next; } next if $cnt > $freq; if ($cnt == $freq) { push @most,$word; } else { @most = ($word); $cnt = $freq; } } if (@most == 0) { print "No words in $file\n"; } elsif (@most == 1) { print "'$most[0]' occurred $cnt times\n"; } else { print "The following words each appeared $cnt times\n@most\n"; }

        An alternative would be to perform a Schwartzian Transform.

        --- print map { my ($m)=1<<hex($_)&11?' ':''; $m.=substr('AHJPacehklnorstu',hex($_),1) } split //,'2fde0abe76c36c914586c';