Как это можно сделать более perl способом - PullRequest
5 голосов
/ 09 октября 2011

Я новичок в Perl, и для одной из моих домашних заданий я придумал такое решение:

#wordcount.pl FILE 
    # 

    #if no filename is given, print help and exit 
    if (length($ARGV[0]) < 1) 
    { 
           print "Usage is : words.pl word filename\n"; 
           exit; 
    } 

   my $file = $ARGV[0];          #filename given in commandline 

   open(FILE, $file);            #open the mentioned filename 
   while(<FILE>)                 #continue reading until the file ends 
    { 
           chomp; 
           tr/A-Z/a-z/;          #convert all upper case words to lower case 
           tr/.,:;!?"(){}//d;            #remove some common punctuation symbols 
           #We are creating a hash with the word as the key.  
           #Each time a word is encountered, its hash is incremented by 1. 
           #If the count for a word is 1, it is a new distinct word. 
           #We keep track of the number of words parsed so far. 
           #We also keep track of the no. of words of a particular length.  

          foreach $wd (split) 
          { 
                $count{$wd}++; 
                if ($count{$wd} == 1) 
                 { 
                       $dcount++; 
                 } 
                $wcount++; 
                $lcount{length($wd)}++; 
          } 
   } 

   #To print the distinct words and their frequency,  
   #we iterate over the hash containing the words and their count. 
   print "\nThe words and their frequency in the text is:\n"; 
   foreach $w (sort keys%count) 
   { 
         print "$w : $count{$w}\n"; 
   } 

   #For the word length and frequency we use the word length hash 
   print "The word length and frequency in the given text is:\n"; 
   foreach $w (sort keys%lcount) 
   { 
         print "$w : $lcount{$w}\n"; 
   } 

   print "There are $wcount words in the file.\n"; 
   print "There are $dcount distinct words in the file.\n"; 

   $ttratio = ($dcount/$wcount)*100;       #Calculating the type-token ratio. 

   print "The type-token ratio of the file is $ttratio.\n"; 

Я включил комментарий, чтобы упомянуть, что он делает. На самом деле я должен найти количество слов из данного текстового файла. Вывод вышеуказанной программы будет выглядеть так:

The words and their frequency in the text is: 
1949 : 1
a : 1
adopt : 1
all : 2
among : 1
and : 8
assembly : 1
assuring : 1
belief : 1
citizens : 1
constituent : 1
constitute : 1
.
.
.
The word length and frequency in the given text is:
1 : 1
10 : 5
11 : 2
12 : 2
2 : 15
3 : 18
There are 85 words in the file. 
There are 61 distinct words in the file. 
The type-token ratio of the file is 71.7647058823529. 

Несмотря на то, что с помощью Google я могу найти решение для моей домашней работы. Но, тем не менее, я думаю, что будет меньший и лаконичный код, использующий реальную силу Perl. Кто-нибудь может дать мне решение на Perl с гораздо меньшим количеством строк кода?

Ответы [ 2 ]

9 голосов
/ 09 октября 2011

Вот несколько предложений:

  • Включите use strict и use warnings в ваши скрипты Perl.

  • Проверка вашего аргумента отсутствует 't тестирование того, что должно быть проверено: (1) есть ли ровно 1 элемент в @ARGV и (2) является ли этот элемент допустимым именем файла.

  • Хотя естьисключения из каждого правила, как правило, рекомендуется присваивать возврат от <> именованной переменной, а не полагаться на $_.Это особенно верно, если код внутри цикла может нуждаться в использовании одной из конструкций Perl, которая также опирается на $_ (например, map, grep или циклы for после исправления)

    while (my $line = <>){
        ...
    }
    
  • Perl предоставляет встроенную функцию (lc) для строчных букв.

  • Вы выполняете ненужные вычисления внутри цикла чтения строки.Если вы просто составите список слов, у вас будет вся необходимая информация.Также обратите внимание, что Perl предлагает однострочную форму для большинства своих управляющих структур (for, while, if и т. Д.), Как показано ниже.

    while (my $line = <>){
        ...
        $words{$_} ++ for split /\s+/, $line;
    }
    
  • Затем вы можете использовать слово «талли» для вычисления другой необходимой вам информации.Например, число уникальных слов - это просто количество ключей в хэше, а общее количество слов - сумма значений хеш-функции.

  • Распределение длин слов может бытьвычисляется так:

    my %lengths;
    $lengths{length $_} += $words{$_} for keys %words;
    
1 голос
/ 09 октября 2011

Использование таких хешей, как вы, - хороший способ сделать это. Более легким способом анализа файла является использование регулярного выражения с флагом / g для чтения слов из строки. \w+ означает одну или несколько буквенно-цифровых цифр.

while( <FILE> )
{
    while( /(\w+)/g )
    {
        my $wd = lc( $1 );
        ...

     }
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...