5

可変サイズの文字列のセットがあります。次に例を示します。

AAA23

AB1D1

A1BC

AAB212

私の目標は、アルファベット順に、次のようなCOLUMNS用に収集された一意の文字を使用することです。

最初の列:AAAA

2列目:AB1A

等々...

この瞬間、ハッシュのハッシュを介して投稿を抽出することができました。しかし今、どうすればデータを並べ替えることができますか?ハッシュのハッシュごとに新しい配列を作成できますか?

助けてくれてありがとう!

アル

私のコード:

#!/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);
4

2 に答える 2

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;
于 2010-07-08T18:42:17.227 に答える
0

%columnsコード内の出力を次のように並べ替えることができます

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

これは与える

ああああ
AAAC
AABB
AABD

しかし、ハッシュキーとしてインデックス番号を使用すると、代わりに配列を使用する必要があるので、そうしましょう。列を取得するには、使用します

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

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

  @columns;
}

質問の文字列を指定すると、返されます

ああああ
1 AAB
1ABB
2 2 CD
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;
}

出力:

あ
1AB
1AB
2CD
1 3
2
于 2010-07-08T18:57:01.230 に答える