Как я могу создать двумерный массив в Perl? - PullRequest
2 голосов
/ 14 октября 2010

В настоящее время я пытаюсь передать матричный файл размером 32 на 48 в многомерный массив в Perl. Я могу получить доступ ко всем значениям, но у меня возникают проблемы с доступом к конкретному значению. Любая помощь будет принята с благодарностью. Я поместил ссылку на набор данных, а также код, который у меня есть ниже.

Вот ссылка на набор данных: http://paste -it.net / государственный / x1d5301 /

Вот что у меня есть для кода прямо сейчас.

#!/usr/bin/perl

open FILE, "testset.txt" or die $!;
my @lines = <FILE>;

my $size = scalar @lines;

my @matrix = (1 .. 32);
my $i = 0;
my $j = 0;
my @micro;

foreach ($matrix)
{

foreach ($lines)
{
    push @{ $micro[$matrix]}, $lines;
}
}

Ответы [ 5 ]

7 голосов
/ 14 октября 2010

Не похоже, что вы понимаете, что $matrix указывает на @matrix, только когда за ним сразу следует индексатор массива: [ $slot ].В противном случае $matrix - это совершенно другая переменная, чем @matrix (и обе они также отличаются от %matrix).См. perldata .

#!/usr/bin/perl
use English;

Не! используйте английский - таким образом !

Это приносит$MATCH, $PREMATCH и $POSTMATCH и влечет за собой ужасные $&, $ `, $' штраф.Вам следует подождать, пока вы не используете английскую переменную, а затем просто импортировать ее.

open FILE, "testset.txt" or die $!;

Две вещи: 1) использовать лексические файловые дескрипторы, и 2) используйте три арг open.

my @lines = <FILE>;

Пока я выбираю: не глотайте большие файлы.(Дело не в этом, но это хорошее предупреждение.)

my $size = scalar @lines;

my @matrix = (1 .. 32);
my $i = 0;
my $j = 0;
my @micro;

Я вижу, что мы находимся на "ПРИБЫЛЕ !!" стадии здесь ...

foreach ($matrix) {

У вас нет переменной $matrix У вас есть переменная @matrix.

    foreach ($lines) {

То же самое верно для $lines.

        push @{ $micro[$matrix]}, $lines;
    }
}

Переписать:

use strict;
use warnings;
use English qw<$OS_ERROR>; # $!
open( my $input, '<', 'testset.txt' ) or die $OS_ERROR;

# I'm going to assume space-delimited, since you don't show
my @matrix;
# while ( defined( $_ = <$input> ))...
while ( <$input> ) {
    chomp; # strip off the record separator
    # load each slot of @matrix with a reference to an array filled with
    # the line split by spaces.
    push @matrix, [ split ]; # split = split( ' ', $_ )
}
3 голосов
/ 15 октября 2010

Если вы собираетесь заниматься математикой, вы можете рассмотреть PDL (язык данных Perl) Вы можете легко настроить свою матрицу и перед операциями с ней:

use 5.010;

use PDL;
use PDL::Matrix;

my @rows;
while( <DATA> ) {
    chomp;
    my @row = split /\s+/;
    push @rows, \@row;
    }

my $a = PDL::Matrix->pdl( \@rows );
say "Start ", $a;

$a->index2d( 1, 2 ) .= 999;
say "(1,2) to 999 ", $a;

$a++;
say "Increment all ", $a;

__DATA__
1 2 3
4 5 6
7 8 9
2 3 4

Выходные данные показывают эволюцию матрицы:

Start 
[
 [1 2 3]
 [4 5 6]
 [7 8 9]
 [2 3 4]
]

(1,2) to 999 
[
 [  1   2   3]
 [  4   5 999]
 [  7   8   9]
 [  2   3   4]
]

Increment all 
[
 [   2    3    4]
 [   5    6 1000]
 [   8    9   10]
 [   3    4    5]
]

Существует довольно много возможностей для выполнения произвольных и сложных операций над каждым членом матрицы, как я добавил 1 к каждому члену. Вы полностью пропускаете зацикленную акробатику.

Мало того, PDL делает много специальных вещей, чтобы сделать математику действительно быстрой и иметь небольшой объем памяти. Некоторые вещи, которые вы хотите сделать, уже могут быть реализованы.

2 голосов
/ 14 октября 2010

Вам, вероятно, нужно chomp значения:

chomp( my @lines = <FILE> );
1 голос
/ 21 октября 2011

Я вижу вопрос довольно старый, но, поскольку автор только что отредактировал вопрос, возможно, он все еще представляет интерес.Также ссылка на данные неактивна, но, поскольку в других ответах в качестве разделителя используется пробел, я тоже буду.другой файл может быть обработан с помощью Text::CSV).

#!/usr/bin/env perl

use strict;
use warnings;

use Tie::Array::CSV;

## put DATA into temporary file
## if not using DATA, put file name in $file
use File::Temp ();
my $file = File::Temp->new();
print $file <DATA>;
##


tie my @data, 'Tie::Array::CSV', $file, { 
  text_csv => {
    sep_char => " ",
  },
};

print $data[1][2];

__DATA__
1 2 3 4 5
6 7 8 9 1
2 3 4 5 6
1 голос
/ 14 октября 2010

Я делаю этот CW, потому что его единственная цель состоит в том, чтобы прояснить касательную точку, которую я высказал в своем комментарии к @ ответу Аксемана . См. perldoc -f split :

Разделение на /\s+/ похоже на split(' '), за исключением того, что любой начальный пробел создает нулевое первое поле. Разделение без аргументов действительно split(' ', $_) внутренне.

#!/usr/bin/perl

use YAML;

$_ = "\t1 2\n3\f4\r5\n";

print Dump { 'split'       => [ split       ] },
           { "split ' '"   => [ split ' '   ] },
           { 'split /\s+/' => [ split /\s+/ ] }
           ;

Выход:

---
split:
  - 1
  - 2
  - 3
  - 4
  - 5
---
split ' ':
  - 1
  - 2
  - 3
  - 4
  - 5
---
split /\s+/:
  - ''
  - 1
  - 2
  - 3
  - 4
  - 5
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...