web-dev-qa-db-ja.com

接尾辞が付いた重複する単語を削除するにはどうすればよいですか?

可変長のソートされていない単語のリストを比較し、接尾辞が付いている重複する単語を削除するにはどうすればよいですか?

単語リストの例:

    iron        
    curl
    curled
    railroad
    curler
    curling
    curls
    irons
    pan
    pans
    park
    parker
    parks
    parked
    railroads

出力例:

    iron
    curl
    railroad
    pan
    park

4文字または8文字だけでなく、すべての単語の長さが異なります。接尾辞を含む単語を検索して印刷する方法は知っていますが、接尾辞が付いている単語のリストを比較し、接尾辞が付いていない単語がある場合は、接尾辞が付いている単語を削除する方法がわかりません。ソート順を変更せずにリスト。

4
J363

別の質問で私のために作成されたこのソリューションユーザー「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
0
J363

これには、Wordステミングアルゴリズムが必要になる場合があります。たとえば、Lingua :: Stemは、Perlで記述されたWordステマーモジュールです。

これがニーズに合う場合は、 CPAN経由のLingua :: Stem をインストールする必要があります。次に、次の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

明らかに、これは、場合によってはあなたのものとは異なるWordサフィックスのステマーの解釈のために、あなたのサンプル出力からわずかに逸脱します。これがアプリケーション内の適度な数の単語にのみ影響する場合は、add_exceptionsメソッドを使用して例外を定義できます。

...
$s->add_exceptions( { "parker" => "park", "curler" => "curl" } );
$stemmed = $s->stem_in_place( @words );
...
7
Guido