我正在寻找一个标准算法/代码(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(最长的通用序列)的东西可以完成这项工作! 但我真的无法弄明白是否有。
任何指针都将受到高度赞赏。
答案 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)
仅供将来参考。第一和第二个答案都很好。 第一个答案是我正在寻找的线索。比较序列的最佳方法。 和, 第二个答案是比较序列的工作代码。但这并没有给出将一个列表转换为另一个列表的最佳结果。但是对于一个简单的差异很好!!
感谢大家的回答!
谢谢, 阿布舍克巴克。