var input = ["KittenService: ", "Leetmeme: Cyberportal", "Cyberportal: Ice", "CamelCaser: KittenService", "Fraudstream: Leetmeme", "Ice: "];
var output = [];
function valid(input) {
for (var i = 0; i < input.length; i++) {
var array = input[i].trim().split(':');
var packageName = array[0].trim();
var dependencyName = array[1].trim();
if (array.length > 1 && dependencyName === '') {
if (output.indexOf(packageName) === -1) {
output.push(packageName);
} else {
return;
}
} else if (array.length > 1 && dependencyName !== '') {
if (output.indexOf(dependencyName) === -1) {
output.push(dependencyName);
if (output.indexOf(dependencyName) > -1) {
if (output.indexOf(packageName) > -1) {
continue;
} else {
output.push(packageName);
}
}
} else if (output.indexOf(dependencyName) > -1) {
output.push(packageName);
}
}
}
return output.join(', ');
}
valid(input);
console.log(output);
我想找到一种获得以下输出的方法:
“KittenService,Ice,Cyberportal,Leetmeme,CamelCaser,Fraudstream”
现在它记录:
'KittenService,Cyberportal,Leetmeme,Ice,CamelCaser,Fraudstream'
我听说拓扑排序可以解决这个问题,但我不确定如何实现tsort。我怎么能这样做,或者我可以使用其他方法来解决这个问题?我想在没有额外库的情况下这样做。
答案 0 :(得分:0)
一些问题:
代码中的第二个push
未验证推送的项是否具有某些依赖项。例如,推送依赖项Cyberportal
,但是您没有检查是否存在Cyberportal
本身具有依赖关系的对:它有...通常,这可能也会重复你可能会发现的依赖:也可以有另一个依赖。所以你需要一个迭代或递归的解决方案。
第一个return
后的else
错误。在某些情况下,这会使您的输出不完整。尝试使用相同输入的代码,然后"CamelCaser: KittenService"
移动到输入数组的开头。由于这个错误,你只会在输出中得到两个元素。
在推送之后检查推送的元素是否在数组中是没用的。你不需要先if (output.indexOf(dependencyName) > -1)
:它永远都是真的。
if (output.indexOf(dependencyName) > -1)
的另一次出现也没用,因为它也一直都是真的。
当您将方法(array.length > 1
)应用于第二个元素时,检查trim()
是没用的。
您不应该让函数将其结果放在全局变量中。而是将output
创建为函数的局部变量,并返回该变量(不是.join()
结果)。
即使进行了更正,该算法也没有线性时间复杂度,因为在一个也是<的循环中有indexOf
( O(n)) em> O(n),导致 O(n²)时间复杂度。然而,这可以在线性时间内完成。
我假设某个值只依赖于最多一个其他元素 - 不计算通过该单个依赖项的间接依赖性 - 因为你的符号(带冒号)似乎暗示了这一点。
我的建议是使用哈希表,使用Set
和Map
来提供对其元素的持续访问。其次,通过递归,您可以确保在输出元素本身之前首先输出元素的依赖关系。
这是ES6代码:
function valid(input) {
let result = new Set(),
pairs = new Map(input.map(s => s.split(': '))),
loop = (_, key) => { // Recursive function to add key with dependencies
if (pairs.get(key)) { // Has dependency
loop(_, pairs.get(key)); // Recurse to add dependencies first
pairs.set(key, null); // Clear dependency
}
// After dependencies were added, now add this key
result.add(key); // Duplicates are ignored
};
pairs.forEach(loop); // Call loop for every element
return [...result]; // Convert Set to Array: order is kept
}
// Sample run:
var input = ["KittenService: ", "Leetmeme: Cyberportal", "Cyberportal: Ice",
"CamelCaser: KittenService", "Fraudstream: Leetmeme", "Ice: "];
var result = valid(input);
console.log(result);
如果您没有ES6支持,则可以使用普通对象而不是“设置”和“地图”。并使用普通function
s而不是箭头符号。