Как узнать, есть ли номер в моем списке? - PullRequest
1 голос
/ 03 мая 2020

Мой код выглядит следующим образом:

#!/usr/bin/perl
$counter=0;
@list=<STDIN>;
chomp(@list);
if (@list==~ /^[+-]?\d+$/ )
{
$counter++;
}
print $counter;

Итак, я пишу данные как: ab c d 1 2 И тогда он должен напечатать 2

из-за 1,2

Но не имеет значения, какие данные я записываю в список, я получаю 0. Так в чем же проблема с моим if?

Ответы [ 2 ]

2 голосов
/ 03 мая 2020

Всегда use strict; use warnings;. Если ваша цель - подсчитать количество элементов di git в вашем списке, вы можете использовать grep для фильтрации элементов списка, а затем применить scalar, чтобы получить его длину (или напрямую использовать $length вместо сохранения отфильтрованный список в @matches):

#!/usr/bin/perl

use strict;
use warnings;

my @list = <STDIN>;
chomp(@list);
my @matches = grep /^[+-]?\d+$/, @list;
print scalar @matches . "\n";

Пример выполнения:

$ ./count.pl
-62
a
b
4
c
+91023
d
3
0 голосов
/ 03 мая 2020

Честно говоря, похоже, вы только что догадались об этом синтаксисе. Это не очень хороший способ написать программу: -)

Ваши основные проблемы в этой строке:

if (@list==~ /^[+-]?\d+$/ )

Здесь есть две довольно большие проблемы. Во-первых, @list. Оператор сопоставления (=~) работает одновременно с одной строкой. Так что вам нужно использовать его на скалярном значении. И если вы дадите ему массив (как вы сделали здесь), то Perl будет (молча) оценивать массив как скаляр - это означает, что вместо получения содержимого массива вы получите количество элементов в массив - который будет целым числом, поэтому ваше регулярное выражение всегда будет совпадать.

Но, вы говорите, оно не совпадает. Да, я это понимаю. И это из-за вашей второй ошибки - у вас неправильный оператор сопоставления. Оператор =~, и вы используете ==~ (см. Дополнительные =). Можно надеяться, что подобная ошибка вызовет синтаксическую ошибку, но вы случайно использовали версию, которая синтаксически действительна, но просто не выполняет то, что вы хотите. Perl интерпретирует ваш код как:

if (@list = =~ /^[+-]?\d+$/ )

Обратите внимание на пробелы, которые я добавил. Один из двух символов = важен. Это говорит "выполнить операцию сопоставления и присвоить результаты @list". Но с чем сопоставляется оператор сопоставления? Ну, ему не была дана явная переменная для сопоставления, и в этом случае она сопоставляется с переменной по умолчанию, $_. Вы ничего не добавили в $_, поэтому совпадение не удалось.

На данный момент, я должен указать, что если бы в вашем коде было use warnings, то вы получите все виды полезных предупреждений. о том, что ты делаешь неправильно. Все Perl программисты (включая самых опытных) должны всегда иметь use strict и use warnings в своем коде.

Здесь есть еще одна путаница. Это способ, которым вы читаете свой ввод.

@list = <STDIN>;

Вы не дали понять, но я подозреваю, что вы печатаете в своем списке все в одну строку. В этом случае вы не хотите хранить свои входные данные в массиве; Вы должны хранить его в скаляре.

chomp($list = <STDIN>);

Затем вы можете преобразовать его в список (для хранения в массиве), используя split().

@list = split /\s+/, $list;

Затем вы можете получить число чисел в вашем массиве, используя grep.

my $count = grep { /^[-+]\d+$/ } @list;

При оценке в виде скаляра, grep возвращает число раз, когда блок кода был истинным.

Установка вместе (и добавив strict и warnings) мы получим следующее:

#!/usr/bin/perl

use strict;
use warnings;

chomp(my $list = <STDIN>);

my $count = grep { /^[-+]\d+$/ } split /\s+/, $list;

Что, на мой взгляд, выглядит проще, чем ваша версия.

...