如何比较可变长度的未排序单词列表并删除具有后缀的重复单词?
单词列表示例:
iron
curl
curled
railroad
curler
curling
curls
irons
pan
pans
park
parker
parks
parked
railroads
示例输出:
iron
curl
railroad
pan
park
这些单词都有不同的长度,而不仅仅是四个或八个字母。我知道如何搜索和打印包含后缀的单词,但我不确定如何比较单词列表,其中一些单词具有后缀,然后删除带后缀的单词(如果有一个单词没有后缀)列表,而不改变排序顺序。
答案1
为此,您可能需要词干算法。例如,语言::词干是一个用 Perl 编写的词干分析器模块。
如果这符合您的需求,您需要安装Lingua::Stem 通过 CPAN。然后,以下 Perl 脚本将完成这项工作:
#!/usr/bin/perl
require Lingua::Stem;
# Read lines into array
chomp(my @words = <STDIN>);
# Stem in English
my $s = Lingua::Stem->new( -locale => 'en' );
my $stemmed = $s->stem_in_place( @words );
# Output result of stemmed words with duplicates removed
my $oldw = undef;
foreach $w (sort @$stemmed) {
print "$w\n" unless ($w eq $oldw);
$oldw = $w;
}
输出示例:
$ ./stem.pl < inputfile
curl
curler
iron
pan
park
parker
railroad
显然,这与您的示例输出略有不同,因为词干分析器对单词后缀的解释在某些情况下与您的不同。如果这仅影响应用程序中的中等数量的单词,则可以使用以下add_exceptions
方法定义异常:
...
$s->add_exceptions( { "parker" => "park", "curler" => "curl" } );
$stemmed = $s->stem_in_place( @words );
...
答案2
用户“123”在另一个问题上为我创建的这个解决方案能够可靠地去除后缀,而不会破坏单词。我想回来回答这个问题,以便任何寻求类似解决方案的人都能得到一个好的答案。
awk 'FNR==NR{a[$0 "s"]++;next}!($0 in a)' file.txt file.txt
awk 'FNR==NR{a[$0 "ed"]++;next}!($0 in a)' file.txt file.txt
awk 'FNR==NR{a[$0 "ing"]++;next}!($0 in a)' file.txt file.txt
awk 'FNR==NR{a[$0 "ness"]++;next}!($0 in a)' file.txt file.txt
awk 'FNR==NR{a[$0 "er"]++;next}!($0 in a)' file.txt file.txt