2011-10-09 2 views
5

나는 펄 초보자 해요 내 숙제 중 하나에 나는이 같은 솔루션을 함께했다 : 나는 무엇을 언급 주석을 포함했다이 더 펄에서 수행 할 수있는 방법을 방법

#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의 진정한 힘을 사용하는 작고 간결한 코드가있을 것이라고 생각합니다. 누구나 코드 줄이 훨씬 적은 펄 솔루션을 나에게 줄 수 있습니까?

+0

, 파일 이름은 두 번째 인수입니다. 그건 당신의 코드와 모순된다. –

+1

제안 사항은 다음과 같습니다. 명시 적으로 열기를 사용하지 마십시오. <> 만 사용하십시오. Perl은 ARGV의 각 인수를 파일 이름으로 해석하고 <>는 파일 이름을 읽습니다. –

+0

@WilliamPursell : 예 파일 이름은 두 번째 인수입니다. – sriram

답변

9

여기에 몇 가지 제안 사항 :

  • 는 Perl 스크립트에 use strictuse warnings를 포함합니다.

  • 인수 유효성 검사는 테스트해야 할 항목을 테스트하지 않습니다. (1) @ARGV에 정확히 1 개의 항목이 있는지, (2) 해당 항목이 유효한 파일 이름인지 여부입니다.

  • 모든 규칙에 예외가 있지만 일반적으로 $_에 의존하지 않고 <>의 반환 값을 명명 된 변수에 할당하는 것이 좋습니다. 루프 내부의 코드가

    while (my $line = <>){ 
        ... 
    } 
    
  • 펄이 내장되어 제공 (예를 들어, map, grep, 또는 for 루프를 후 수정)도 $_에 의존 펄의 구조 중 하나를 사용해야 할 수도 있습니다 경우에 특히 그러하다 -in 함수 (lc)를 소문자 문자열로 변환합니다.

  • 라인 읽기 루프 내에서 불필요한 계산을 수행하고 있습니다. 단순히 단어 수를 늘리면 필요한 모든 정보를 얻을 수 있습니다. Perl은 아래 그림과 같이 대부분의 제어 구조 (for, while, if 등)에 대해 한 줄짜리 양식을 제공합니다.

    while (my $line = <>){ 
        ... 
        $words{$_} ++ for split /\s+/, $line; 
    } 
    
  • 그런 다음 tallies라는 단어를 사용하여 필요한 기타 정보를 계산할 수 있습니다. 예를 들어, 고유 한 단어의 수는 단순히 해시의 키 수이고 총 단어 수는 해시 값의 합계입니다.

  • 단어 길이의 분포

  • 는 다음과 같이 계산 될 수있다 : 당신의 사용}에 따르면

    my %lengths; 
    $lengths{length $_} += $words{$_} for keys %words; 
    
+0

포스트 픽스 루프는 문법 가짜 언어로 가득 찬 # 1의 구문 가짜입니다. – Nemo

+0

오오! 예를 들어 Perl 요리 책처럼 보입니다. split/\ s +/$ line에 대한 $ words {$ _} ++에 대한 의심이 있습니다. 정확히 무엇을하고 있습니까? 나는'$ words {$ _} '가 왜이 방식으로 사용되었는지, 정확히'$ _'는 무엇인지 알아낼 수 없었습니다. – sriram

+0

@GroovyUser 'for (split/\ s + /, $ line) {$ words {$ _} ++}'의 줄임표 형태입니다.'$ _ '는 개별 단어입니다. – FMc

1

여러분처럼 해시를 사용하면 좋은 방법입니다. 파일을 구문 분석하는 펄 방법은/g 플래그가있는 정규식을 사용하여 줄에서 단어를 읽는 것입니다. \w+은 하나 이상의 영숫자를 의미합니다.

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

    } 
} 
관련 문제