0

私はPerlが初めてです。コマンド ラインから可算単語を受け取り、その複数形を生成する Perl プログラムを作成する課題があります。以下のコードを作成しましたが、コンパイルのエラーは表示されません。コマンド ラインから実行すると (たとえば、perlplural.pl)、名詞を入力するように求められます。その後、どの名詞を入力として入力しても、複数形は同じです。残りの if ステートメントは実行されません。

たとえば、「cat」という単語を入力すると、複数形は「cats」として生成されます。しかし、たとえば「church」という単語を入力すると、複数形は「churches」、「fly」は「flys」と生成されます。

コードは次のとおりです。

#!/usr/bin/perl

$suffix1 = 's';
$suffix2 = 'es';
$suffix3 = 'ies';

print "Enter a countable noun to get plural: ";
$word = <STDIN>;
chomp($word);

if(substr $word, -1 == 'b' or 'd' or 'c' or 'g' or 'r' or 'j' or 'k' or 'l' or 'm' or 'n' or 'p' or 'q' or 'r' or 't' or 'v' or 'w' or 'e' or 'i' or 'o' or 'u') {
    $temp = $word.$suffix1;
    print "The plural form of the word \"$word\" is: $temp \n";
}
elsif (substr $word, -1 == 's' or 'sh' or 'ch' or 'x' or 'z') {
    $temp = $word.$suffix2;
    print "The plural form of the word \"$word\" is: $temp \n";
}
elsif (substr $word, -1 == 'y') {
    chop($word);
    $temp = $word.$suffix3;
    print "The plural form of the word \"$word\" is: $temp \n";
}

コードで 3 つのステートメントを実行するのを手伝ってくれませんか。

4

5 に答える 5

8

まず、常に使用しますuse strict; use warnings;

  • eq文字列はではなくを使用して比較され==ます。

  • substr $word, -1 eq 'b'は を意味substr $word, (-1 eq 'b')しますsubstr($word, -1) eq 'b'。関数呼び出しの括弧を省略すると、多くの問題に直面します。

  • substr($word, -1) eq 'b' or 'd'と同じ意味(substr($word, -1) eq 'b') or ('d')です。'd'は常に真です。を使用する必要がありますsubstr($word, -1) eq 'b' or substr($word, -1) eq 'd'。(変数に保存substr $word, -1して、繰り返し実行しないようにすることをお勧めします。)

  • substr $word, -1chまたはと等しくなることはありませんsh

マッチ演算子はこれを簡単にします:

if ($word =~ /[bdcgrjklmnpqrtvweiou]\z/) {
   ...
}
elsif ($word =~ /(?:[sxz]|[sc]h)\z/) {
   ...
}
elsif ($word =~ /y\z/) {
   ...
}
于 2013-04-08T03:11:14.730 に答える
3
  1. Perl では、eq代わりに文字列比較に使用します==
  2. このままでは使えませんor。のようになるはずですif (substr($word, -1) eq 'b' or substr ($word, -1) eq 'd')。それ以外の場合は、比較したいすべての文字列を含む配列を使用して、その配列から grep することができます。
于 2013-04-08T02:58:45.077 に答える
2

まず、常に、常に と を含めuse strict;ますuse warnings;

次に、インデントを使用します。私は職場で Perl のコースを教えていましたが、正しくインデントされていない割り当てを受け入れることを拒否しています。実際、私はユーザーに標準 (4 スペース インデントなど) に合わせてコーディングすることを学んでもらいたいので、これについて非常に厳格です。これにより、プログラムが読みやすくなり、サポートしやすくなります。

その際、特に StackOverflow では、過度に長い行を分割してください。前後にスクロールしなければならない場合、プログラムを読むのは困難です。

あなたのプログラムを簡単に見てみましょう:

Perl では、文字列と数値は 2 つの異なるブール演算セットを使用します。これは、文字列には数字のみを含めることができますが、文字列のままであるためです。1384やのような在庫品目番号を想像してください993。これらを文字列として並べ替えると、1384項目が最初になります。それらを数値的にソートしている場合は、993最初に来る必要があります。あなたのプログラムは、あなたが使用するブール演算を除いて、これを知る方法がありません:

Boolean Operation   Numeric  String
=================   =======  ======
Equals              ==       eq
Not Equals          !=       ne
Greater Than        >        gt
Less Than           <        lt
Greater than/Equals >=       ge
Less than/Equals    <=       le

もう 1 つは、orand||および&&が 2 つのブール値でのみ機能することです。これはうまくいきません:

if ( $a > $b or $c ) {

これが言っていることは次のとおりです。

if ( ( $a > $b ) or $c ) {

したがって、$cがゼロ以外の値の場合は$ctrueなり、ステートメント全体が true になります。あなたはこのようにあなたの声明をしなければなりません:

if ( $a > $b or $a > $c ) {

もう 1 つのことは、引用符を含む文字列を引用するときにqq(..)andを使用することです。q()このように、それらの前にバックスラッシュを付ける必要はありません。

print "The word is \"swordfish\"\n";

print qq(The word is "swordfish"\n);

また、プログラムの先頭で を使用すると、次のようなuse feature qw(say);ボーナス コマンドが得られますが、最後の改行が想定されます。sayprint

say qq(The word is "swordfish");

を使用するsubstr, $foo, -1と、最後の文字だけが表示されます。2 文字の文字列にすることはできません。

if ( substr $word, -1 eq "ch" ) {

常に false になります。

長い if は保守が困難です。私はfor loop(実際にはそうではありませんが、今のところふりをしましょう..)を使用します:

#! /usr/bin/env perl

#
# Use these in ALL of your programs
#
use strict;
use warnings;
use feature qw(say);

#
# Use better, more descriptive names
#
my $standard_plural_suffix = 's';
my $uncommon_plural_suffix = 'es';
my $y_ending_plural_suffix = 'ies';

print "Enter a countable noun to get plural: ";
chomp (my $word = <STDIN>);

my $plural_form;

#
# Instead of a long, long "if", use a for loop for testing. Easier to maintain
#
for my $last_letter qw( b d c g r j k l m n p q r t v w e i o u) {
    if ( substr($word, -1) eq $last_letter ) {
        $plural_form = $word . $standard_plural_suffix;
        last;
    }
}
#
# Is it an "uncommon plural" test (single character)
#
if ( not $plural_form ) {
    for my $last_letter qw(s x z) {
        if ( substr($word, -1) eq $last_letter ) {
            $plural_form = $word . $uncommon_plural_suffix;
            last;
        }
    }
}
#
# Is it an "uncommon plural" test (double character)
#
if ( not $plural_form ) {
    for my $last_two_letters qw(sh ch) {
        if ( substr($word, -2) eq $last_two_letters ) {
            $plural_form = $word . $uncommon_plural_suffix;
            last;
        }
    }
}
if ( not $plural_form ) {
    if ( substr($word, -1) eq 'y' ) {
        chop ( my $chopped_word = $word );
        $plural_form = $chopped_word . $y_ending_plural_suffix;
    }
}

if ( $plural_form ) {
    say qq(The plural of "$word" is "$plural_form");
}
else {
    say qq(Could not find plural form of "$word");
}

正規表現について知っていますか?substr一度に複数のことをテストできるため、それらを使用するよりもはるかにうまく機能します。さらに、私は使用しませんchopが、正規表現の置換:

#! /usr/bin/env perl

#
# Use these in ALL of your programs
#
use strict;
use warnings;
use feature qw(say);

#
# Use better, more descriptive names
#
my $standard_plural_suffix = 's';
my $uncommon_plural_suffix = 'es';
my $y_ending_plural_suffix = 'ies';

print "Enter a countable noun to get plural: ";
chomp (my $word = <STDIN>);

my $plural_form;

#
# Standard plural (adding plain ol' 's'
#
if ( $word =~ /[bdcgrjklmnpqrtvweiou]$/ ) {
    $plural_form = $word . $standard_plural_suffix;
}
#
# Uncommon plural (adding es)
#
elsif ( $word =~ /([sxz]|[sc]h)$/ ) {
    $plural_form = $word . $uncommon_plural_suffix;
}
#
# Final 'y' rule: Replace y with ies
#
elsif ( $word =~ /y$/ ) {
    $plural_form = $word;
    $plural_form =~ s/y$/ies/;
}

if ( $plural_form ) {
    say qq(The plural of "$word" is "$plural_form");
}
else {
    say qq(Could not find plural form of "$word");
}
于 2013-04-08T03:55:06.270 に答える