Ваш код проверяет только первую букву, а затем останавливает цикл, если они совпадают.Вы правильно определили эту проблему.Это из-за 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 выйти из цикла.Вместо этого вам нужно проверять каждую букву.Как только вы достигли середины, ваш результат верен, потому что строка палиндром .Но как только вы видите несоответствие, вы должны потерпеть неудачу и выйти.
Вы делаете это, сохраняя состояние в переменной и проверяя его после.Я добавил strict
и warnings
и сделал код немного короче.
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
встроенный , когда вызывается в скалярном контексте, переворачивает строку.
my $name = lc '12321';
$name =~ s/[^a-z]//g;
if ($name eq reverse $name) {
print "true\n";
} else {
print "false\n";
}