2011-10-09 5 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. 

यहां तक ​​कि मैं अपना होमवर्क के लिए समाधान पता लगाने के लिए सक्षम कर सकते हैं गूगल की मदद से हालांकि। लेकिन हालांकि मुझे लगता है कि पर्ल की वास्तविक शक्ति का उपयोग करके एक छोटा और संक्षिप्त कोड होगा। क्या कोई मुझे कोड की बहुत कम लाइनों के साथ पर्ल में समाधान दे सकता है?

+0

अपने उपयोग बयान के अनुसार, फ़ाइल नाम दूसरा तर्क है। यह आपके कोड के विपरीत है। –

+1

सुझाव एक है: स्पष्ट रूप से खुला उपयोग न करें। बस <> का उपयोग करें। पर्ल एआरजीवी में एक फ़ाइल नाम के रूप में प्रत्येक तर्क की व्याख्या करेगा, और <> इससे पढ़ेगा। –

+0

@WilliamPursell: हाँ फ़ाइल का नाम दूसरा तर्क है .. – sriram

उत्तर

9

यहाँ कई सुझाव हैं:

  • use strict और अपने पर्ल स्क्रिप्ट में use warnings शामिल करें।

  • आपका तर्क सत्यापन परीक्षण नहीं कर रहा है कि यह परीक्षण कर रहा है: (1) क्या @ARGV में बिल्कुल 1 आइटम है, और (2) क्या यह आइटम वैध फ़ाइल नाम है।

  • हालांकि प्रत्येक नियम के अपवाद हैं, लेकिन आमतौर पर <> से $_ पर निर्भर होने के बजाय, नामित चर पर वापसी असाइन करना अच्छा अभ्यास है। यह विशेष रूप से सच पाश अंदर कोड पर्ल के निर्माणों में से एक यह है कि यह भी $_ पर निर्भर करता है का उपयोग करने के (उदाहरण के लिए, map, grep, या for छोरों के बाद ठीक)

    while (my $line = <>){ 
        ... 
    } 
    
  • पर्ल एक निर्मित प्रदान करता है की आवश्यकता हो सकती है, तो है -इन फ़ंक्शन (lc) स्ट्रिंग को कम करने के लिए।

  • आप लाइन रीडिंग लूप के अंदर अनावश्यक गणना कर रहे हैं। यदि आप बस शब्दों का एक सार बनाते हैं, तो आपके पास आवश्यक सारी जानकारी होगी। यह भी ध्यान रखें कि पर्ल अपने अधिकांश नियंत्रण संरचनाओं (for, while, if इत्यादि) के लिए एक-लाइनर फॉर्म प्रदान करता है, जैसा कि नीचे दिखाया गया है।

    while (my $line = <>){ 
        ... 
        $words{$_} ++ for split /\s+/, $line; 
    } 
    
  • तब आप अन्य जानकारी की गणना करने के लिए लम्बी शब्द का उपयोग कर सकते हैं। उदाहरण के लिए, अद्वितीय शब्दों की संख्या हैश में केवल चाबियों की संख्या है और शब्दों की कुल संख्या हैश मानों का योग है।

  • शब्द लंबाई के वितरण इस तरह की जा सकती है:

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

पोस्टफिक्स लूप वाक्यविन्यास घृणा से भरे एक भाषा में # 1 वाक्यविन्यास घृणित हैं – Nemo

+0

ओह! ऐसा लगता है कि पर्ल कुकबुक उदाहरणों की तरह :) मुझे कुछ संदेह हैं, '$ शब्द {$ _} ++ विभाजन/\ s +/$ $ के लिए;' यह वास्तव में क्या कर रहा है? मैं यह समझने में सक्षम नहीं था कि इस फैशन में '$ शब्द {$ _}' क्यों उपयोग किया गया था, वास्तव में '$ _' क्या है? – sriram

+0

@GroovyUser यह 'स्प्लिट/\ s + /, $ line) {$ शब्द {$ _} ++} 'के लिए एक छोटा सा रूप है, जहां' $ _' एक व्यक्तिगत शब्द है। – FMc

1

आपके जैसे हैंश का उपयोग करना इसके बारे में जाने का एक अच्छा तरीका है। फ़ाइल को पार्स करने के लिए एक और पर्ल तरीका लाइन से शब्दों को पढ़ने के लिए/g ध्वज के साथ रेगेक्स का उपयोग करना है। \w+ का अर्थ है एक या अधिक अल्फान्यूमेरिक्स।

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

    } 
} 
संबंधित मुद्दे