約10,000個の数字を含む配列SPLNOがあります。次に、MDN.TXTファイル(約1.5lacレコードを含む)から配列で加入者番号を検索したいと思います。加入者番号が配列に見つかった場合は、次のようにします。私の問題は、数値に対して10kレコードの配列全体を取得するため、時間がかかることです。したがって、1.5lacレコードの場合は繰り返されます(1.5lac * 10K)。効率的な方法を提案してください。
SPLNO.TXT 例:
918542054921|30|1|2
918542144944|12|1|2
918542155955|12|1|2 918542166966|12 |1|2 918542355955|12|
2 9 1 8542455955|12|1|2 918542555955 |12|1| 2 918542955955|12|1|2
MDN.TXTの例:
8542166966
8542355955
8542555955
awk -F"|" 'FNR==1 { ++counter}
counter==1 {SPLNOPULSE[$1]=$4;SPLNOAMT[$1]=$3;SPLNOMAXLEN[$1]=$2;next}
{
for ( mdn in SPLNOMAXLEN)
{
if ( ($1 ~ "^"mdn && length($1) <=SPLNOMAXLEN[mdn]) || ("91"$1 ~ "^"mdn && length("91"$1) <=SPLNOMAXLEN[mdn]) )
{
print found
}
else
print not found
}
} ' SPLNO.TXT MDN.TXT
答え1
これは使用する1つの方法ですperl
。
#!/usr/bin/perl
# read the subscribers
open(A,"<","SPLNO.TXT");
while(<A>) {
chomp;
@a=split(/\|/,$_);
$splnopulse{$a[0]}=$3;
$splnoamt{$a[0]}=$2;
$splnomaxlen{$a[0]}=$1;
}
close A;
# read the mdn, looking for matches
open(B,"<","MDN.TXT");
while(<B>) {
chomp;
@b=split(/\|/,$_);
foreach $mdn (keys %splnomaxlen) {
if($mdn eq $b[0] || "$mdn" eq "91" . $b[0]) {
print "found\n";
} else {
print "not found\n";
}
}
}
close B;
答え2
ファイル1の各行に対してファイル2全体を検索するアルゴリズムの時間パフォーマンスはですm * n
。ここではm
、ファイル2の行数、およびn
ファイル1の行数です。これは非常に高速ではなく、非常に遅くなります。
解決策は、最初に各ファイルを並べ替えてから(例:* log(n)時間)、次のように2つのファイル間の行を比較することです。
- i = 1(ファイル1の行番号)、j = 1(ファイル2の行番号)のままにします。
a=(file 1)[line i]
それと比較してみてくださいb=(file 2)[line j]
。if a<b;
その後、iを増やして2に戻ります(ファイル1の終わりを確認)。if a>b;
その後、jを増やして2に戻ります(ファイル2の終わりを確認してください)。if a=b;
これは一致します。印刷してiを増やします。
実行時間は次のとおりです(n + m
すべての行を読み取るのにかかる時間)。
これにより、プロセス全体の実行時間は次のようになりますn*log(n) + m*log(m) + n + m
。
ここで O(n) はn * log(n)
次のようになりますn > m
。
ソートは簡単です。sort
各ファイルに対して次のコマンドを使用できます。
sort -t '|' -k 1 file01.csv > file01-sorted.csv
次に、awkで上記のプロセスを実行します。
編集:SPLNOの10,000個の数字がすべて固有の場合(重複なし)と思いました。また、MDN.TXTにも独自のレコードがあります。その後、2つのファイルをリンクして重複した値を検索すると、回避策も提供されます。これは単純な平等に適用されます。ほとんどの場合、正規表現の一致はこれらの概念を破ります。