J'ai un tableau de 11 éléments. Où je veux additionner les éléments impairs, y compris le premier et le dernier élément comme un scalaire et les evens comme un autre.
Voici mon code J'essaie d'utiliser la carte en ajoutant 2 à chaque index pour obtenir le résultat mais je pense que j'ai s'est trompé.
use strict; use warnings; use Data::Dumper; print 'Enter the 11 digiet serial number: '; chomp( my @barcode = //, <STDIN> ); my @sum1 = map { 2 + $_ } $barcode[1] .. $barcode[11]; my $sum1 = sum Dumper( \@sum1 ); # sum2 = l2 + l4 + l6 + r8 + r10; printf "{$sum1}";
Quel est le bon moyen d'y parvenir?
5 Réponses :
Somme des indices pairs / impairs (ce que vous avez demandé, mais pas ce que vous voulez [1] ):
use List::Util qw( sum ); # Or: sub sum { my $acc; $acc += $_ for @_; $acc } my $sum_of_vals_at_even_idxs = sum @nums[0,2,4,6,8,10]; my $sum_of_vals_at_odd_idxs = sum @nums[1,3,5,7,9];
Somme des valeurs paires / impaires ( ce que vous avez également demandé, mais pas ce que vous voulez [1] ):
use List::Util qw( sum ); # Or: sub sum { my $acc; $acc += $_ for @_; $acc } my $sum_of_vals_at_even_idxs = sum @nums[ grep { $_ % 2 == 0 } 0..$#nums ]; my $sum_of_vals_at_odd_idxs = sum @nums[ grep { $_ % 2 == 1 } 0..$#nums ];
Somme des valeurs aux index pairs / impairs (ce que vous voyez à vouloir):
use List::Util qw( sum ); # Or: sub sum { my $acc; $acc += $_ for @_; $acc } my $sum_of_even_vals = sum grep { $_ % 2 == 0 } @nums; my $sum_of_odd_vals = sum grep { $_ % 2 == 1 } @nums;
Étant donné que vous savez combien d'éléments vous avez, vous pouvez utiliser ce qui suit:
use List::Util qw( sum ); # Or: sub sum { my $acc; $acc += $_ for @_; $acc } my $sum_of_even_idxs = sum grep { $_ % 2 == 0 } 0..$#nums; my $sum_of_odd_idxs = sum grep { $_ % 2 == 1 } 0..$#nums;
Vous pouvez réduire vos deux greps à, dans l'ordre grep {$ _% 2}
et gerep {! ($ _% 2)}
1) Je ne l'ai pas fait pour la symétrie (qui produit un code plus clair). 2) Bien que cela réduise le nombre de jetons pour les cotes, cela augmente en fait le nombre de jetons pour les évens.
Vous pouvez utiliser le fait que l'opérateur ?:
est assignable
print 'Enter the 11 digiet serial number: '; chomp( my @barcode = //, <STDIN> ); my $odd = 0; my $even = 0; for (my $index = 0; $index < @barcode; $index++) { ($index % 2 ? $even : $odd) += $barcode[$index]; }
Cela fonctionne en indexant sur @barcode
et en prenant le mod 2 de l'index, c'est-à-dire en divisant l'index par 2 et en prenant le reste, et si le reste est 1 ajouter cet élément de @barcode
à $ even
sinon à $ impair
.
Cela semble étrange jusqu'à ce que vous vous souveniez que les tableaux sont basés sur 0, donc votre premier numéro du code-barres est stocké dans $ barcode [0]
qui est un index pair.
Additionnez les valeurs aux indices pairs et impairs
perl -wE'@ary = 1..6; for (0..$#ary) { $_ & 1 ? $odds += $ary[$_] : $evens += $ary[$_] }; say "odds: $odds, evens: $evens" '
Remarque pour les tests: avec des indices pairs (0,2,4) nous avons des valeurs (impaires!) (1,3,5 ), dans cet exemple ( 1..6
)
belle utilisation de l'opérateur ternaire pour attribuer des cotes / égales .. J'ai aussi posté une réponse pour cela ..
chomp (my @barcode = //,
était probablement censé avoir un split
avant le //
?
@barcode
aura tous les caractères de la ligne lus, y compris la nouvelle ligne. Le chomp changera l'élément final d'une nouvelle ligne en une chaîne vide.
Mieux vaut d'abord chomp pour avoir juste vos chiffres dans le tableau:
chomp(my $barcode = <STDIN>); my @barcode = split //, $barcode;
p>
Un autre Perl, si la chaîne est de longueur 11 et ne contient que des chiffres
$ perl -le ' $_="12121212121"; s/(.)(.)|(.)$/$odd+=$1+$3;$even+=$2/ge; print "odd=$odd; even=$even" ' odd=6; even=10 $
avec une entrée différente
$ perl -le ' $_="12345678911"; s/(.)(.)|(.)$/$odd+=$1+$3;$even+=$2/ge; print "odd=$odd; even=$even" ' odd=26; even=21 $
Une façon intéressante de faire pair / impair dans une chaîne! Nits à choisir: il est destructeur pour la chaîne d'origine (d'une manière qui n'est pas utile), et il utilise l'expression régulière avec / e
pour son effet secondaire; peut peut-être faire la même chose mais comme while (/.../g) {$ odd + = ...}
? Je ne sais pas comment cela se passe en termes d'efficacité: le s ///
fonctionne sous / e
mais est une expression régulière tandis que while
démarre le moteur chacun temps (sauf si ce cas est optimisé?). Je ne suggère pas de changer cela, juste une note à considérer à l'avenir.
Il s'agit d'une question «Déboguer mon code pour moi», qui n'est pas ici. Pouvez-vous nous expliquer votre code et expliquer ce que l'instruction
map
est censée faire? Surtout, que doit faire$ barcode [1] .. $ barcode [11]
? Regardez le cas de$ barcode [1] = 99
et$ barcode [11] = 0
.normalement tableau de 11 éléments, les éléments sont indexés de 0 à 10;
@barcode [0..10]
notez le préfixe@
pour obtenir un tableau découpé