2010-07-08 3 views
5

Я набор строк с переменными размерами, например:Perl - Hash хэш и столбцов :(

AAA23

AB1D1

A1BC

AAB212

Моя цель состоит в алфавитном порядке и уникальных персонажах, собранных для КОЛОННЫ, таких как:

первая колонка: AAAA

второй колонке: AB1A

и так далее ...

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

Большое вам спасибо за помощь!

Al

Мой код:

#!/usr/bin/perl 

use strict; 
use warnings; 

my @sessions = (
    "AAAA", 
    "AAAC", 
    "ABAB", 
    "ABAD" 
); 

my $length_max = 0; 
my $length_tmp = 0; 

my %columns; 

foreach my $string (@sessions){ 

    my $l = length($string); 

    if ($l > $length_tmp){ 
      $length_max = $l; 
    } 
} 

print "max legth : $length_max\n\n"; 

my $n = 1; 

foreach my $string (@sessions){ 

    my @ch = split("",$string); 

    for my $col (1..$length_max){ 
     $columns{$n}{$col} = $ch[$col-1]; 
    } 

    $n++; 
} 

foreach my $col (keys %columns) { 

    print "colonna : $col\n"; 

    my $deref = $columns{$col}; 

    foreach my $pos (keys %$deref){ 
      print " posizione : $pos --> $$deref{$pos}\n"; 
    } 

    print "\n"; 
} 

exit(0); 
+0

Что вы собираетесь делать в пятом и шестой столбцы, где отсутствуют некоторые символы? – Zaid

+0

Вы говорите, что вам нужны уникальные символы в каждом столбце.Для английского говорящего с некоторым математическим обучением это означает, что каждый столбец не должен содержать повторяющихся символов, но ожидаемые ответы для первого и второго столбцов - «AAAA» и «AB1A». Как сортировать цифры по алфавиту? Учитывая, что 'A' появляется как в начале, так и в конце ответа второго столбца, он, похоже, не сортируется вообще. –

ответ

2

Что вы делаете, вращающийся массив. Ему не нужен хэш хэша или что-то еще, просто еще один массив. Удивительно, но ни List :: Util, ни List :: MoreUtils не поставляет один. Вот простая реализация с тестом. Я предположил, что вы хотите, чтобы короткие записи заполнялись пробелами, поэтому столбцы выглядят правильно.

#!/usr/bin/perl 

use strict; 
use warnings; 

use Test::More; 
use List::Util qw(max); 

my @Things = qw(
    AAA23 
    AB1D1 
    A1BC 
    AAB212 
); 


sub rotate { 
    my @rows = @_; 

    my $maxlength = max map { length $_ } @rows; 

    my @columns; 
    for my $row (@rows) { 
     my @chars = split //, $row; 
     for my $colnum (1..$maxlength) { 
      my $idx = $colnum - 1; 
      $columns[$idx] .= $chars[$idx] || ' '; 
     } 
    } 

    return @columns; 
} 


sub print_columns { 
    my @columns = @_; 

    for my $idx (0..$#columns) { 
     printf "Column %d: %s\n", $idx + 1, $columns[$idx]; 
    } 
} 


sub test_rotate { 
    is_deeply [rotate @_], [ 
     "AAAA", 
     "AB1A", 
     "A1BB", 
     "2DC2", 
     "31 1", 
     " 2", 
    ]; 
} 


test_rotate(@Things); 
print_columns(@Things); 
done_testing; 
+0

Я не могу прочитать о вращении массива, не думая об этом сообщении Раймонда Чена: http://blogs.msdn.com/b/oldnewthing/archive/2008/09/02/8918130.aspx. Прочитав тело, прокрутите вниз до комментария «640k» для забавной части. «Вы даже можете вращаться на 10 градусов!» –

+1

Да, я тоже был разочарован, когда не нашел «транспонирование» в «List :: MoreUtils» ... – Zaid

0

Вы можете сортировать вывод %columns в коде с

foreach my $i (sort { $a <=> $b } keys %columns) { 
    print join(" " => sort values %{ $columns{$i} }), "\n"; 
} 

Это дает

A A A A 
A A A C 
A A B B 
A A B D

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

sub columns { 
    my @strings = @_; 
    my @columns; 

    while (@strings) { 
    push @columns => [ sort map s/^(.)//s ? $1 :(), @strings ]; 
    @strings = grep length, @strings; 
    } 

    @columns; 
} 

Учитывая строки из вашего вопроса, то она возвращает

A A A A 
1 A A B 
1 A B B 
2 2 C D 
1 1 3 
2

Как вы можете видеть, это несортированный и повторяет символы. С Perl, когда вы видите уникальное слово, всегда думайте о хешах!

sub unique_sorted_columns { 
    map { my %unique; 
     ++$unique{$_} for @$_; 
     [ sort keys %unique ]; 
     } 
     columns @_; 
} 

Если вы не против уничтожения информации, вы можете иметь columns сортировки и фильтрации дубликатов:

sub columns { 
    my @strings = @_; 
    my @columns; 

    while (@strings) { 
    my %unique; 
    map { ++$unique{$1} if s/^(.)//s } @strings; 
    push @columns => [ sort keys %unique ]; 
    @strings = grep length, @strings; 
    } 

    @columns; 
} 

Выход:

A 
1 A B 
1 A B 
2 C D 
1 3 
2