これを説明する方法が正確にわからないので、例から始めます。
次のデータがあるとします。
Apple
Apricot
Blackberry
Blueberry
Cherry
Crabapple
Cranberry
Elderberry
Grapefruit
Grapes
Kiwi
Mulberry
Nectarine
Pawpaw
Peach
Pear
Plum
Raspberry
Rhubarb
Strawberry
データの最初の文字に基づいてインデックスを生成したいのですが、文字をグループ化したいと考えています。
上記のデータセットの最初の文字の頻度は次のとおりです。
2 A
2 B
3 C
1 E
2 G
1 K
1 M
1 N
4 P
2 R
1 S
サンプル データ セットは小さいので、文字を組み合わせる最大数は 3 としましょう。上記のデータを使用すると、インデックスは次のようになります。
A B C D-G H-O P Q-Z
「DG」リンクをクリックすると、次のように表示されます。
Elderberry
Grapefruit
Grapes
上記の範囲のリストでは、完全なアルファベットをカバーしています-完全に必要ではないと思います-この出力でも問題ありません。
A B C E-G K-N P R-S
明らかに、私のデータセットは実を結びません。より多くのデータ (約 1000 ~ 2000 項目) があり、「範囲ごとの最大値」は 3 を超えます。
データの偏りについてもあまり心配していません。つまり、データの 40% が「S」で始まる場合、S には独自のリンクがあるだけです。データの 2 番目の文字で分割する必要はありません。 .
私のデータセットはあまり頻繁に変更されないので、静的な「範囲ごとの最大値」で問題ありませんが、それも動的に計算するとよいでしょう。また、データセットは数字で始まることはありません - AZ からの文字で始まることが保証されています。
このためのアルゴリズムの構築を開始しましたが、非常に面倒になり、最初からやり直しています。これをグーグルで検索する方法がわかりません-このメソッドが何と呼ばれているかわかりません。
これが私が始めたものです:
#!/usr/bin/perl
use strict;
use warnings;
my $index_frequency = { map { ( $_, 0 ) } ( 'A' .. 'Z' ) };
my $ranges = {};
open( $DATASET, '<', 'mydata' ) || die "Cannot open data file: $!\n";
while ( my $item = <$DATASET> ) {
chomp($item);
my $first_letter = uc( substr( $item, 0, 1 ) );
$index_frequency->{$first_letter}++;
}
foreach my $letter ( sort keys %{$index_frequency} ) {
if ( $index_frequency->{$letter} ) {
# build $ranges here
}
}
私の問題は、一連のグローバル変数を使用して、カウントと以前の文字の調査を追跡し続けていることです。私のコードは非常に速く乱雑になります。
誰かが私に正しい方向への一歩を与えることができますか? これはどちらかというとアルゴリズムの問題だと思うので、Perl でこれを行う方法がない場合は、疑似コードでも機能すると思います。それを Perl に変換できます。
前もって感謝します!