Как мне сопоставить порядок строк между двумя документами в Perl? - PullRequest
3 голосов
/ 24 мая 2010

У меня проблема с созданием программы PERL для сопоставления слов в двух документах. Допустим, есть документы A и B.

Итак, я хочу удалить слова в документе A, которых нет в документе B.

Пример 1 :

A: Я ем пиццу

Б: Она идет на рынок и ест пиццу

результат: есть пиццу

пример 2 : A: есть пиццу

B: пицца ест

Результат: пицца (порядок слов релевантен, поэтому слово «есть» удаляется.)

Я использую Perl для системы, и предложения в каждом документе не слишком большие, поэтому я думаю, что не буду использовать SQL

А программа является подпрограммой для автоматической оценки эссе по индонезийскому языку (бахаса)

Thanx, Извините, если мой вопрос немного сбивает с толку. Я действительно новичок в этом мире :) 1027 *

1 Ответ

1 голос
/ 24 мая 2010

ОК, в данный момент у меня нет доступа, так что это не гарантирует 100% или даже компиляцию, но должно предоставить достаточное руководство:

Решение 1 : (порядок слов не имеет значения)

#!/usr/bin/perl -w

use strict;
use File::Slurp;

my @B_lines = File::Slurp::read_file("B") || die "Error reading B: $!";
my %B_words = ();
foreach my $line (@B_lines) {
    map { $B_words{$_} = 1 } split(/\s+/, $line);
}
my @A_lines = File::Slurp::read_file("A") || die "Error reading A: $!";
my @new_lines = ();
foreach my $line (@A_lines) {
    my @B_words_only = grep { $B_words{$_} } split(/\s+/, $line);
    push @new_lines, join(" ", @B_words_only) . "\n";
}
File::Slurp::write_file("A_new", @new_lines) || die "Error writing A_new: $!";

Это должно создать новый файл "A_new", который содержит только слова A, которые находятся в B.

В этом есть небольшая ошибка - он заменит любой пробел в файле A одним пробелом, поэтому

    word1        word2              word3

станет

word1 word2 word3

Это можно исправить, но это очень раздражает, поэтому я не стал беспокоиться, если только вы абсолютно не потребуете 100% правильного сохранения пробелов

Решение 2 : (порядок слов имеет значение, НО вы можете печатать слова из файла A, не заботясь о сохранении пробелов вообще)

#!/usr/bin/perl -w

use strict;
use File::Slurp;

my @A_words = split(/\s+/gs, File::Slurp::read_file("A") || die "Error reading A:$!");
my @B_words = split(/\s+/gs, File::Slurp::read_file("B") || die "Error reading B:$!");
my $B_counter = 0;
for (my $A_counter = 0; $A_counter < scalar(@A_words); ++$A_counter) {
    while ($B_counter < scalar(@B_words)
        && $B_words[$B_counter] ne $A_words[$A_counter]) {++$B_counter;}
    last if $B_counter == scalar(@B_words);
    print "$A_words[$A_counter]";
}

Решение 3 (зачем нам снова нужен Perl? :))

Вы можете сделать это тривиально в оболочке без Perl (или с помощью вызова system () или обратных галочек в родительском скрипте Perl)

comm -12 A B | tr "\012" " " 

Чтобы позвонить из Perl:

my $new_text = `comm -12 A B | tr "\012" " " `;

Но посмотрите мой последний комментарий, почему это может считаться "плохим Perl" ... по крайней мере, если вы делаете это в цикле с очень большим количеством итерируемых файлов и заботитесь о производительности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...