我真的把这个打到了地上。正如预期的那样,@Louis Durand 对两个嵌套 for 循环的回答在包含 100 个字符串的数组上最快(在我的机器上大约 4 毫秒)。这表明在这种情况下,嵌套循环可能是您最好的选择。
第二快的是我的递归解决方案,它在大约 7-8 毫秒内完成。
第三个是@Redu 的回答,对于相同的任务,它在大约 12-15 毫秒内完成。我怀疑他的实现速度较慢,因为他在算法中使用 slice 方法来更新数组(其他答案只是增加索引而使输入数组保持不变,这要快得多)。此外,此实现导致输入数组的多个副本存储在内存中(每次调用该函数时,它都会从原始数组创建一个新的输入数组,并从中删除第一个元素)。这也可能会影响性能。
所以要回答你的问题:不,除了连接到字符串并在最后打印答案(Louis 建议的)之外,我认为没有更好的方法来处理你正在做的事情。
var arr = [];
for (var i = 0; i< 100; i++){
arr.push(i+"");
}
/*
console.time("test0");
test0();
function test0() {
var s = "";
for (var i=0; i<arr.length-1;i++) {
for (var j=i+1; j<arr.length;j++) {
s += arr[i] + " " + arr[j]+" ; ";
}
s += "\n";
}
console.log(s);
}
console.timeEnd("test0");
*/
console.time("test1");
test1();
function test1() {
var output = [];
getCombos(0, 0, [], 2);
console.log(JSON.stringify(output));
function getCombos(index, depth, tmp, k){
if(depth < k){
for(var i = index; i<arr.length; i++){
var tmp1 = [arr[i]];
Array.prototype.push.apply(tmp1, tmp);
getCombos(i+1, depth+1,tmp1, k);
}
}else{
output.push(tmp);
}
}
}
console.timeEnd("test1");
/*
console.time("test2");
test2();
function test2(){
Array.prototype.combinations = function(n){
return this.reduce((p,c,i,a) => (Array.prototype.push.apply(p,n > 1 ? a.slice(i+1).combinations(n-1).map(e => (e.push(c),e))
: [[c]]),p),[]);
};
console.log(JSON.stringify(arr.combinations(2)));
}
console.timeEnd("test2");*/
这是一个递归解决方案,它不能解决您的时间复杂度问题,但可以考虑另一种方式。额外的好处是您可以将其推广到任何 k,这样您就不会只找到两个字母的组合。此外,您只需声明一个循环(尽管您的调用堆栈中将存在多个它的副本)
var arr = ["a", "b", "c", "d", "e"];
var output = "";
getCombos(0, 0, [], 2);
console.log(output);
function getCombos(index, depth, tmp, k){
if(depth < k){
for(var i = index; i<arr.length; i++){
var tmp1 = [...tmp, arr[i]];
getCombos(i+1, depth+1,tmp1, k);
}
}else{
output += tmp.toString() + ";";
}
}