gpt4 book ai didi

javascript - 嵌套 for 循环 - 如何忽略某些组合?

转载 作者:搜寻专家 更新时间:2023-11-01 05:26:31 24 4
gpt4 key购买 nike

我正在使用某种蛮力攻击来解决问题。从理论上讲,这是一个可行的解决方案,实际上也是如此,但需要相当长的时间。

我有 7 个相互嵌套的 for 循环,但我只需要其中没有重复的“for 变量”的组合。所以例如允许使用 1,2,3,4,5,6,7,但应忽略 1,1,3,4,5,6,7。我目前正在使用一个函数来检查数组中的重复项:

http://www.groggyjava.tv/freebies/duplicates.html

不过,我认为如果我可以立即忽略这些组合,而不是对每个 单个组合反复使用该函数,我会过得更好。现在我正在评估 14^7 = 105.413.504 种组合,但只有 14 nPr 7 = 17.297.280 种组合是必需的。

我目前的代码是(其中hgd是重复测试函数,如果没有重复则返回true):

for(var a=0;a<14;a++) {
for(var b=0;b<14;b++) {if(hgd([a,b])) {
for(var c=0;c<14;c++) {if(hgd([a,b,c])) {
for(var d=0;d<14;d++) {if(hgd([a,b,c,d])) {
for(var e=0;e<14;e++) {if(hgd([a,b,c,d,e])) {
for(var f=0;f<14;f++) {if(hgd([a,b,c,d,e,f])) {
for(var g=0;g<14;g++) {if(hgd([a,b,c,d,e,f,g])) {
check([a,b,c,d,e,f,g]);
}}
}}
}}
}}
}}
}}
}

我怎样才能让它更快,是否有其他解决方案而不是 for 循环?

谢谢。

最佳答案

您在这里所做的是遍历 14 个离散值列表的所有排列

一般来说,要访问离散事物列表的所有排列,您需要访问列表的每个元素。对于每个元素,形成一个包含原始列表的所有其他 元素的新列表。获取 that 列表的所有排列,将元素添加到每个排列之前,您将获得可以以该特定元素开头的原始列表的所有排列。完成所有元素后,您就完成了。

当然,找到包含一个元素的列表的所有排列是一项简单的任务。

因此我们得到的是这样的:

function forEachPermutation(list, operation) {
function pluckElement(list, index) {
var e = list[index];
var l = [];
for (var i = 0; i < list.length; ++i)
if (i !== index) l.push(list[i]);
return { element: e, remainder: l };
}

function permute(partial, remainder) {
if (remainder.length === 0)
operation(partial);
else {
for (var i = 0; i < remainder.length; ++i) {
var plucked = pluckElement(remainder, i);
partial.push(plucked.element);
permute(partial, plucked.remainder);
partial.length--;
}
}
}

permute([], list);
}

它所做的是递归地执行我上面描述的操作。 “pluckElement”函数返回列表中的一个元素,以及该列表的rest。然后,“置换”函数要么在原始列表的完整排列上执行传入的操作(当它注意到剩余列表为空时),要么递归地调用它传递的列表中的每个元素。

要使用该功能,您只需执行以下操作:

forEachPermutation([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], check);

编辑 — 如果您只想从原始列表中提取一定数量的值,则必须修改以上内容;等一下。

好的 - 如果您想传入一个包含(比方说)14 个元素的列表,但要为每个不同的(比方说)14 个元素中的 7 个列表调用“操作”函数,您可以按如下方式修改该函数。外部的“forEachPermutation”函数将采用一个额外的“len”参数,以告诉它所需的字符串长度。然后,“permute”函数将检查“partial.length”是否为目标长度,而不是检查空余数。

function forEachPermutation(list, len, operation) {
function pluckElement(list, index) {
var e = list[index];
var l = [];
for (var i = 0; i < list.length; ++i)
if (i !== index) l.push(list[i]);
return { element: e, remainder: l };
}

function permute(partial, remainder) {
if (partial.length === len)
operation(partial);
else {
for (var i = 0; i < remainder.length; ++i) {
var plucked = pluckElement(remainder, i);
partial.push(plucked.element);
permute(partial, plucked.remainder);
partial.length--;
}
}
}

permute([], list);
}

你会调用它

forEachPermutation([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], 7, check);

另一个编辑 — 如果出于某种原因您想在“操作”函数处理每个排列后保存排列,那么我们将不得不考虑这一事实正在使用的部分数组被覆盖。可以更改对“操作”的调用:

if (partial.length === len)
operation(partial.slice(0));

这会生成“部分”数组的副本,以便每次调用“操作”时都可以使用它自己的数组。当然,这会使过程变慢。

关于javascript - 嵌套 for 循环 - 如何忽略某些组合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4431218/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com