我不确定如何解释这一点,所以我将从一个例子开始。
给定以下数据:
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 将只有自己的链接——我不需要用数据中的第二个字母来分解它.
由于我的数据集不会经常更改,因此我可以使用静态的“每个范围的最大值”,但也可以动态计算它。此外,数据集不会以数字开头 - 保证以 AZ 的字母开头。
我已经开始为此构建算法,但它变得如此混乱,我重新开始。我不知道如何在 google 上搜索这个 - 我不确定这个方法叫什么。
这是我开始的:
#!/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。
提前致谢!