Как мне превратить таблицу в матрицу? - PullRequest
1 голос
/ 12 февраля 2009

Если я получил таблицу в текстовом файле, например

  • A B 1
  • A C 2
  • A D 1
  • B A 3
  • C D 2
  • A E 1
  • E D 2
  • C B 2
  • . , .
  • . , .
  • . , .

И я получил еще один список символов в другом текстовом файле. Я хочу преобразовать эту таблицу в структуру данных Perl, например:

  • _ A D E. , .
  • A 0 1 1. , ,
  • D 1 0 2. , .
  • E 1 2 0. , .
  • . , , , , , .

Но мне нужен только какой-то выбранный символ, например, A, D и E выделены в тексте символа, а B и C - нет.

Ответы [ 4 ]

2 голосов
/ 12 февраля 2009

Используйте массив для первого и 2-мерный хеш для второго. Первый должен выглядеть примерно так:

$list[0] # row 1 - the value is "A B 1"

А хеш вроде:

$hash{A}{A} # the intersection of A and A - the value is 0

Понимание того, как решить проблему, составляет для меня около 75% умственного сражения. Я не буду вдаваться в подробности о том, как печатать хеш или массив, потому что это легко, и я также не совсем понимаю, как вы хотите, чтобы он печатался, или сколько вы хотите печатать. Но преобразование массива в хеш должно выглядеть примерно так:

foreach (@list) {
  my ($letter1, $letter2, $value) = split(/ /);
  $hash{$letter1}{$letter2} = $value;
}

По крайней мере, я думаю, это то, что вы ищете. Если вы действительно хотите, вы можете использовать регулярное выражение, но это, вероятно, излишне просто для извлечения 3 значений из строки.

РЕДАКТИРОВАТЬ: Конечно, вы можете отказаться от @list и просто собрать хеш прямо из файла. Но это ваша работа, а не моя.

1 голос
/ 05 ноября 2014

вы можете попробовать это с помощью awk:

awk -f matrix.awk yourfile.txt> newfile.matrix.txt

где matrix.awk:

BEGIN {
   OFS="\t"
}
{
  row[$1,$2]=$3
  if (!($2 in f2)) { header=(header)?header OFS $2:$2;f2[$2]}
  if (col1[c]!=$1)
     col1[++c]=$1
}
END {
  printf("%*s%s\n", length(col1[1])+2, " ",header)
  ncol=split(header,colA,OFS)
  for(i=1;i<=c;i++) {
    printf("%s", col1[i])
    for(j=1;j<=ncol;j++)
      printf("%s%s%c", OFS, row[col1[i],colA[j]], (j==ncol)?ORS:"")
  }
}
0 голосов
/ 12 февраля 2009

CPAN имеет много потенциально полезных суффиксов . Я использую Data :: Table для многих целей. Data :: Pivot также выглядит многообещающе, но я никогда не использовал его.

0 голосов
/ 12 февраля 2009

Еще один способ сделать это - создать двумерный массив -

my @fArray = ();
## Set the 0,0th element to "_"
push @{$fArray[0]}, '_';

## Assuming that the first line is the range of characters to skip, e.g. BC
chomp(my $skipExpr = <>);

while(<>) {
    my ($xVar, $yVar, $val) = split;

    ## Skip this line if expression matches
    next if (/$skipExpr/);

    ## Check if these elements have already been added in your array
    checkExists($xVar);
    checkExists($yVar);

    ## Find their position 
    for my $i (1..$#fArray) {
        $xPos = $i if ($fArray[0][$i] eq $xVar);
        $yPos = $i if ($fArray[0][$i] eq $yVar);
    }

    ## Set the value 
    $fArray[$xPos][$yPos] = $fArray[$yPos][$xPos] = $val;
}

## Print array
for my $i (0..$#fArray) {
    for my $j (0..$#{$fArray[$i]}) {
        print "$fArray[$i][$j]", " ";
    }
    print "\n";
}

sub checkExists {
    ## Checks if the corresponding array element exists,
    ## else creates and initialises it.
    my $nElem = shift;
    my $found;

    $found = ($_ eq $nElem ? 1 : 0) for ( @{fArray[0]} );

    if( $found == 0 ) {
        ## Create its corresponding column
        push @{fArray[0]}, $nElem;

        ## and row entry.
        push @fArray, [$nElem];

        ## Get its array index
        my $newIndex = $#fArray;

        ## Initialise its corresponding column and rows with '_'
        ## this is done to enable easy output when printing the array
        for my $i (1..$#fArray) {
            $fArray[$newIndex][$i] = $fArray[$i][$newIndex] = '_';
        }

        ## Set the intersection cell value to 0
        $fArray[$newIndex][$newIndex] = 0;
    }
}

Я не слишком горжусь тем, как я справляюсь со ссылками, но терпите новичка здесь (пожалуйста, оставляйте свои предложения / изменения в комментариях). Вышеупомянутый хэш-метод Криса звучит намного проще (не говоря уже о том, чтобы печатать меньше).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...