2013-03-13 6 views
6

Мне нужно удалить дублированные абзацы в тексте со многими абзацами.Как сравнить два абзаца текста?

Я использую функции класса java.security.MessageDigest для вычисления значения хэша MD5 каждого абзаца, а затем добавьте это значение хеша в Set.

Если add() 'ed успешно, это означает, что последний абзац является дубликатом.

Есть ли риск такого рода?

За исключением String.equals(), есть ли другой способ сделать это?

+0

Я думаю, что это лучший подход вместо выполнения сравнения строк. –

+0

Я согласен с Равиндрой. MD5 не создает уникальные хеши. –

+0

Нужно ли им соответствовать _exactly_ или игнорировать, скажем, ведущие/конечные пробелы? –

ответ

0

Я думаю, что это хороший способ. Однако есть некоторые вещи, о которых следует помнить:

  1. Обратите внимание, что вычисление хэша является тяжелой операцией. Это может сделать вашу программу медленной, если вам нужно повторить ее для миллионов абзацев.
  2. Даже в этом случае вы могли бы получить несколько разных абзацев (с опечатками, для примера), идущими undetecetd. Если это так, вы должны нормализовать абзацы перед вычислением хэша (помещая его в нижний регистр, удаляя лишние пробелы и т. Д.).
1

Если хеш MD5 еще не установлен, это означает, что абзац уникален. Но противоположное не соответствует действительности. Поэтому, если вы обнаружите, что хэш уже находится в наборе, вы можете потенциально иметь не дубликат с тем же значением хэша. Это было бы очень маловероятно, но вам нужно будет проверить этот параграф на всех остальных, чтобы быть уверенным. Для этого были использованы String.equals.

Кроме того, вы должны очень хорошо рассмотреть то, что вы называете уникальным (относительно опечаток, пробелов, столиц и т. Д.), Но это было бы в случае любого метода.

1

Нет необходимости вычислять хеш MD5, просто используйте HashSet и попробуйте поместить сами строки в этот набор. Это будет использовать метод String#hashCode(), чтобы вычислить значение хэша для строки и проверить, уже ли он в наборе.

public Set removeDuplicates(String[] paragraphs) { 
    Set<String> set = new LinkedHashSet<String>(); 
    for (String p : paragraphs) { 
     set.add(p); 
    } 
    return set; 
} 

Использование LinkedHashSet даже сохраняет первоначальный порядок абзацев.

1

Как и другие, вы должны знать, что небольшие различия в пунктуации, пробелы, разрывы строк и т. Д. Могут сделать ваши хэши разными для абзацев, которые по существу одинаковы.

Возможно, вам следует рассмотреть менее хрупкую метрику, например, например. Cosine Similarity, который хорошо подходит для соответствия абзацам.

Приветствия,

2

Перед хэширования можно нормализовать абзацы, например, Удаление пунктуации, преобразование в нижний регистр и удаление дополнительных пробелов. После нормализации абзацы, которые только отличаются друг от друга, получат одинаковый хэш.

Смежные вопросы