2009-11-12 4 views
4

Я пытаюсь написать программу для сравнения файлов. Например:Логика для сравнения файлов

file1

1 
2 
3 
4 
5 

file2

1 
2 
@ 
3 
4 
5 

Если я построчно, я получаю:

1 == 1; 
2 == 2; 
3 != @; 
4 != 3; 
5 != 4; 
    != 5; 

Но, правда в том, что единственное различие между файлами - @. Я хочу получить примерно следующее:

1 == 1; 
2 == 2; 
    != @; 
3 == 3; 
4 == 4; 
5 == 5; 

Каков наилучший способ сделать это? без использования каких-либо внешних приложений, таких как diff, fc и т. д.

+0

узнать о и время –

ответ

1

Python имеет очень удобную библиотеку для сравнения последовательностей, называемых difflib. Основной класс SequenceMatcher принимает две последовательности python и дает вам (между прочим) последовательность кодов операций, сообщающую вам, как вы будете получать от первой последовательности ко второй (т. Е. Различия). Они имеют вид:

  • Заменить этот блок с этим одним
  • Вставьте блок
  • удалить блок
  • Скопировать блок (так называемый «равно»)

Эти ссылки блоков, указав индексы в исходные последовательности. Это может быть применено к строкам в файле или символам в строке или что-то еще, что вы можете превратить в последовательность в python.

2

Интересно, поможет ли вам в этой ситуации Levenshtein Distance. Это дало бы вам, насколько похожи эти два файла, но я не знаю, можете ли вы использовать нуль в @. Что-то не смотря ни на что.

1

Я считаю, что вы ищете расстояние между двумя строками, может быть, this может вам помочь.

1

Если вы не пишете программу, чтобы узнать что-то об алгоритмах diff, но просто ищете решение, вы должны попробовать diff-match-patch. Он содержит реализации алгоритмов diff и patch в разных языках программирования (cpp, C#, java, javascript, python).

Я попробовал свою версию java, и это сработало как шарм.

1

Немного устаревший, я полагаю :), но я наткнулся на это сообщение, потому что искал помощь по той же проблеме: у меня есть два файла, которые я показываю бок о бок, и я должен отмечать линии, которые не совпадают красным цветом.

Mine - это немного особенный случай, потому что 1) порядок не важен, и 2) каждая строка гарантирована только один раз (текст - это файл лицензии с определениями, строка за строкой).

Оказалось, что самый простой способ сделать это было просто сделать списки двух файлов, LS1 и LS2, и сделайте следующее (в псевдокоде):

i = 0; 
while (i < ls1.count) { 
    n = ls2.find(ls1[i]); 
    if (n >= 0) { 
     // found match in ls2 
     ls1.Delete(i); 
     ls2.Delete(n); 
    } else 
     i++; 
} 

Разъяснения, для каждой линии ls1, посмотрите, есть ли соответствующая строка в ls2. Если это так, удалите оба. То, что у вас осталось, - это просто различия, и вы можете легко пометить эти строки в исходном тексте.

Чрезвычайно просто, без библиотек. Только мои два цента ...

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