level19.lesson10.bonus01 Графическое пояснение условия задачи.

Так как задача одна из самых сложных из всех до 19 лвл включительно, плюс пример в условии приведен с ошибкой, решил облегчить мучения будущих джаварашевцев. Надеюсь цвет ячеек даст вам намек на то что в цикле каждую строку файла1 сравниваем со строкой №1 файла2, если равны то SAME, если нет то сравниваем со строкой №2 файла2 если равны то строка №1 файла2 ADDED, если не равны то текущая строка файла1 REMOVED. В случаях SAME и ADDED нулевую строку файла2 удаляем. Ну и сложные условия проверок равенства вы сами додумаете чем дополнить если файл2 уже пуст.


а вот представление случая когда размер файла2 больше размера файла1

60 комментариев

Byshevsky
Да и забыл добавить, в случае ADDED минусуем переменную цикла.
mykolay21
Огромная Вам Byshevsky благодарность. Особенно помогла таблица когда второй файл больше. Долго тупил, в результате приняло с 10-й попытки.
xtiesto
Когда получил в идее эту задачу, примерно с час не мог вкурить в условие. Твоя тема оказалась первой попавшейся в поисках объяснения по условию задачи. В итоге, решил с первого раза) Спасибо.
Byshevsky
Рад что смог помочь)
valera7979
а как ты догадался что именно курил автор этой задачи?
noxior
ппц, как же улыбнул этот коммент!:)))))))))))
remain4life
Очень сбило с толку неисправленное условие. Пост помог сориентироваться, спасибо — плюсую! На всякий случай выложу корректный пример условия (он больше всего и пригодился ;)):

        file1:         file2:             результат:(lines)

        строка1        строка1            SAME строка1
        строка2                           REMOVED строка2
        строка3        строка3            SAME строка3
        строка4                           REMOVED строка4
        строка5        строка5            SAME строка5
                       строка0            ADDED строка0
        строка1        строка1            SAME строка1
        строка2                           REMOVED строка2
        строка3        строка3            SAME строка3
                       строка5            ADDED строка5
        строка4        строка4            SAME строка4
        строка5                           REMOVED строка5
DenisIbrahimau
  • DenisIbrahimau
  • 0
  • Комментарий отредактирован 2016-03-11 15:37:28 пользователем DenisIbrahimau
скажите, в решении вы исходили из логики, что есть строки пустые? или в тестовых файлах все строки были одна за одной?
задание сделал без массивов и рассчитывал что одна за другой — пока не приняло
Joysi
По моему не важно, пустая строка или нет(главное — не пропускать строки). Акцентируйтесь не на этом. Просто читайте и сравнивайте через equals(). Для меня эта задача была самая сложная из всех, что встречались до нее (правда 2/3 времени убил на то, что не донца понял условия из-за некорректности примера).
DenisIbrahimau
понимаете, если рассчитывать, что строки идут одна за другой (без пустых строк) и при этом учитывать, что через раз строки одинаковые (Type.SAME), то считывать надо 2 строки из редактированного файла. А это сильно усложняет логику. Я выполнил решение для теста без пустых строк.
Если пустые строки есть, значит читаем по строке сравниваем и делаем вывод — это легко.
Возможные варианты отказа в принятии решения:
1)не правильно понятые исходные условия, неправильный тестовый файл и следовательно неверная голика решения
2) использовал не тот способ решения (например надо было через массив и циклы for — как может показаться из коммента создателя топика). Обработка данных при этом верна.

ГЛАВНЫЙ ВОПРОС ДЛЯ ПРАВИЛЬНОГО РЕШЕНИЯ — КАКИЕ ИСХОДНЫЕ ДАННЫЕ.ЛОГИКА ДОЛЖНА ТАНЦЕВАТЬ ОТ ИСХОДНЫХ ДАННЫХ
mOPs
Отталкивайся от того, что пустых строк нет.
Если строка удалена, то оставшиеся строки поднялись на одну (на место удаленной) выше.
Если добавил строку, то оставшиеся опустились на одну вниз.
Так же не советую ломать голову над тем, что может быть добавлено 2 или больше строки подряд или удалено 2 и больше строк подряд! Условие не требует этого! После каждого ADDED и REMOVED должно обязательно идти SAME.
Это упрощает решение.
Да и в условии не сказано, но сделать надо — вывести lines в консоль.
remain4life
В текстовых файлах строки шли одна за одной, пустое место в примере — для наглядности. Решал с массивами, пробегая по строкам первого файла. Приняло даже с main-ом (который забыл удалить) с первого раза. Если интересно — могу кинуть этапы алгоритма в личку.
DenisIbrahimau
если не трудно, киньте пожалуйста. Завис. Кручусь возле одной логики, вроде решает правильно, но код корявый, не читаемый и не принимаемый.
Spirit
Спасибо!
mOPs
  • mOPs
  • 0
  • Комментарий отредактирован 2016-03-11 18:17:04 пользователем mOPs
Тоже над условием долго думал.
Потом над решением.
Потом думал оставить ее… навсегда.
Передумал.
В экселе долго разукрашивал…
Но пока логику до конца не понял, не кодировал.
В итоге спустя 2 дня решил написать код, основываясь на этом посте.
И вуаля:


Byshevsky — благодарочка! Плюсанул.
DenisIbrahimau
  • DenisIbrahimau
  • 0
  • Комментарий отредактирован 2016-03-12 14:29:42 пользователем DenisIbrahimau
Желающим решить:
Обьяснение сути анализа у создателя топика верное. При решении учтите следующие моменты:
1) строки идут одна да другой, без пустых.
2) строк не будет миллиард, поэтому для облегчения задачи копируйте их все в листы (я в первый раз читали обрабатывал сразу, код увеличился и стал сложнее, а сервер не принял), а поом с листов анализируйте.
3) лучше использовать листы, с них проще удалять. Хотя наверно можно и массивы, тогда код сложнее (нельзя постоянно обращаться к элементом о одними и теми же индексами, а обработанные удалять), но работать должен наверно быстрее.

Мое отличие от создателя топика и других комментаторов:
я первым делом проверял в листах эквивалентность первых строк и приводил к общему началу(чтобы были не эквивалентны), тогда сравнил 2 строки 1 раз и добавил в lines сразу 2 LineItem (2 строка исходя из условия будет всегда SAME).
Хвосты листов обработать не забудтье
<code>boolean sameLineFlag = startingList.get(0).equals(finiteList.get(0));   /*булевский флаг, дабы привести за  1 раз к общему началу
         (это когда нулевые строки отличаются), дальше просто  добавлять по 2 строки сразу(0 строка будет отличаться, а 1 по любому SAME)*/

       while (условие){  
            if (sameLineFlag){
                lines.add(new LineItem(Type.SAME,startingList.get(0)));
                startingList.remove(0);
                finiteList.remove(0);
                sameLineFlag = false;                 //работает 1 раз и то при необходимости
            }
// дальнейшая обработка листов в цикле
</code>
Создателю топика плюсую за разьяснение сути задания, джаварашевцам побоку за столько лет свои ошибки поисправлять
artur-ant
Byshevsky, спасибо за столь понятное пояснение.
Помогло в решении.
Sygurny
блин ну задачка, условие кривое, ладно добрые люди есть, которые прояснят задачу — а если бы не Byshevsky, то вообще её не решить получается?
Pegas
Практическое применение у этой задачи есть? А то крыша едет. Есть смысл ее побеждать? По-моему в ней нет смысла для практики.
Byshevsky
я думаю что на практике часто можно столкнутся с отредактированными файлами, в которых нужно залогировать что и как редактировали. Представь что бухгалтер поработала над списком сотрудников и уволилась, а тебе дали два файла до её вмешательства и после. Списки на 10 000 строк. Будешь вручную их сверять?
Pegas
Ну в списке я так понимаю каждая строка имеет индивидуальный идентификатор? Просто два файла по этим идентификаторам сравнил и все. Не пройдет такой вариант?
Santegra
Total Commander — сравнить по содержимому.
Pegas
  • Pegas
  • 0
  • Комментарий отредактирован 2016-04-03 14:07:24 пользователем Pegas
Ориентировался на эту ссылку. Такой вывод не прокатил. Выкладываю свой пример, который принялся сервером:

Входные:

строка1 строка1
строка2 строка3
строка3 строка5
строка4 строка2
строка5 строка4
строка1
строка2
строка3
строка4
строка5

Вывод:

SAME строка1
REMOVED строка2
SAME строка3
REMOVED строка4
SAME строка5
REMOVED строка1
SAME строка2
REMOVED строка3
SAME строка4
REMOVED строка5

Входные:

строка1 строка1
строка2 строка3
строка3 строка5
строка4 строка0
строка5 строка1
строка1 строка3
строка2 строка5
строка3 строка4
строка4
строка5

Вывод:

SAME строка1
REMOVED строка2
SAME строка3
REMOVED строка4
SAME строка5
ADDED строка0
SAME строка1
REMOVED строка2
SAME строка3
REMOVED строка4
SAME строка5
ADDED строка4
dementevay
Ну и расползлось у тебя всё в хлам… по буквам тест надо восстанавливать.
neikov
Рассмотрим простой пример:

строка3 строка3
строка4 строка5
строка5 строка4

Мне одному кажется, что однозначного решения для этого варианта нет? А именно:

SAME строка3
REMOVED строка4
SAME строка5
ADDED строка4

или так:

SAME строка3
ADDED строка5
SAME строка4
REMOVED строка5

А ведь такая конфигурация может встретиться в любом месте. Какие мнения?
valera7979
  • valera7979
  • 0
  • Комментарий отредактирован 2016-05-05 15:03:19 пользователем valera7979
получается что да.
whimzey
тоже столкнулась с этой проблемой, не стала обрабатывать ее и все равно код прошел проверку. видимо, тестирование кода на сервере не предполагает таких сложных вещей. а если разбираться, то все зависит от вашего кода, проверяете ли вы сначала удаление, а потом вставку, или наоборот. в первом случае будет верным первый вариант решения, во втором — второй.
boyarskiy
  • boyarskiy
  • 0
  • Комментарий отредактирован 2017-01-24 18:56:54 пользователем boyarskiy
Я тоже столкнулся с этой проблемой, когда закидывал своей программе вторые входные данные, предложенные выше. Сначала думал, что прога неправильно отраблтала, потом взял ручку, всё сошлось, стал уж грешить на автора тестов, а тут оказывается неоднозначность.

1   1   same 1
2   -   removed 2
3   3   same 3
4   -   remove 4
5   5   same 5
-   0   added 0
1   1   same 1
2   -   remove 2
3   3   same 3
------------------
-   5   added 5
4   4   same 4
5   -   remove 5
StVK
  • StVK
  • +1
  • Комментарий отредактирован 2016-04-24 01:51:15 пользователем StVK
Благодарности коллеге Byshevsky!

Потратил часов 14 из-за нечеткого условия. Решил с 5 попытки, оказалось все просто.
В условии сказано «Нужно создать объединенную версию строк, записать их в список lines», вот именно так и надо делать. Возможно, мои художества кому-нибудь помогут:
imp
а если у вас будет 2 таких списка:
1
2
3

и

1
3
4

как он поступит?
StVK
  • StVK
  • 0
  • Комментарий отредактирован 2016-07-28 00:21:43 пользователем StVK
Подставил, получил ответ:
SAME 1
REMOVED 2
SAME 3
ADDED 4
imp
  • imp
  • 0
  • Комментарий отредактирован 2016-07-28 10:55:11 пользователем imp
вопрос снят, все понял
StVK
Точно не помню (исходники на другой машине, дома), но находясь в левом столбце, сравниваем с правым. На текущем примере, сравниваем первую строку (1 против 1) там понятно что SAME; вторая строка, справа нет 2ки, значит она REMOVED и пишем во второй столбец 2; третья строка, поскольку во второй столбец добавили, тройки встали друг против друга, т.е. SAME; а четверку и сравнивать не с чем, а она во втором столбце… Очень уж явно описал. Надеюсь, без бана обойдется. Эх, отпуск!!!
catalystlip
  • catalystlip
  • 0
  • Комментарий отредактирован 2016-05-17 21:32:09 пользователем catalystlip
Скажите пожалуйста, этот алгоритм вы ведь сами придумали? Просто очень интересно, как??? Я сейчас в сильном зашкваре, но по-моему и будучи в здравом уме, не смог бы этого сотворить. Чё, бросать инфу тогда нафиг? Я реально не понимаю, как можно было допереть до такого способа, не просто же Вы подбирали его под ответ...((((
P.S. извините, если что, я просто рил в отчаянии. Сам бы вряд ли правда до такого когда додумался бы :(
P.P.S
если нет то сравниваем со строкой №2 файла2 если равны то строка №1 файла2 ADDED
вроде опечатка тут
Pegas
Не вы первый запариваетесь. Начните решать, выложите наработки, если не справляетесь и вам подскажут куда дальше двигаться. Задача вполне решаема, хоть условие и не сразу понятно. Начните с изображения условия задачи в виде схемы на листе бумаги…
Byshevsky
спасибо, исправил
Levit
Большое спасибо за пояснение.
Sonchik
Спасибо, добрый человек!
Без вас я бы не разобралась!
Alukard1H
Спасибо! с правильным примером в задаче вся логика встала на свои места!
alexeyfrei
Не уверен, что смог бы сам додуматься до такой логики программы. обидно :/ хотя сказать честно я потратил на самостоятельные размышления над условием около часа. Затем полез на форум. Мое почтение гению товарища Byshevsky. Только благодаря Вашим примерам решено с первого раза.
noxior
Ребят задача реально очень простая, как стекло)) реально час работы. вы слишком заморачиваетесь над всеми возможными нюансами. вот мой пруф)
Kellzar
спс за объяснения задачи^^
kasper1987
/* Отслеживаем изменения
Считать в консоли 2 имени файла — file1, file2.
Файлы содержат строки, file2 является обновленной версией file1, часть строк совпадают.
Нужно создать объединенную версию строк, записать их в список lines
Операции ADDED и REMOVED не могут идти подряд, они всегда разделены SAME
Пример:
оригинальный редактированный общий
file1: file2: результат:(lines)

строка1 строка1 SAME строка1
строка2 REMOVED строка2
строка3 строка3 SAME строка3
строка4 REMOVED строка4
строка5 строка5 SAME строка5
строка0 ADDED строка0
строка1 строка1 SAME строка1
строка2 REMOVED строка2
строка3 строка3 SAME строка3
строка5 ADDED строка5
строка4 строка4 SAME строка4
строка5 REMOVED строка5
*/


public class Solution {
    public static List<LineItem> lines = new ArrayList<LineItem>();

    public static void main(String[] args) throws IOException
    {
        BufferedReader fileName = new BufferedReader(new InputStreamReader(System.in));
        String file1 = fileName.readLine();
        String file2 = fileName.readLine();
        fileName.close();

        ArrayList<String> listFile1 = new ArrayList<>();
        ArrayList<String> listFile2 = new ArrayList<>();

        BufferedReader readerFile1 = new BufferedReader(new FileReader(file1));
        BufferedReader readerFile2 = new BufferedReader(new FileReader(file2));

        while (readerFile1.ready())
        {
            listFile1.add(readerFile1.readLine().replaceAll("\\n\\r\\p{Cf}", ""));
        }
        readerFile1.close();

        while (readerFile2.ready())
        {
            listFile2.add(readerFile2.readLine().replaceAll("\\n\\r\\p{Cf}", ""));
        }
        readerFile2.close();

        for (int i = 0; i < listFile1.size(); i++)
        {
            try
            {
                if (listFile1.get(i).equals(listFile2.get(0)))
                {
                    lines.add(new LineItem(Type.SAME, listFile1.get(i)));
                    listFile2.remove(0);
                } else if (listFile1.get(i).equals(listFile2.get(1)))
                {
                    lines.add(new LineItem(Type.ADDED, listFile2.get(0)));
                    listFile2.remove(0);
                    i--;
                } else
                {
                    lines.add(new LineItem(Type.REMOVED, listFile1.get(i)));
                }
            }
            catch (Exception e)
            {
                lines.add(new LineItem(Type.REMOVED, listFile1.get(i)));
            }
        }

        for (int i = 0; i < listFile2.size(); i++)
        {
            try
            {
                if (listFile2.get(i).equals(listFile1.get(0)))
                {
                    lines.add(new LineItem(Type.SAME, listFile2.get(i)));
                    listFile1.remove(0);
                } else if (listFile2.get(i).equals(listFile1.get(1)))
                {
                    lines.add(new LineItem(Type.ADDED, listFile1.get(0)));
                    listFile1.remove(0);
                    i--;
                } else
                {
                    lines.add(new LineItem(Type.REMOVED, listFile2.get(i)));
                }
            }catch (Exception e)
            {
                lines.add(new LineItem(Type.REMOVED, listFile2.get(i)));
            }
        }

        for (LineItem l : lines)
        {
            System.out.println(l.type + " " + l.line);
        }
    }

    public static enum Type {
        ADDED,        //добавлена новая строка
        REMOVED,      //удалена строка
        SAME          //без изменений
    }

    public static class LineItem {
        public Type type;
        public String line;

        public LineItem(Type type, String line) {
            this.type = type;
            this.line = line;
        }
    }
}


Народ, посмотрите что не так в программе. Отрабатывает на ура, чего не хватает, уже все способы перепробовал!
mykolay21
Учитывайте длину Листов if ((listFile1.size()>=listFile2.size()){Ваш алгоритм когда первый файл длиннее второго }
} else{Алгоритм когда второй файл длиннее первого. Ваш алгоритм для этого случая немного неверен. Нужно ADDED поменять местами с REMOVED }
muhadroid
  • muhadroid
  • +1
  • Комментарий отредактирован 2016-09-06 14:24:08 пользователем muhadroid
Чот я немогу тут ошибку найти, может кто подсказать?
<code>for (int i = 0; i < s1.size(); i++) {
            if (s2.size()>1){
                if (s1.get(i).equals(s2.get(0))){
                    lines.add(new LineItem(Type.SAME, s1.get(i)));
                    s2.remove(0);
                }else if (s1.get(i).equals(s2.get(1)) && !s2.get(1).equals("end")){
                    lines.add(new LineItem(Type.ADDED, s2.get(0)));
                    s2.remove(0);
                    i--;
                }else {
                    lines.add(new LineItem(Type.REMOVED, s1.get(i)));
                }
            }else if (s2.size()== 1&& s2.get(0).equals("end")&& i != s1.size()-1){
                lines.add(new LineItem(Type.REMOVED, s1.get(i)));
            }else if (s2.size()== 2 && s2.get(1).equals("end") && i == s1.size()-1){
                lines.add(new LineItem(Type.ADDED, s2.get(0)));
            }
        }</code>
выход не тот что ожидается, но где именно исправить чот немогу
muhadroid
ОУЖАС на каких кастылях я решил эту задачу, показывать стыдно. Аж с 15 пытки (нервно клацал кнопку сдать задание)
и исписал 3-4 листа бумаги в тетради… =)
bkozhaev
Подскажите пожалуйста что здесь не так
public class Solution {
    public static List<LineItem> lines = new ArrayList<LineItem>();

    public static void main(String[] args) throws IOException {

        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String file1 = "D:/file_1.txt";
        String file2 = "D:/file_2.txt";

        BufferedReader f1 = new BufferedReader(new FileReader(file1));
        BufferedReader f2 = new BufferedReader(new FileReader(file2));

        List<String> array1 = new ArrayList<>();
        List<String> array2 = new ArrayList<>();


        while (f1.ready()) {
            array1.add(f1.readLine());
        }

        while (f2.ready()) {
            array2.add(f2.readLine());
        }

        for (int i = 0; i < array1.size(); i ++){

            try {
                if (array1.get(i).equals(array2.get(0))){
                    lines.add(new LineItem(Type.SAME, array1.get(i)));
                    array2.remove(0);
                } else if (array1.get(i).equals(array2.get(1))){
                    lines.add(new LineItem(Type.ADDED, array2.get(0)));
                    array2.remove(0);
                    i--;
                } else {
                    lines.add(new LineItem(Type.REMOVED, array1.get(i)));
                }
            } catch (IndexOutOfBoundsException e){
                if (array1.size() > array2.size()){
                    lines.add(new LineItem(Type.REMOVED, array1.get(i)));
                }

                if (array1.size() < array2.size()){
                    lines.add(new LineItem(Type.ADDED, array2.get(0)));
                }
            }
        }

        for (LineItem i : lines) {
            System.out.println(i.type + " " + i.line);
        }

        reader.close();
        f1.close();
        f2.close();
    }
Joysi
Из условий
Считать в консоли 2 имени файла - file1, file2.

А у вас имена файлов захардкорены явно
String file1 = "D:/file_1.txt";
        String file2 = "D:/file_2.txt";
jahstreetlove
Спасибо, тебе!!!
Legas
Фуух, наконец-то с 19 попытки решил. Пошаговые подсказки:
1. Строки старого и нового файла занесите в два arraylist.
2. Цикл в котором будут данные обрабатываться я сделал так: пока(файл1 не пустой или файл2 не пустой)
3. В цикле
if(){
} else if(){
} else if(){
}

Главное правильно распишите условия в нужной последовательности. Имеется в виду в одном if тоже несколько условий на вход в условие.
4. Отталкивайтесь от примеров, которые выше описал StVK. Отдельная ему благодарность.
5. После каждого входа в условие какая-то строка(строки) удаляются из arraylist(листов). Думаю и так понятно, но я с этим затупил в начале.
В целом код у меня вышел на 26 строк. Главное, правильно опишите if(). Пока я делал таким образом:
if(){
} else if(){
} else{
}

у меня ничего не получалось. Последнее условие тоже должно быть else if(). Ну может и не должно быть, может есть иные варианты. Но у меня прошел именно такой.
Tars
Супер! Спасибо за описание алгоритма! Мой алгоритм вряд ли бы взлетел, а до этого я бы неделю думал. Отлично.
Artem_Novikov
  • Artem_Novikov
  • 0
  • Комментарий отредактирован 2017-01-24 13:47:18 пользователем Artem_Novikov
24.01.2017. 8 часов раздумий. Со 2 попытки. Отредактированное условие помогло.
Делал через один цикл while(true). Внутри if-else. И проверяйте пограничное условие — то есть, когда первый файл пустой, а второй нет и наоборот. И в условии где идёт запись SAME проверка на пустоту обоих файлов.
1drv.ms/u/s!AosDITWDBX9Mg1Zu5KmQd61_USzi — тут можно скачать проверочные файлы и какие должны быть результаты. На кодировку не обращайте внимания.
Xan
Убил полчаса из-за фразы — «на кодировку не обращайте внимания». Обращайте! Преобразовал в UTF8 и файл подгрузился.
ivan3177
Огромное вам спасибо! Лучшее описание алгоритма, оно должно быть в условии задачи! Долго не мог понять чего хотят от меня составители задачи, нашёл ваше объяснение и за 5 минут понял всё! За 10 последующих минут был написан код и о боги — программа с первой попытки выдала верный ответ на разобранные вами тесты. Далее при проверке задача решена с первой попытки. Byshevsky огромное вам человеческое спасибо
AMTsurkanu
Замучился совсем. Подскажите, что не так?
public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String fileNameOne = reader.readLine();
        String fileNameTwo = reader.readLine();
        reader.close();

        BufferedReader fileReader = new BufferedReader(new FileReader(fileNameOne));
        BufferedReader fileReaderTwo = new BufferedReader(new FileReader(fileNameTwo));

        List <String> listOne = new ArrayList();
        List <String> listTwo = new ArrayList();

        while (fileReader.ready()) {
            listOne.add(fileReader.readLine());
        }

        while (fileReaderTwo.ready()) {
            listTwo.add(fileReaderTwo.readLine());
        }

        fileReader.close();
        fileReaderTwo.close();

        int i = 0;
        while (listOne.size() > 0 || listTwo.size() > 0){
            if (listOne.get(i).equals(listTwo.get(i))){
                lines.add(new LineItem(Type.SAME, listOne.get(i)));
                listTwo.remove(i);
                i++;
            } else if (listOne.get(i).equals(listTwo.get(i+1))){
                lines.add(new LineItem(Type.ADDED, listTwo.get(i)));
                listTwo.remove(i);
                i--;
            } else if (!listOne.get(i).equals(listTwo.get(i+1))){
                lines.add(new LineItem(Type.REMOVED, listOne.get(i)));
                listOne.remove(i);
            }
        }
    }
AMTsurkanu
Спасибо, уже разобрался
Xan
Подскажите пожалуйста почему нижеследующий код не проходит. Тесты вроде проходит.
В логике может где косяк? Сменил ввод на буферы, потому что требовалось (думал в этом дело).
package com.javarush.task.task19.task1916;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;


/* 
Отслеживаем изменения
*/

public class Solution {
    //    public static String file1="c:/Temp/1.txt";
//    public static String file1="c:/T/1.txt";

//    public static String file2="c:/T/2.txt";
//    public static String file2="c:/Temp/2.txt";

    public static String file1 = "/home/xan/t/6.txt";
    public static String file2 = "/home/xan/t/7.txt";


    public static List<LineItem> lines = new ArrayList<LineItem>();

    public static List<String> listFromFile1 = new ArrayList<>();
    public static List<String> listFromFile2 = new ArrayList<>();

    public static void main(String[] args) throws IOException {

        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("Ввелите имя файла1");
        file1 = reader.readLine();
        System.out.println("Ввелите имя файла2");
        file2 = reader.readLine();
        reader.close();

        BufferedReader readerFile1 = new BufferedReader(new FileReader(file1));
        BufferedReader readerFile2 = new BufferedReader(new FileReader(file2));

        while (readerFile1.ready()){
            listFromFile1.add(readerFile1.readLine());
        }

        while (readerFile2.ready()){
            listFromFile2.add(readerFile2.readLine());
        }

        readerFile2.close();
        readerFile1.close();



    /*    Scanner scanner = new Scanner(System.in);
        file1 = scanner.nextLine();
        file2 = scanner.nextLine();
        scanner.close();

        try {
            listFromFile1 = Files.readAllLines(Paths.get(file1));
            listFromFile2 = Files.readAllLines(Paths.get(file2));

        } catch (IOException e) {
            e.printStackTrace();
        }*/



        int file1size = listFromFile1.size();
        int file2size = listFromFile2.size();
        int i = 0, j = 0;
        for (i = 0, j = 0; i < file1size && j < file2size; i++, j++) { //производим сравнение строк

            String string1 = listFromFile1.get(i);
            String string2 = listFromFile2.get(j);

            if (string1.equals(string2)) { //сравнение 1-1 и 2-1 строк  если равны то SAME
                lines.add(new LineItem(Type.SAME, string1));
                continue;
            } else if ((j + 1) < listFromFile2.size() && string1.equals(listFromFile2.get(j + 1))) { //если не SAME то  сравниваем строку 1-i с 1-j+1 и если равны то строка 2-j была добавлена, а 2-i сместилась вниз
                lines.add(new LineItem(Type.ADDED, string2));
                lines.add(new LineItem(Type.SAME, listFromFile2.get(j + 1)));
                j++;
                continue;
            } else

            {
                lines.add(new LineItem(Type.REMOVED, string1));
                j--;
            }

        }
        //теперь добиваем хвосты если они есть
        if (file1size > file2size) {
            for (; i < file1size; i++) {
                lines.add(new LineItem(Type.REMOVED, listFromFile1.get(i))); // Если второй файл меньше, то строки удаляли
            }


        } else if (file1size < file2size) {
            for (; j < file2size; j++) {
                lines.add(new LineItem(Type.ADDED, listFromFile1.get(j))); // Если второй файл больше то строки прибавляли
            }
        }

        //вывод результата
     /*   for (LineItem line : lines) {
            System.out.println(line.type + " " +line.line);
        }*/
    }


    public static enum Type {
        ADDED,        //добавлена новая строка
        REMOVED,      //удалена строка
        SAME          //без изменений
    }

    public static class LineItem {
        public Type type;
        public String line;

        public LineItem(Type type, String line) {
            this.type = type;
            this.line = line;
        }
    }
}
vovandoz
Добрый день! Хотел бы уточнить вот какой момент:
Допустим есть 2 файла с конкретными строками f1 f2
E X
A E
X A
Я верно понимаю, что исходя из условия, строки считаются SAME, если содержимое строк equals и при этом сохранен порядковый номер строки в файле?

Теперь вопросы по алгоритму(он правда хорош, сам бы не допер).Для строк указанных выше алгоритм отработает вот так:
ADD X
ADD E
и далее исключение о выходе за границы массива…
1)Вообщем то странно считать, что строки X и E добавлены, ведь они по-прежнему присутствуют в обновленном файле, только не в той же позиции, что в исходнике.Почему мы считаем, что строки X и E добавлены? Объясните пожалуйста, возможно не понимаю этот момент

2)При таком наборе данных нарушается условие, что ADD и REMOVED разделяются SAME

3)Как быть с IndexOutOfBoundsException, когда мы сравниваем «X» из f1 с последним, оставшимся «A» из f2?

P/S Мне вот странно, что валидатор хавает решение, предложенное здесь, ведь оно не на 100% верно=)
Я не хочу обидеть автора статьи, она очень полезна.Вопрос скорее к составителям данной задачи
vovandoz
1000 Извинений, на предыдущий пост еретика внимания не обращать=)), во всем разобрался=)
vinsler
Может кому-то понадобится. Блок-схема.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.