Предыстория:
Я очень долго решал эту задачу. В ней надо было сравнить 2 версии файла и найти изменения. Содержимое файлов я решил извлекать в виде массивов и сравнивать массивы. Потом долго тупил и ошибался и в конце концов нарисовал массивы на бумажке в клеточку. Вообще, перед этим я посмотрел другой вариант решения. Но он такой сложный, что я его не осилил :) К тому же там было 2 разных алгоритма на случай если старый файл длиннее и если новый файл длиннее. Мне это не понравилось.Суть моего варианта решения:
Есть 2 одинаковых массива. По ходу текста я буду их называть "новый массив" и "старый массив". И в каждый из них могут быть вставлены новые элементы. Т.е. эталонным считается массив, соответствующий содержимому старого файла со всеми удалениями. Содержимое старого и нового файла рассматриваются как эталон со вставками. Мы проходим оба массива (содержимое старого и нового) в цикле. И если обнаруживаем вставку в одном из них - то пропускаем один шаг , чтобы одинаковые элементы сравниваемых массивов снова были рядом.Алгоритм:
Переменные: i - индекс ячейки массива с содержимым СТАРОГО файла. nI - индекс ячейки массива с содержимым НОВОГО файла. Если элементы массивов отличаются - записываем их во временные переменные: oldMismatch - элемент из стагого массива newMismatch - элемент из нового массива При переборе элементов массива возможны слеюдущие случаи:переменные oldMismatch и newMismatch пусты. Элементы в двух массивах совпадают. Записываем Type.SAME в список. Идем дальше.
переменные oldMismatch и newMismatch пусты. Элементы в двух массивах НЕ совпадают. Записываем значение из старого в oldMismatch, из нового - в newMismatch. Идем дальше.
переменные oldMismatch и newMismatch НЕ пусты. Сравниваем их с текущими элементами массива.
Делаем выводы. Записываем выводы в список (пременная lines). Пропускаем шаг цикла для одного из массивов.
3.1 oldMismatch равна текушему элементу НОВОГО массива. Это значит, что в файл добавили строку.
Значение этой строки хранится в newMismatch. Так и запишем.
lines.add(new LineItem(Type.ADDED, newMismatch)); lines.add(new LineItem(Type.SAME, oldMismatch));
Так как в массиве с содержимым нового файла есть дополнительный элемент, нужно сдвинуть новый массив на 1 элемент вперед относительно старого.
Поэтому СТАРЫЙ массив пропускает 1 шаг цикла.
i--;
3.2 newMismatch равна текущему элементу СТАРОГО массива. Это значит, что из файла была удалена строка. Записываем.
lines.add(new LineItem(Type.REMOVED, oldMismatch)); lines.add(new LineItem(Type.SAME, newMismatch));
В СТАРОМ массиве есть допoлнительный элемент. Значит НОВЫЙ массив пропускает 1 шаг цикла.
nI--;
Обработка конца массива. И вот мы подошли к концу старого массива. Возможно несколько вариантов ситуации
4.1 - ArrayIndexOutOfBoundsException - новый массив короче старого. Записываем, что последняя строка файла была удалена.
4.2 - Остался последний элемент нового массива, не охваченный нашим вниманием. Записываем его как добавленный.
4.3 - Переменные oldMismatch и newMismatch не пусты. Записываем:
lines.add(new LineItem(Type.ADDED, newMismatch)); lines.add(new LineItem(Type.SAME, oldMismatch));
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ