簡體   English   中英

如何在Perl中檢查回文?

[英]How do I check a palindrome in Perl?

我正在嘗試在Perl中編寫回文檢查器。 如果輸入的向前和向后相同,則應該返回"true"

例:

./determine kayak
True
./determine "Do geese see God?"
True
./determine "Do ducks see God?"
False

我的代碼:

#!/usr/bin/perl -w 

$name = $ARGV[0];
$name = lc $name;
$name =~ s/[^a-z]//g;
@all = split //,$name;
$half = $#all/2;

foreach $i (0..$half){
    my $count = 0;
    if($all[$i] eq $all[-($i+1)]){
        #print"$all[$i]\n";
        #print"$all[-($i+1)]\n";
        print "true\n";
        last;       
    }else{
        print "flase\n";
    }

}

閱讀全部后無法確定是非。

例如:當讀到: "Do ducks see God?" ,前兩個字母相同,因此將輸出true,但這應該是false。

您的代碼僅檢查第一個字母,然后如果相同則停止循環。 您已正確識別出該問題。 這是因為last

foreach $i (0..$half){
    my $count = 0;
    if($all[$i] eq $all[-($i+1)]){
        print "true\n";
        last;                       # <-- here
    }else{
        print "flase\n";
    }
}

這將使Perl退出循環。 您要做的是繼續檢查每個字母。 一旦到達中間位置,您的結果就是正確的,因為字符串是回文 但是一旦發現不匹配,就必須失敗並退出。

您可以通過將狀態保留在變量中,然后進行檢查來做到這一點。 我添加了strictwarnings ,並使代碼短了一些。

my $name = lc 'Do ducks see God?';
$name =~ s/[^a-z]//g;
my @all = split //, $name;
my $half = $#all / 2;

my $is_palindrome = 1;
foreach my $i ( 0 .. $half ) {
    my $count = 0;
    if ( $all[$i] ne $all[ -( $i + 1 ) ] ) {
        $is_palindrome = 0;
        last;
    }
}

if ($is_palindrome) {
    print "true\n";
} else {
    print "false\n";
}

使用ne check會更容易,因為在if之后添加一個空塊會造成混淆。

if ( 1 == 0 ) {
} else {
    # do stuff
}

它更容易扭轉的條件和擺脫塊,或使用unless ,這是一樣的, 如果不是在Perl。

if ( 1 != 0 ) {
    # do stuff
}

unless ( 1 == 0 ) {
    # do stuff
} 

請注意,有一種更短的實現方式:您可以將字符串與其reverse進行比較。 當在標量上下文中調用內置reverse函數時,會reverse字符串。

my $name = lc '12321';
$name =~ s/[^a-z]//g;

if ($name eq reverse $name) {
    print "true\n";
} else {
    print "false\n";
}

當前,對於字符數組的每次迭代,您都打印“ true”或“ false”。 您確實要檢查每個字母,只在最后打印結果。

my $is_palindrome = 1;

foreach $i (0..$half){
    if ($all[$i] ne $all[-($i+1)]){
        $is_palindrome = 0;
        last;
    }
}

say $is_palindrome ? 'true' : 'false';

但是,就我個人而言,我認為只檢查$name變量與其反向變量相同是容易的。

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

my $name = $ARGV[0];
$name = lc $name;
$name =~ s/[^a-z]//g;

say $name eq reverse($name) ? 'true' : 'false';

注意:請使用use warnings而不是-wuse strict

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM