我是Perl的新手,我正在尝试写一个单词频率计数器作为学习练习。
但是,在我处理之后,我无法在下面的代码中找出错误。这是我的代码:
$wa = "A word frequency counter.";
@wordArray = split("",$wa);
$num = length($wa);
$word = "";
$flag = 1; # 0 if previous character was an alphabet and 1 if it was a blank.
%wordCount = ("null" => 0);
if ($num == -1) {
print "There are no words.\n";
} else {
print "$length";
for $i (0 .. $num) {
if(($wordArray[$i]!=' ') && ($flag==1)) { # start of a new word.
print "here";
$word = $wordArray[$i];
$flag = 0;
} elsif ($wordArray[$i]!=' ' && $flag==0) { # continuation of a word.
$word = $word . $wordArray[$i];
} elsif ($wordArray[$i]==' '&& $flag==0) { # end of a word.
$word = $word . $wordArray[$i];
$flag = 1;
$wordCount{$word}++;
print "\nword: $word";
} elsif ($wordArray[$i]==" " && $flag==1) { # series of blanks.
# do nothing.
}
}
for $i (keys %wordCount) {
print " \nword: $i - count: $wordCount{$i} ";
}
}
既不打印“这里”,也不打印。我并不担心此时的优化,尽管在这个方向上的任何输入也会受到高度赞赏。
答案 0 :(得分:6)
这是一个很好的例子,如果你只是向它寻求帮助,Perl会帮助你弄清楚出了什么问题。习惯于总是添加行:
use strict;
use warnings;
到你的Perl程序的顶部。
答案 1 :(得分:1)
拳头,
$wordArray[$i]!=' '
应该是
$wordArray[$i] ne ' '
根据Perl documentation比较字符串和字符。基本上使用数字运算符(==
,>=
,...)表示数字,使用字符串运算符(eq
,ne
,lt
,...)。< / p>
另外,你可以做到
@wordArray = split(" ",$wa);
而不是
@wordArray = split("",$wa);
然后@wordArray
不需要进行不稳定的字符检查,你就不会遇到问题。 @wordArray
将被分成已经存在的单词,您只需要计算出现次数。
答案 2 :(得分:1)
你似乎在Perl中编写C语言。区别不仅仅是风格。通过将字符串爆炸成单个字符数组,您的脚本内存占用也会爆炸。
此外,你需要考虑一个单词的构成。下面,我并不是说任何\w+
都是单词,而是指出\S+
和\w+
之间的区别。
#!/usr/bin/env perl
use strict; use warnings;
use YAML;
my $src = '$wa = "A word frequency counter.";';
print Dump count_words(\$src, 'w');
print Dump count_words(\$src, 'S');
sub count_words {
my $src = shift;
my $class = sprintf '\%s+', shift;
my %counts;
while ($$src =~ /(?<sequence> $class)/gx) {
$counts{ $+{sequence} } += 1;
}
return \%counts;
}
输出:
--- A: 1 counter: 1 frequency: 1 wa: 1 word: 1 --- '"A': 1 $wa: 1 =: 1 counter.";: 1 frequency: 1 word: 1