2

DBには多くの数字があります。例えば、

448-48-00 #(from 00 to 99, 100 numbers)
336-87-00 #(same as above)
449-20-00 #(from 000 to 999, 1000 numbers)

これらの数値のベースを取得する必要があります。この例では、44848、33687、および 4492 を取得する必要があります。

私はこのコードを持っていますが、それを終了する方法がわかりません:)

#!/usr/bin/perl

use v5.10;
use warnings;

my @p = 4484900..4484999;
push @p, $_ for 3368700..3368799;

my $data;

do {
    my $z = 1;
    while($z++ <= length $_) {
        $data->{substr $_, 0, $z}++;
    }
} for @p;

foreach my $key (sort { $data->{$a} <=> $data->{$b} } (keys %$data)) {
    say $key if $data->{$key} > 99;
}

最長の要素を取得し、最長のコードに含まれる短い要素を削除する必要があります

4

2 に答える 2

3
#!/usr/bin/env perl -l

use strict; use warnings;

my $prefix = "1234";

foreach (<DATA>) {
    print $prefix . $1 . $2 if m/^(\d{3})-(\d{1,2})/;
}

__DATA__
448-48-## (00-99)
336-87-## (-||-)
449-2#-## (0-9, 00-99)

出力

123444848
123433687
12344492

より高い値が必要な場合:

#!/usr/bin/env perl -l

my @arr;
my $prefix = "1234";
my $higher_prefix = 0;

foreach (<DATA>) {
    my $cur = $1 . $2 if m/^(\d{3})-(\d{1,2})/;
    $higher_prefix = $prefix . $cur if $cur > $higher_prefix;
}

print $higher_prefix;

__DATA__
448-48-## (00-99)
336-87-## (-||-)
449-2#-## (0-9, 00-99)

出力

123444848
于 2012-11-21T07:26:26.423 に答える
1

私はあなたがコードで何をしているのかを理解し、あなたが望むようにそれを改善しようとしました。免責事項: それほど単純ではありません。たとえば、グループ化したくないが、代わりにグループ44848..4492...したいなどをアルゴリズムが確認する方法はありません。しかし、これはすでにあなたを助けているかもしれません。44.....4492...44924..

336重要な部分は、たとえば のカウントを調べて3368削除する「スマートフィルター」だと思います336(336の自明なスーパーセットをマークします3368)。stateここで重要なのは、変数とともに文字列ソートを行うことです$last:

#!/usr/bin/env perl

use strict;
use warnings;
use feature qw(say state);
use List::Util 'shuffle';

# shuffled phone numbers (don't make it too easy)
my @numbers = shuffle (
    4484800 .. 4484899,
    3368700 .. 3368799,
    4492000 .. 4492999
);

my %count = ();

# import phone numbers
foreach my $number (@numbers) {

    # work on all substrings from the beginning
    for (my $pos = 1; $pos <= length $number; $pos++) {
        my $prefix = substr $number, 0, $pos;
        $count{$prefix}++; # increase the number of equal prefixes
    }
}

# smart filter
foreach my $prefix (sort {$a cmp $b} keys %count) {
    state $last //= 'nothing';

    # delete trivial super sets
    if ($prefix =~ /^\Q$last/ and $count{$last} == $count{$prefix}) {
        delete $count{$last};
    }

    # delete trivial sets
    if ($count{$prefix} == 1) {
        delete $count{$prefix};
        next;
    }

    # remember the last prefix
    $last = $prefix;
}

# output
say "$_ ($count{$_})" for sort {
    $count{$b} <=> $count{$a} or $a cmp $b
} keys %count;

出力は絶対に正しいですが、まだあなたが望むものではありません:

44 (1100)
4492 (1000)
33687 (100)
44848 (100)
44920 (100)
44921 (100)
44922 (100)
44923 (100)
44924 (100)
44925 (100)
44926 (100)
44927 (100)
44928 (100)
44929 (100)
336870 (10)
(large list of 10-groups)

したがって、10 グループを取り除きたい場合は、次のように変更できます。

# delete trivial sets
if ($count{$prefix} == 1) {
    delete $count{$prefix};
    next;
}

# delete trivial sets
if ($count{$prefix} <= 10) {
    delete $count{$prefix};
    next;
}

出力:

44 (1100)
4492 (1000)
33687 (100)
44848 (100)
44920 (100)
44921 (100)
44922 (100)
44923 (100)
44924 (100)
44925 (100)
44926 (100)
44927 (100)
44928 (100)
44929 (100)

これはとても良さそうです。4492-100-groups と44-1100- groupsをどうするかはあなた次第です。4492長さに応じて 100 個のグループを削除する場合は、大きなグループを優先してグループを削除することもでき44ます。

于 2012-11-21T10:08:41.547 に答える