1

私はこのようにパックされた配列のセットを持っています:

sub pack_key {
     return pack 'N' . ('w/a*' x @_), scalar(@_), @_;
}

私はそれらをハッシュの複数値キーとして使用しているためです(つまり、ハッシュのキーは配列です)。

パックされた配列の最初のn要素が同じであるかどうかを比較するための高速な方法はありますか?または反対のことをする-最後のm個の要素が異なるかどうかを比較しますか?

解凍してsmartmatch演算子(~~)を使用するという明らかな解決策がありますが、パックされた配列で直接動作するものを探しています。

ありがとう。

4

1 に答える 1

1

長さが埋め込まれた任意の長さのデータをパックしたので、答えは2つの文字列を比較する高速な方法がないということです。必然的に、一度に1つのコンポーネントで文字列を調べる必要があります。

これが実用的な解決策です。

警告:これは、シングルバイト文字エンコードを使用するPerlのインストールによって異なります。これはほとんどの場合当てはまりますが、当てはまらない場合は、Encodeを調べて、これらの文字列がバイトとして扱われることを確認してください。

use strict;
use warnings;

my @arr1 = (1,2,3,4,5);
my @arr2 = (1,2,3,4,8);

sub pack_key {
     return pack 'N' . ('w/a*' x @_), scalar(@_), @_;
}

sub n_elements_equal {
    my ($compare_length,$k1,$k2) = @_;
    my $length1 = unpack('N',$k1);
    my $length2 = unpack('N',$k2);
    if ($length1<$compare_length or $length2<$compare_length) { return 0; }

    my $curr_pos = 4;
    my $curr_element = 1;

    while ($curr_element++ <= $compare_length)
    {
        my $el1 = unpack('w/a*',substr($k1,$curr_pos));
        my $el2 = unpack('w/a*',substr($k2,$curr_pos));
        if ($el1 ne $el2) { return 0; }
    $curr_pos += (unpack('w',substr($k1,$curr_pos)) + 1);       
    }
    return 1;
}

my $key1 = pack_key(@arr1);
my $key2 = pack_key(@arr2);

for (1..5)
{
    print "First $_ elements are " . 
        (n_elements_equal($_,$key1,$key2) ? '' : 'not ') . "equal.\n"; 
}

これは、単に開梱してスマートマッチを行うよりも優れていますか?配列が非常に長い場合は、配列全体を解凍する必要がないため、高速になります。一致するステータスを決定するまで、文字列を通過するだけです。配列がそれほど長くない場合は、おそらく何も保存されません。

デザインを変更してこれを解決する方が良いかもしれません。しかし、それはあなたがしていることに依存します。

于 2012-10-16T08:17:52.010 に答える