【问题标题】:Perl: Frequency of words and a top ten list of the wordsPerl:单词的频率和单词的前十名列表
【发布时间】:2023-03-26 12:23:01
【问题描述】:

我正在努力制作一个 perl 脚本,请注意我对此很陌生..

这是我试图实现的目标:制作一个脚本,该脚本采用 .txt 文件并计算文件中的每个单词。并且当它被计算时,如果文件中的前 10 个单词显示每个单词我计算了多少次,那么这些单词会列出一个列表。

这就是我到目前为止所做的,我能够让脚本计算单词以及它们出现的次数。现在我需要进入前十名,我真的不知道在哪里以及如何去做。这是一个家庭作业,所以我不希望/期望你为我解决它,只是给我一些关于从哪里开始的指示。

感谢您的帮助(提前)


10 月 15 日更新

好的,一切都很好,但是..

现在它只是在一行中打印所有内容。我需要它像这样打印它:

4 字
3 下一个词
2 下一个单词

你明白了..


我想我明白了……我想:P


....................................

#! /usr/bin/perl

use utf8;


print ("Vilken fil?\n");
my $filen = @ARGV ? shift(@ARGV) : <STDIN>;
chomp $filen;

my %freq;

open my $DATA, $filen or die "Hittade inte den filen!";


while(<$DATA>) {

    s/[;:()".,!?]/ /gio;    
    foreach $word(split(' ', lc $_)) {  
    $freq{$word}++;                  
     }
}

@listing = (sort { $freq{$b} <=> $freq{$a} } keys %freq)[0..9];
foreach my $word (@listing )
    { print $freq{$word}." $word\n"; };

【问题讨论】:

  • 这句话中,单词句子出现了多少次? (你的代码会说一个。)
  • Regex 对我来说似乎有缺陷。在字符串Hello? Hello! Is somebody here? 中,您将Hello 视为最常用的词。也许/[^\w-]+/(或至少/\s+/ 包含换行符)会产生更好的结果。
  • split ' '(按空格分割)优于split / /(按空格分割)。不过,除了这种特殊情况,我确实鼓励 split /.../ 超过 split '...'
  • 如果有机会使用标点符号,这篇文章可能会对您有所帮助,以便您只抓住单词。 stackoverflow.com/questions/3614686/…

标签: perl


【解决方案1】:

查看 Perl 排序功能的文档:

http://perldoc.perl.org/functions/sort.html

它有一个表单,可以让您指定一个代码块来定义元素的顺序。您可以使用它来按频率而不是按单词的字母顺序对列表进行排序。

文档包括这个例子:

# this sorts the %age hash by value instead of key
# using an in-line function
@eldest = sort { $age{$b} <=> $age{$a} } keys %age;

您应该能够根据自己的问题调整这种模式。

获得前十名列表的最有效方法可能是随时跟踪前十名:每次计算计数时,检查它是否属于前十名,如果是,则将其插入正确的位置,可能会敲掉列表中的底部项目。这样,无论字典有多大,您一次只需要跟踪十个单词的顺序。不过,我不知道您是否需要这种额外的效率。

顺便说一句,我在几次求职面试中都看到过这种问题,所以掌握一下是一件好事。

【讨论】:

  • 谢谢!我会试一试。我仍然感到很困惑,但这并没有什么不寻常的.. =)
  • 我已经更新了我的代码,但我需要一些帮助打印。就像现在一样,它只是在一行中打印所有内容。我需要它像这样打印它:4 个单词,3 个下一个单词,2 个下一个单词,等等。
【解决方案2】:

基于 Nate 的回答,您可以使用切片提取前 10 个元素:

@eldest = (排序 { $age{$b} $age{$a} } 键 %age)[0..9];

【讨论】:

  • 如果少于十个,则在末尾添加一个undef。使用splice(@eldest, 10) if @eldest &gt; 10; 而不是列表切片可以避免这个问题。
  • 好的,我试了一下,我想我快到了。一切正常,但我需要一些帮助打印。就像现在一样,它只是在一行中打印所有内容。我需要它像这样打印它:4 个单词,3 个下一个单词,2 个下一个单词,等等……
  • 你可以做一个foreach my $word ( @sorted_words ) { print $words_hash{$word}." $word\n"; }
  • $words_hash 是哈希,其中键是单词,值表示出现的次数
  • 是的,就是这样 - 你可以在你的印刷品中更神秘地使用一个帖子 foreach print $freq{$_}." $_\n" foreach (@listing);
【解决方案3】:

哈,当我读完你的问题描述时,我知道这是某种家庭作业! :)

下一步,您必须扫描 %count 哈希并确定哪些单词出现次数最多。

最幼稚的方法是扫描列表 10 次;每次,找到计数最高的一个并将其存储在前十名列表中,然后将其从 %count 中删除(或将其设置为 0 也可以)。

如果你想更有野心,你可以实现一个排序函数,对 %count 个条目进行排序,然后前 10 个将放在一起。

我的 Perl 生锈了,但 Perl 库甚至可能为您提供一些功能。一般来说,绝对值得您花时间浏览一下图书馆参考资料以熟悉可用的内容。

【讨论】:

  • 谢谢!我也会试一试:)
  • 嗯,其他的答案都比我的好。我应该预料到这一点;自从我使用 Perl 以来已经有好几年了。我想知道你正在上什么样的课程,使用 Perl 而不是 Python 或 Ruby,两者都或多或少地取代了 Perl,受到现代人的青睐。
  • 嗯,它被称为脚本。我们在这门课上学习 Python、Perl 和 AWk。
  • 啊,那太好了。你可能仍然会在野外看到很多 Perl。
猜你喜欢
  • 1970-01-01
  • 2013-02-02
  • 2011-04-24
  • 2014-10-16
  • 2019-02-01
  • 1970-01-01
  • 2013-12-28
相关资源
最近更新 更多