我正在编写脚本来获取和打印段落中最高频率的独特单词。
有关代码 - 请参阅附件。
my $freq;
my $word;
my $textdata = <<"END_MSG";
mm mm mm mm kk kk kk kkkk kk To pp pp pp pp pp pp.
END_MSG
foreach $word ( split ( ' ', lc $textdata)
{
$freq{$word}++;
#print $freq{$word};
#print "..";
}
use sort 'stable';
my @listing = ( sort { $freq{$b} <=> $freq{$a} } keys %freq)[0..5];
foreach my $word ( @listing )
{
print $freq{$word}." $word\n";
};
输出1:
5 pp
4 mm
4 kk
1 pp.
1 to
1 kkkk
输出2:
5 pp
4 kk
4 mm
1 pp.
1 to
1 kkkk
单词mm
,kk
的频率为4 - 但每当订单变化时我正在运行。
我希望输出保持不变。
我如何根据情况进行排序?
关心, 拉姆。
答案 0 :(得分:3)
是的,这里的问题是 - 你试图对两个没有相对排序的值进行排序。
因此,您的结果基于keys
的退货订单,按定义随机(ish)。就sort
而言,这两者是等价的,因此它们出现的方式无关紧要。
如果多次运行keys %freq
,您将获得不同的关键订单。因为有时kk
会在mm
之前出现 - 因为就sort
而言,它们是相同的,因为它们具有相同的频率 - 这就是为什么你得到你做的。
所以你需要的是一个二级排序,这是一致的。比如 - 例如 - 按字母顺序排序如果频率相同。
有用 - 我们可以使用<=>
与||
运算符相结合的事实让您链接条件。因为如果你这样做;
$condition1 || $condition2;
如果为“true”则返回条件1 - 如果为假则返回条件2。 <=>
会返回1
,0
或-1
。这里只有0
为false,所以你可以这样做:
$a <=> $b || $a cmp $b
或者在你的情况下:
$freq{$b} <=> $freq{$a} || $a cmp $b
像这样:
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
my @words = qw ( mm mm mm mm kk kk kk kkkk kk To pp pp pp pp pp pp nn nn );
my %freq;
$freq{$_}++ for @words;
print Dumper \%freq;
foreach my $word ( sort { $freq{$b} <=> $freq{$a}
|| $a cmp $b } keys %freq ) {
print "$word => $freq{$word}\n";
}
这将首先对频率进行排序,如果有两个具有相同频率的将按字母数字排序。因此,在kk => 4
之前mm => 4
始终总是。
您还应该在代码中注明:
你没有声明%freq
- 你应该这样做。您还应该启用use strict;
和use warnings;
,这会告诉您这一点。
use sort 'stable';
似乎没有做任何事情。这并不奇怪,因为sort
工作得很好。