Передісторія:
Я дуже довго вирішував це завдання . У ній треба було порівняти 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));
У СТАРОМУ масиві є додатковий елемент. НОВИЙ масив пропускає 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));
-
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ