необходимо дважды использовать функцию pop для удаления последнего элемента из массива (perl) - PullRequest
2 голосов
/ 16 марта 2019

Я только начал изучать Perl и присоединился к проекту Euler, чтобы попрактиковаться в программировании.Это первое упражнение, которое я сделал.Задача состояла в следующем: «Если мы перечислим все натуральные числа ниже 10, которые кратны 3 или 5, мы получим 3, 5, 6 и 9. Сумма этих мультипликаторов равна 23. Найдите сумму всех кратных 3 или5 ниже 1000 ".Мое решение:

use strict;
use warnings;

my @numbers = (1..1000);
my $counter = 0;
my @all_array = ();
my $total = 0;

foreach $counter (@numbers) {
    if (($numbers[$counter] % 3 == 0) or ($numbers[$counter] % 5 == 0)) {
        push (@all_array, $numbers[$counter]);
    }
}

pop (@all_array);    #after that the last digit is still in place
pop (@all_array);    # only now the number 1000 is removed

my $tot = eval join '+', @all_array;      #returns correct value
print $tot;

Последний элемент массива - 1000. Кажется, что за ним следует пробел, поэтому, чтобы удалить число и получить правильный результат, я должен дважды использовать функцию pop.Использование локального $ "= '' ничего не меняет. Кроме того, я получаю сообщение: Использование неинициализированного значения в @numbers в модуле (%) в строке C: \ Users \ Greg \ Documents \ perl \ unt.pl 10. Что я делаю не так и как это исправить?

1 Ответ

3 голосов
/ 16 марта 2019

Давайте пройдемся по вашему коду:

  • @numbers - массив с числами от 1 до 1000
    • Почему вы включаете 1000 в список, когда в упражнении написано «меньше чем N»?
  • цикл for
    • присваивает каждому из номеров $counter, то есть 1, 2, ...
    • вы используете $counter в качестве индекса в @numbers
      • почему вы делаете это, когда $counter уже является номером, который вы ищете?
      • Массивы Perl начинаются с индекса 0, поэтому у вас появляется ошибка "один за другим"
      • вы никогда не проверяете 1, потому что ваш первый номер будет $numbers[1] == 2 (ОК, не приводит к неверному результату для текущей задачи ...)
      • вы получаете доступ к одному элементу за массивом, т.е. $numbers[1000] == undef
    • расчет с undef вызовет предупреждение
    • undef % 3 == 0 верно, следовательно ...
  • первый pop() удалит undef (из $counter == 1000)
  • второй pop() удалит 1000 (из $counter == 999)
  • затем вы используете eval для строки 3 + 5 + 6 + ... очень неэффективный способ сделать сумму: -)

Разве это не будет более простой подход для вычисления суммы при работе от чисел от 1 до N-1? F.ex.:

#!/usr/bin/perl
use strict;
use warnings;

foreach my $arg (@ARGV) {
    my $sum = 0;

    foreach my $number (1..$arg - 1) {
        $sum += $number
            if ($number % 3 == 0) || ($number % 5 == 0);
    }

    print "${arg}: ${sum}\n";
}

exit 0;

Тестовый прогон:

$ perl dummy.pl 10 100 1000 10000
10: 23
100: 2318
1000: 233168
10000: 23331668
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...