Я не уверен, как это объяснить, поэтому я просто начну с примера.Как я могу сгенерировать набор диапазонов от первых букв списка слов в Perl?
Учитывая следующие данные:
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 будет просто своя связь - мне не нужно разбить ее на вторую букву в данных.
Поскольку мой набор данных не будет меняться слишком часто, мне будет хорошо со статическим «максимумом за диапазон», но было бы неплохо, чтобы это было рассчитано динамически. Кроме того, набор данных не будет начинаться с цифр - он гарантированно начнется с буквы A-Z.
Я начал строить алгоритм для этого, но он продолжает становиться настолько грязным, что я начинаю все заново. Я не знаю, как искать 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.
Заранее благодарен!
'мой% index_frequency' будет лучше. Тогда вам не нужно иметь 'if ($ index_frequency ....' –
Посмотрите на мое решение снова, так как я добавил еще один подход, который, я думаю, лучше подходит вашим потребностям. –