Java 8,虽然这个答案应该适用于任何一个lang。
我有一个问题,我需要比较对象,比如Widgets
,然后产生一个"差异"它们之间:也就是说,一组步骤,如果遵循这些步骤,会将一个Widget
(源)转换为另一个(目标)。< / p>
class Widget {
// Properties and such.
}
class WidgetDiffer extends Differ<Widget> {
List<Transformation> diff(Widget source, Widget target) {
// The produced list will convert source to target, if executed
// by some runtime.
}
}
class WidgetTransformer extends Transformer<Widget> {
@Override
Widget transformSourceToTarget(Widget source, List<Transformation> transforms) {
// Somehow, run 'transforms' on 'source', which *should*
// produce an object with the same state/properties as
// the original target.
}
}
我知道字符串转换的Levenshtein Distance算法,但是:
Widgets
;和List<Transformation>
,当由某个引擎执行时,将源变为目标我想知道是否有任何已知的算法来执行此类操作。这些算法是否有可能在某个库中存在?!?
答案 0 :(得分:1)
我将其视为搜索问题。构造一个图形,其中目标节点是所需的窗口小部件,起始节点是要转换的窗口小部件。每个步骤(图中的边缘)表示对窗口小部件的一种可能转换(添加或删除属性)。构建图形后,在其上运行带有路径提取的DFS,您将获得将起始窗口小部件转换为所需步骤所需的步骤(它也将是所需步骤的最小数量)。
答案 1 :(得分:0)
如果小部件只是key-gt;价值袋,那么问题非常简单。
这是一个JavaScript(您可以将其用作Java实现的伪代码)版本。
function diff(src, target) {
var result = [];
for(var key in src) {
if(key in target) {
if(src[key] !== target[key]) {
result.push({op:"update", name:key, value:target[key]});
}
} else {
result.push({op:"delete", name:key});
}
}
for(var key in target) {
if(!(key in src)) {
result.push({op:"add", name:key, value:target[key]});
}
}
return result;
}
console.log(JSON.stringify(diff({}, {a:1, b:2, c:3})));
console.log(JSON.stringify(diff({a:1, b:2, c:3}, {})));
console.log(JSON.stringify(diff({a:1, b:2, c:3}, {b:20, c:30, d:40})));
O(srcPropCount * lookupTargetProp + targetPropCount * lookupSrcPropCount)
唯一的操作是添加新属性,更新现有属性和删除属性。