使用Perl实现大小写排序遇问题:无法提取大写单词
问题分析与解决
你的代码存在两个核心问题,导致无法提取并区分大写单词:
- 丢失大小写信息:统计阶段直接把所有单词转成小写(
lc($word))作为哈希键,原始的大写单词信息被完全覆盖,后续根本无法区分大小写变体。 - 排序逻辑混乱:排序部分的
sort {"\$a" cmp uc"\$b"} lc($word)完全不符合Perl语法——lc($word)是单个字符串,sort无法对单个元素排序,且比较逻辑完全错误。
修正后的代码
统计单词(保留大小写信息)
my %word_stats; my $filename = "electricity.txt"; # 增加文件打开错误处理,避免静默失败 open my $fh, '<', $filename or die "无法打开文件 $filename: $!"; while (my $line = <$fh>) { chomp $line; # 用非单词字符分割,提取纯单词(跳过分割产生的空字符串) foreach my $word (split /\W+/, $line) { next if $word eq ''; my $lower_word = lc($word); # 用小写单词分组统计次数,同时保存该分组下的所有大小写变体 $word_stats{$lower_word}{count}++; $word_stats{$lower_word}{variants}{$word} = 1; } } close $fh;
按要求排序输出
print "\n\n按字母排序,首字母相同的大写单词排在小写单词前面:\n"; # 先按小写字母顺序对分组键排序 foreach my $lower_key (sort keys %word_stats) { # 对当前分组内的大小写变体排序:大写在前,同组单词按字母顺序排列 my @sorted_words = sort { uc($a) cmp uc($b) || $a cmp $b } keys %{$word_stats{$lower_key}{variants}}; foreach my $word (@sorted_words) { printf "%-31s 出现次数: %d\n", $word, $word_stats{$lower_key}{count}; } }
关键修正说明
- 保留大小写信息:用小写单词作为分组键统计次数,同时在分组内存储所有原始大小写的单词变体,既保证统计准确,又不丢失大小写特征。
- 合理分割单词:使用
/\W+/分割文本,避免将标点符号和单词混为一谈(比如原代码会把"问题是:"当成一个单词,修正后能提取出纯单词"问题是")。 - 正确排序逻辑:先按不区分大小写的规则分组,同一分组内再通过
$a cmp $b让大写单词排在前面(大写字母的ASCII码小于小写)。
内容的提问来源于stack exchange,提问作者baishakh22
相关产品推荐
相关产品推荐

