java中的序列比较

时间:2009-05-09 11:10:53

标签: java collections diff compare sequence

我正在寻找一个标准算法/代码(Java),它比较两个整数列表(旧的和新的)并给出第三个结果列表,它提供了将“旧”列表转换为“新”列表的操作。 / p>

例如:

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 个答案:

答案 0 :(得分:3)

Levenshtein distance算法似乎适合你(基本上是你提到的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]以递归方式返回整个过程并将所选操作推送到堆栈中。

答案 1 :(得分:2)

我在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());
    }
}

答案 2 :(得分:0)

仅供将来参考。第一和第二个答案都很好。 第一个答案是我正在寻找的线索。比较序列的最佳方法。 和, 第二个答案是比较序列的工作代码。但这并没有给出将一个列表转换为另一个列表的最佳结果。但是对于一个简单的差异很好!!

感谢大家的回答!

谢谢, 阿布舍克巴克。