如何从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 单击“D-G”链接将显示: Elderberry Grapefruit Grapes 在上面的我的范围列表中,我覆盖了完整的字母 – 我想这不是完全必要的 – 我也可以使用这个输出: A B C E-G K-N P R-S 显然我的数据集不是水果,我将有更多的数据(大约1000-2000项),我的“每个范围的最大值”将超过3. 我也不太担心不平衡的数据 – 所以如果我40%的数据以“S”开头,那么S只会有自己的链接 – 我不需要将数据中的第二个字母分解. 由于我的数据集不会经常更改,我可以使用静态“每个范围的最大值”,但是动态计算也是很好的.此外,数据集不会以数字开头 – 保证以A-Z的字母开头. 我已经开始为此构建算法,但是我开始变得如此混乱.我不知道如何搜索谷歌这个 – 我不知道这个方法叫什么. 这是我开始的: #!/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,1 ) ); $index_frequency->{$first_letter}++; } foreach my $letter ( sort keys %{$index_frequency} ) { if ( $index_frequency->{$letter} ) { # build $ranges here } } 我的问题是我继续使用一堆全局变量来跟踪计数和之前检查的字母 – 我的代码变得非常混乱非常快. 有人能给我一个正确的方向吗?我想这更像是一个算法问题,所以如果你没有办法在Perl中做到这一点,伪代码也会起作用,我想 – 我可以将它转换为Perl. 提前致谢! 解决方法
基本方法:
#!/usr/bin/perl -w use strict; use autodie; my $PAGE_SIZE = 3; my %frequencies; open my $fh,'data'; while ( my $l = <$fh> ) { next unless $l =~ m{A([a-z])}i; $frequencies{ uc $1 }++; } close $fh; my $current_sum = 0; my @letters = (); my @pages = (); for my $letter ( "A" .. "Z" ) { my $letter_weigth = ( $frequencies{ $letter } || 0 ); if ( $letter_weigth + $current_sum > $PAGE_SIZE ) { if ( $current_sum ) { my $title = $letters[ 0 ]; $title .= '-' . $letters[ -1 ] if 1 < scalar @letters; push @pages,$title; } $current_sum = $letter_weigth; @letters = ( $letter ); next; } push @letters,$letter; $current_sum += $letter_weigth; } if ( $current_sum ) { my $title = $letters[ 0 ]; $title .= '-' . $letters[ -1 ] if 1 < scalar @letters; push @pages,$title; } print "Pages : " . join( ",",@pages ) . "n"; 问题在于它输出(来自您的数据): Pages : A,B,C-D,E-J,K-O,P,Q-Z 但我认为这实际上是好方法:)你可以随时将for循环更改为: for my $letter ( sort keys %frequencies ) { 如果你需要. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- Go语言middleware:Web中间件
- perl – 为什么我需要知道有多少测试我将运行Test :: More?
- Delphi的Socket I/O模型全接触(2)
- 用 Groovy 进行 Ant 脚本编程
- Perl 与 Python 之间的一些异同
- VB 6 / .NET互操作最近是否被Windows更新破坏了?
- 初学 Delphi 嵌入汇编[21] - Delphi 的其他整数类型
- [字符串][第二阶段-字符串处理][HDOJ-2031]A + B Again
- php – Laravel Blade – 通过@include或@yield传递变量
- Django date__range([start,end])其中不包括end时间