2009-07-04 14 views
7

मैं लामा (Learning Perl) पुस्तक पढ़ रहा हूं, और अभ्यास पर काम कर रहा हूं। और इस अभ्यास के लिए:यह सरल पर्ल पुश/पॉप प्रोग्राम क्यों काम नहीं कर रहा है?

एक ऐसा प्रोग्राम लिखें जो अलग-अलग लाइनों पर स्ट्रिंग्स की सूची को अंत तक इनपुट तक पढ़ता है और सूची को रिवर्स ऑर्डर में प्रिंट करता है। [। । ।]

ठीक है, मैं पहले से ही बाहर एक सरल तरीका (मुझे याद है आप सरणियों पर reverse इस्तेमाल कर सकते हैं ... पर्ल तो है ... भयानक अब तक) लगा, लेकिन क्यों यह एक नहीं है मैं सोच रहा हूँ काम कर रहे।

#!/usr/bin/perl 

use 5.010; 

chomp(@strings = <STDIN>); 

foreach (@strings){ 
    push @revstrings, $_; 
} 

while($i++ <= scalar @revstrings){ 
    say pop @revstrings; 
} 

यह इस प्रकार है:

$ ./first
एक
दो
तीन

[^ डी]
तीन
दो
$ अगर मैं सिर्फ < जबकि पाश में <= बदलने

उत्पादन में ही है।

+7

यदि मैं सुझाव दे सकता हूं, तो अपने आप को एक पक्ष बनाओ और का उपयोग करना शुरू करें; चेतावनियों का उपयोग करें; शुरुआत से आपके सभी कार्यक्रमों में । यह आपके दिमाग को अच्छे प्रथाओं के अनुरूप प्रारूपित करेगा :) – Damien

+0

सच है, लेकिन मैं प्यार करता हूं कि अनुमत perl कितना है। यह आपको जो कुछ भी आप चाहते हैं उसे करने देता है –

+3

और कई चीजें जिन्हें आप नहीं चाहते हैं लेकिन आपने दुर्घटना से किया ... – ijw

उत्तर

15

आप आधी दूरी तक कभी नहीं मिलेगा ... कि पिछले यात्रा के माध्यम से हर बार, आप चाहते हैं:

  • $i++ मतलब यह है कि $i एक के बाद में वृद्धि होगी;
  • pop @revstrings का अर्थ यह होगा कि scalar @revstrings एक से कम हो जाएगा।

वे बीच में मिलेंगे, जब $i++ आधा मूल @revstrings लंबाई से अधिक है।

वास्तव में, $i++, अनावश्यक है scalar @revstrings के बाद से शून्य हो जाएगा जब सरणी रिक्त है, तो आप सिर्फ जरूरत है:

while(scalar @revstrings){ 
    say pop @revstrings; 
} 
+10

या तो 'स्केलर' की कोई ज़रूरत नहीं है। जबकि बूलियन (स्केलर) संदर्भ में सशर्त मूल्यांकन करता है। तो जबकि (@revstrings) {...} चाल करेगा। – daotoad

+0

@daotoad: +1 अच्छा बिंदु। – Stobor

+0

'* माथे smacks *'। किसी कारण से मैंने माना कि @revstrings का मूल्यांकन केवल एक बार किया जाएगा। हाहा, यह एक बेवकूफ गलती थी - मुझे एक अलग संरचना के साथ पहले एक ही समस्या थी (मैं क्या भूल गया), इसलिए मैंने सोचा कि मैं केवल $ i ++ का उपयोग करूंगा ताकि यह सिर्फ एक असंबंधित गिनती हो। अगर मैंने एक चर में @revstrings की लंबाई संग्रहित की है और फिर लूप में उपयोग किया है, तो मुझे लगता है कि यह काम करेगा। धन्यवाद हालांकि –

0

संपादित: "। क्योंकि आपके पाश हालत गलत है" लघु जवाब है अधिक verbose "scalar @revstrings प्रत्येक पुनरावृत्ति का मूल्यांकन किया जाता है"।

while (<STDIN>) { 
    push @lines, $_ 
} 

while(@lines){ 
    print pop @lines; 
} 

कम

@lines = <STDIN>; 

while(@lines){ 
    print pop @lines; 
} 

कम

print reverse <>; 

टाइपिंग

@lines = <STDIN>; 
print reverse @lines; 

कम टाइपिंग लेकिन अब तक का सबसे अच्छा समाधान टाइपिंग

01 है
exec("tac"); 
+2

यदि आपका लक्ष्य PERl_ सीखना है तो यह सबसे अच्छा समाधान नहीं है। उल्लेख नहीं है कि सभी प्रणालियों पर 'tac' मौजूद नहीं है। यानी, समाधान पोर्टेबल नहीं है। – Telemachus

+1

'रिवर्स ' प्रिंट करने के लिए क्या हुआ? –

+1

ठीक है, मुझे उत्सुकता मिली: प्रश्न में 'tac' का उल्लेख किया गया है और उत्तर 'प्रिंट रिवर्स <>' है। लेकिन, फिर, अगर वह पर्ल सीखने की कोशिश कर रहा है, तो उसे यह भी पता होना चाहिए कि उसका जवाब _didn't_ क्यों काम करता है। (_Learning Perl_ अध्याय 5 अगर आप घर पर खेल रहे हैं।) – Telemachus

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