2009-10-19 14 views
-1

Bon, j'ai eu du mal avec ça tout le week-end, et j'ai reçu beaucoup d'aide, mais je ne comprends toujours pas. Voici mon code jusqu'à présent: ce que je veux faire est de construire quelques matrices à partir de l'entrée de l'utilisateur. Finalement, je veux les multiplier. Une autre histoire.Comment puis-je construire une matrice 2D à partir d'une entrée standard en Perl?

entrée

est la suivante

1 2 2 4 
4 5 6 6 

1 2 2 3 
1 2 2 3 

sub makeMatrix { 
    my ($input) = @_; 
    my @mat; 
    while (<$input>) { 
    if ($input eq ""){ 
     print "it's blank\n"; 
     return; 
    } 
    else{ 
     push @mat, [ split ]; 
    } 
    return \@mat; 
    } 
} 

my @a =(); 
while($a = <>) { 
    chomp $a; 
    push @a,($a); 
    } 


@matrices; 
push @mat, (makeMatrix(@a)); 

foreach $input (@matrices){ 
    print "input was $input\n"; 

} 

Pourquoi pas ce travail? Pourquoi ne crée-t-il pas un tableau de matrices dans @matrices? Est-ce l'instruction return dans le sous-programme? Mon but est d'avoir deux matrices dans le tableau des matrices. Merci pour votre aide.

+3

Vous avez déjà posé cette question: http://stackoverflow.com/questions/1581330/how-do-i-build-a-2d-matrix -using-stdin-in-perl –

+0

ouais mais je ne peux pas le faire fonctionner. Je ne saisis pas l'idée. Je veux vraiment le comprendre. – Mawnster

+3

Il semble que vous devez d'abord étudier les bases de la langue. Avez-vous déjà un livre? –

Répondre

2

Vous semblez être un peu confus au sujet de la signification de l'opérateur <>.

La ligne

while (<$input>) 

est faux. Cela indique à Perl de lire à partir d'un descripteur de fichier $input. Cependant, ce que vous avez passé dans le sous-programme n'est pas un handle de fichier, c'est un morceau de texte. Vous n'avez pas besoin du <> ici. En outre, vous semblez avoir ignoré la plupart des entrées du sous-programme. Vous l'appelez comme ceci:

makeMatrix(@a) 

mais vous utilisez uniquement la première valeur de @a dans la routine. La routine devrait ressembler à ceci:

use warnings; 
use strict; 

sub makeMatrix { 
    my @inputs = @_; 
    my @mat; 
    for my $input (@inputs) { 
     # print "$input\n"; # debugging code left here for artistic effect 
     if ($input eq "") { 
      print "it's blank\n"; 
     } 
     else{ 
      push @mat, [ split /\s+/, $input ]; 
     } 
    } 
    return \@mat; 
} 

my @a; 

while ($a = <>) { 
    chomp $a; 
    push @a, $a; 
} 


my $matrices = makeMatrix (@a); 

for my $row (@$matrices){ 
    for my $column (@$row) { 
     print "input was $column\n"; 
    } 
} 
+0

Notez que 'split ''' est différent de 'split/\ s +/'. Slurping le fichier n'est ni nécessaire ni souhaitable. Passer toutes les lignes sous la forme d'un tableau aplati lorsque ce tableau est grand est une mauvaise pratique. –

1

Vous passez makeMatrix un tableau de chaînes mais la fonction prétend qu'il est passé un descripteur de fichier. Je ne sais pas pourquoi vous passez à travers tant de cerceaux, mais c'est le gros problème avec votre code.

En outre, si un vrai filehandle ont été transmis à makeMatrix, la ligne

while (<$input>) { 
    if ($input eq ""){ 

ne ferait pas ce que vous pensez qu'il devrait faire.

while (<$input>) { 

lirait la ligne en $_ à chaque itération. Alors:

if ($input eq ""){ 

sera toujours faux parce $input serait un descripteur de fichier (et donc pas égale à la chaîne vide). De plus, même si vous avez correctement écrit

if ($_ eq ""){ 

la condition serait faux lors de la rencontre d'une ligne vide parce que vous ne l'avez pas chomp de la ligne de fin ($_ ne serait pas vide).

Dans l'ensemble, un véritable désordre de code où le lecteur peut seulement essayer de deviner ce que vous essayez de faire. Pensez à ce que vous voulez accomplir et expliquez-le un peu mieux.

http://learn.perl.org/ a d'excellentes ressources pour apprendre Perl.

Le code ci-dessous est horriblement obscure et je ne le recommanderais pas à utiliser dans la production, mais en essayant de comprendre ce qu'il ne peut vous apprendre beaucoup:

#!/usr/bin/perl 

use strict; 
use warnings; 

use Data::Dumper; 

while (my $matrix = read_matrix()) { 
    print Dumper $matrix; 
} 

sub read_matrix { 
    local $/ = "\n\n"; 
    return if eof DATA; 
    return [ map { [ split ] } split /\n/, scalar <DATA> ]; 
} 

__DATA__ 
1 2 2 4 
4 5 6 6 

1 2 2 3 
1 2 2 3 

Sortie:

 
$VAR1 = [ 
      [ 
      '1', 
      '2', 
      '2', 
      '4' 
      ], 
      [ 
      '4', 
      '5', 
      '6', 
      '6' 
      ] 
     ]; 
$VAR1 = [ 
      [ 
      '1', 
      '2', 
      '2', 
      '3' 
      ], 
      [ 
      '1', 
      '2', 
      '2', 
      '3' 
      ] 
     ]; 
+0

@Kinopiko: il dit cela. Que pensez-vous besoin d'éclaircissement? – ysth

+0

Il est dit "$ input est un handle de fichier" au milieu de la réponse. –

1

Matt, S'il vous plaît vérifier ce que j'ai écrit ci-dessous pour voir si je comprends le problème:

Mes points généraux sont:

(1) Vos données d'exemple ne fonctionnent pas tout à fait pour la multiplication matricielle. Si votre premier tableau est 2x4 alors votre deuxième tableau doit être 4x2 et votre réponse sera 2x2. (2) Perl vous fournit un langage de données (PDL) très puissant qui est efficace lors de la manipulation de matrices. Je vous suggère de l'utiliser si vous allez faire beaucoup d'algèbre matricielle.

(3) Selon la solution ci-dessous, le produit matriciel est supprimé en 3 lignes à condition que vous ayez lu vos données dans un tableau 2D (AoA est un tableau de tableaux) en premier.

#!/usr/bin/perl 
use strict; 
use warnings; 
use PDL; # perl data language enables matrix multiplication 
use Inline::Files; #multiple virtual files inside code 

my @AoA_A = make_matrix("ARRAY_A"); #read in 2D array 
my @AoA_B = make_matrix("ARRAY_B"); 

my $a = pdl [ @AoA_A ]; #Construct new pdl object 
my $b = pdl [ @AoA_B ]; 
my $c = $a x $b; # x overload 
print "matrix a", $a; 
print "matrix b", $b; 
print "matrix c",$c; 

sub make_matrix { 
    my $source = shift; 
    my @AoA; 
    while (<$source>){ 
     my @tmp = split; 
     push @AoA, [ @tmp ]; 
    } 
    return @AoA; 
} 

__ARRAY_A__ 
1 2 2 4 
4 5 6 6 
__ARRAY_B__ 
1 2 
2 3 
1 2 
2 3 

Il a créé la sortie suivante:

matrix a 
[ 
[1 2 2 4] 
[4 5 6 6] 
] 
matrix b 
[ 
[1 2] 
[2 3] 
[1 2] 
[2 3] 
] 
matrix c 
[ 
[15 24] 
[32 53] 
] 
+0

Texte corrigé pour refléter le commentaire de Sinan. – heferav

Questions connexes