JavaRush /Java блог /Random UA /Варіант розв'язання задачі рівень 19 завдання 16 (відстеж...
Anton Stezhkin
41 рівень

Варіант розв'язання задачі рівень 19 завдання 16 (відстежуємо зміни)

Стаття з групи Random UA

Передісторія:

Я дуже довго вирішував це завдання . У ній треба було порівняти 2 версії файлу та знайти зміни. Вміст файлів я вирішив отримувати як масивів і порівнювати масиви. Потім довго тупив і помилявся і, зрештою, намалював масиви на папірці в клітинку. Взагалі перед цим я подивився інший варіант рішення. Але він такий складний, що я його не подужав :) До того ж там було 2 різних алгоритми на випадок, якщо старий файл довший і якщо новий файл довший. Мені це не сподобалось.

Суть мого варіанта вирішення:

Є 2 однакові масиви. По ходу тексту я називатиму їх "новий масив" і "старий масив". І кожен з них можуть бути вставлені нові елементи. Тобто. Еталонним вважається масив, що відповідає вмісту старого файлу з усіма видаленнями. Вміст старого та нового файлу розглядаються як зразок зі вставками. Ми проходимо обидва масиви (вміст старого та нового) у циклі. І якщо виявляємо вставку в одному з них - то пропускаємо один крок, щоб однакові елементи масивів, що порівнюються, знову були поруч.

Алгоритм:

Змінні: i - індекс комірки масиву із вмістом СТАРОГО файлу. nI - індекс комірки масиву із вмістом НОВОГО файлу. Якщо елементи масивів відрізняються - записуємо їх у тимчасові змінні: oldMismatch - елемент із стагого масиву newMismatch - елемент з нового масиву При переборі елементів масиву можливі наступні випадки:
  1. Змінні oldMismatch і NewMismatch порожні. Елементи у двох масивах збігаються. Записуємо Type.SAME до списку. Йдемо далі.

  2. Змінні oldMismatch і NewMismatch порожні. Елементи у двох масивах не збігаються. Записуємо значення зі старого в oldMismatch, з нового - в NewMismatch. Йдемо далі.

  3. Змінні oldMismatch і newMismatch не порожні. Порівнюємо їх із поточними елементами масиву.

    Робимо висновки. Записуємо висновки до списку (змінна lines). Пропускаємо крок циклу одного з масивів.

    1. 3.1 oldMismatch дорівнює поточному елементу НОВОГО масиву. Це означає, що файл додали рядок.

      Значення цього рядка зберігається в NewMismatch. Так і запишемо.

      lines.add(new LineItem(Type.ADDED, newMismatch));
      lines.add(new LineItem(Type.SAME, oldMismatch));

      Так як у масиві із вмістом нового файлу є додатковий елемент, потрібно зрушити новий масив на 1 елемент уперед щодо старого.

      Тому СТАРИЙ масив пропускає 1 крок циклу.

      i--;

    2. 3.2 NewMismatch дорівнює поточному елементу СТАРОГО масиву. Це означає, що з файлу видалено рядок. Записуємо.

      lines.add(new LineItem(Type.REMOVED, oldMismatch));
       lines.add(new LineItem(Type.SAME, newMismatch));

      У СТАРОМУ масиві є додатковий елемент. НОВИЙ масив пропускає 1 крок циклу.

      nI--;

  4. Обробка кінця масиву. І ось ми добігли кінця старого масиву. Можливо кілька варіантів ситуації

    1. 4.1 - ArrayIndexOutOfBoundsException - новий масив коротший за старий. Записуємо, що останній рядок файлу було видалено.

    2. 4.2 - Залишився останній елемент нового масиву, не охоплений увагою. Записуємо його як доданий.

    3. 4.3 - Змінні oldMismatch і NewMismatch не порожні. Записуємо:

      lines.add(new LineItem(Type.ADDED, newMismatch));
      lines.add(new LineItem(Type.SAME, oldMismatch));
PS – не забуваємо обнуляти змінні та стежити за зміненою nI.
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ