Сравнение последовательностей в Java - PullRequest
2 голосов
/ 09 мая 2009

Я ищу стандартный алгоритм / код (Java), который сравнивает два списка целых чисел (старый и новый) и дает третий список результатов, который предоставляет действия для преобразования «старого» списка в «новый» список.

Например:

old-> 1, 2, 3, 4
new-> 9, 2, 3, 6, 4

поэтому результат должен выглядеть примерно так:

1-, 9+, 2, 3, 4-, 6+, 4+ 

Здесь суффикс:

  - = Deleted item from old list.
  + = New added item to old list.

, а остальные (без суффикса) являются числами, которые не изменились (т.е. значение, а также индекс). Я верю, что что-то с использованием LCS (самая длинная общая последовательность) сделает эту работу! Но я не могу понять, есть ли они.

Любые указатели будут высоко оценены.

Ответы [ 3 ]

3 голосов
/ 09 мая 2009

Алгоритм Левенштейна , кажется, работает для вас (по сути, алгоритм LCS, который вы упомянули). Просто запишите действие, которое вы выберете, в другой таблице (сразу после того, как вы выберете минимум, вам нужно записать, какое действие привело к минимальной стоимости, чтобы иметь возможность посмотреть его позже).

if (seq1[i] == seq2[j] && d[i - 1, j - 1] <= d[i - 1, j] + 1
                       && d[i - 1, j - 1] <= d[i, j - 1] + 1) {
     d[i, j] = d[i - 1, j - 1];
     action[i, j] = MATCHED;
} else if (d[i - 1, j] < d[i, j - 1]) // If cost of insertion is less:
{
     d[i, j] = d[i - 1, j] + 1;
     action[i, j] = INSERTION;
} else {
     d[i, j] = d[i, j - 1] + 1;
     action[i, j] = DELETION;
}

Затем используйте action[i, j], чтобы рекурсивно вернуться к процессу и поместить выбранное действие в стек.

2 голосов
/ 09 мая 2009

Я что-то реализовал в C #. Портирование на Java ...

(редактирование)

Вот версия Java:

enum Action {
    UNCHANGED, ADDED, REMOVED
}

static class DiffResult<T> {
    private T value;
    public Action type;

    public DiffResult(T value, Action type) {
        super();
        this.value = value;
        this.type = type;
    }

    public T getValue() {
        return value;
    }

    public Action getType() {
        return type;
    }
}


public static <T> List<DiffResult<T>> listDiff(List<T> originalList,
        List<T> newList) {
    List<DiffResult<T>> result = new ArrayList<DiffResult<T>>();

    int maxCount = Math.max(originalList.size(), newList.size());
    for (int i = 0; i < maxCount; i++) {
        if (newList.size() < i + 1)
            result.add(new DiffResult<T>(originalList.get(i),
                    Action.REMOVED));
        else {
            if (originalList.size() < i + 1) {
                result.add(new DiffResult<T>(newList.get(i), Action.ADDED));
            } else {
                if (originalList.get(i).equals(newList.get(i)))
                    result.add(new DiffResult<T>(originalList.get(i),
                            Action.UNCHANGED));
                else {
                    result.add(new DiffResult<T>(originalList.get(i),
                            Action.REMOVED));
                    result.add(new DiffResult<T>(newList.get(i),
                            Action.ADDED));
                }
            }
        }
    }
    return result;
}

public static void main(String[] args) {
    List<Integer> oldList = new ArrayList<Integer>();
    oldList.add(1);
    oldList.add(2);
    oldList.add(3);
    oldList.add(4);

    List<Integer> newList = new ArrayList<Integer>();
    newList.add(9);
    newList.add(2);
    newList.add(3);
    newList.add(6);
    newList.add(4);

    List<DiffResult<Integer>> diff = listDiff(oldList, newList);

    for (DiffResult<Integer> d : diff) {
        System.out.println("Item: " + d.getValue() + " -> " + d.getType());
    }
}
0 голосов
/ 28 мая 2009

Только для будущих ссылок. И 1-й, и 2-й ответы хороши. Первый ответ - ключ к тому, что я искал. Оптимальный способ сравнения последовательностей. а также, Второй ответ - это рабочий код для сравнения последовательностей. Но это не дает оптимального результата для покрытия одного списка другим. Но хорошо для простого сравнения !!

Спасибо всем за ответы !!

Спасибо, Абхишек.

...