我有一个javascript应用程序,我需要对数字0到6的每个可能组合进行测试,而不复制组合中的任何数字。
所以: 0123456, 0123465, 0123546, 0123564 ...
(但是,例如,不应包括0123455,因为5是重复的)
我已经迭代地完成了它:
function testAllCombinations(){
for(var i = 0; i < 7; i++){
for(var j = 0; j < 7; j++){
if(j == i)
continue;
for(var k = 0; k < 7; k++){
if(k == j || k == i)
continue;
for(var l = 0; l < 7; l++){
if(l == k || l == j || l == i)
continue;
for(var m = 0; m < 7; m++){
if(m == l || m == k || m == j || m == i)
continue;
for(var n = 0; n < 7; n++){
if(n == m || n == l || n == k || n == j || n == i)
continue;
for(var o = 0; o < 7; o++){
if(o == n || o == m || o == l || o == l || o == j || o == i)
continue;
runTest(i, j, k, l, m, n, o);
}
}
}
}
}
}
}
}
并且它工作正常,但我想以递归方式进行,并且我很难构建算法。
有人可以给我一些方向吗?
提前致谢。
答案 0 :(得分:4)
这看起来像关于递归的一般问题。
递归算法可以分为两部分,一个基本案例和一个递归案例。 首先,弄清楚基本情况,这导致一个微不足道的结果,不需要递归。可能有多个输入导致基本情况。从最琐碎的输入开始,然后从那里扩展。 很快,您将发现递归情况,这是递归函数的关键因素。您会发现递归案例都可以使用由先前案例组成的类似模式来解决,包括基本案例。
所以对于这个问题,假设用户可以输入一个字符串,并且你想打印字符串中的所有字符组合,让我们调用这个调用f(s)。 如果用户输入长度为0或1的字符串,则只返回提供的字符串,因为只有一个组合可用。这里没什么特别的。这是基本情况。
如果用户输入长度为2的字符串(例如“01”),很明显可能的组合是“01”和“10”。
你是怎么得到这个答案的?
注意“01”=“0”+“1”和“10”=“1”+“0”
哇,我们循环遍历每个数字并将其与f(s)的结果相结合,其中s =剩余数字
即。 “01”=“0”+ f(“1”)和“10”=“1”+ f(“0”)。
我们已经知道如何在长度为1时解决这个问题,所以现在我们知道如何在输入长度为2时解决问题。
现在如果输入长度是3(例如“012”),你知道答案是“012”,“021”,“102”,“120”,“201”,“210”。
注意“012”,“021”=“0”+“12”,“0”+“21”和“102”,“120”=“1”+“02”,“1”+“20”,和“201”,“210”=“2”+“01”,“2”+“10”
哇,我们循环遍历每个数字并将其与f(s)的结果相结合,其中s =剩余数字。
听起来很熟悉?
即。 “012”,“021”=“0”+ f(“12”)和“102”,“120”=“1”+ f(“02”)和“201”,“210”=“2”+ F( “10”)
我们已经知道如何在长度为2时解决这个问题,所以现在我们知道如何在输入长度为3时解决问题。
你现在看到了这种模式吗? 在每个级别(输入的长度),我们应用相同的原则,因此可以在问题的子集上反复使用相同的代码片段,最终将它们组合在一起以形成最终答案。这就是使递归如此优雅的原因。
注意当输入长度为4时,我们可以再次应用相同的模式 即。 f(“0123”)=“0”+ f(“123”),“1”+ f(“023”),“2”+ f(“013”),“3”+ f(“012”) ,当长度为3时,我们已经知道如何解决这个问题,所以现在我们知道如何在输入长度为4时解决问题。
我可以继续,并在代码中写出解决方案,但毫无疑问,有更好的资源用于学习递归,所以我会让你自己寻找它们。 但是,(我希望)我的解释足以让你思考正确的方向,甚至可以解决你的问题,而不必阅读任何额外的资源。
请记住,解决递归问题的关键是从最简单的情况开始,然后从那里开始构建。
答案 1 :(得分:0)
您可能需要查看按字典顺序生成 next 排列的the following algorithm。
在传递给生成算法之前,必须按升序对初始数组进行排序。
以下算法在给定排列后按字典顺序生成下一个排列。它就地改变了给定的排列。
- 找到
k
这样的最大索引a[k] < a[k + 1]
。如果不存在这样的索引,则排列是最后的排列。- 找到最大的索引
l
,使a[k] < a[l]
。- 将
的值互换a[k]
的值与a[l]
。- 将序列从
醇>a[k + 1]
反转至最终元素a[n]
。