我有一个数组U
的数组D
,其长度各不相同。我需要能够返回数组索引的所有排列,这些排列将选择由每个集合中的1个元素组成的不同排列。我还要求将此算法表示为仅记住最后一个排列的对象,并使用get_next方法返回下一个排列。
例如,U = [array_of_size_n1, array_of_size_n2, array_of_size_n3]
会有n1*n2*n3
个排列,每个 3 元素都很长。
修改:套数也有所不同。
答案 0 :(得分:2)
如果你正在使用python,这是标准库的一部分:itertools.product
。但假设你不是,这是伪代码版本。
// Create an initialised array of indexes.
int[] index0(arrays) {
// We require all arrays to be non-empty.
for a in arrays {
assert len(a) != 0;
}
return new int[len(arrays)];
}
// Increment the indices. Returns false when the indices wrap round to the start.
bool next_index(indices, arrays) {
for (i = len(indices) - 1; i >= 0; --i) {
indices[i] += 1
if indices[i] < len(arrays[i]) {
return true;
}
indices[i] = 0;
}
return false;
}
你可以像这样使用它(假设你的数组都不是空的)。此示例打印出数组中每个元素的组合。
indices = index0(arrays);
{
for (i = 0; i < len(arrays); ++i) {
print arrays[i][indices[i]];
}
print
} while next_index(indices);
答案 1 :(得分:1)
你可以在每个阵列中为你的个人位置保留一个计数器。在你的get_next方法中,将计数器增加一个,然后按数组的长度进行修改。然后,每当前一个计数器翻转为0时,只需增加下一个计数器;
if (pos3 == array_of_size_n3 -1)
{
if (pos2 == size_of_array_2 -1)
{
pos1 = (pos1 + 1) % size_of_array_1
}
pos2 = (pos2 + 1) % size_of_array_2
}
pos3 = (pos3 + 1) % size_of_array_3
print array1[pos1], array2[pos2], array3[pos3]
编辑:如果数组的数量不同,请将位置变量保存在数组中。实际上,无论如何这可能会更好。这样你可以像引用数组本身一样引用pos变量。
答案 2 :(得分:0)
那么......这个不是直截了当的呢?
你想要一个迭代器。您希望它迭代最后一个数组。当它到达该数组的末尾时,在第二个数组中递增其当前位置,然后返回到最后一个数组的开头。
psuedocode使用C#s yield return
语法:
foreach n1 in a1
foreach n2 in a2
foreach n3 in a3
yield return (n1, n2, n3)
编辑:如果集的数量不同,您可以使用某种形式的递归:
function next(list)
firstArray = list.first
iterator = iterator(list.rest)
if !iterator
foreach i in firstArray
yield return i
else
foreach i in firstArray
while (iterator.hasNext)
yield return (i, iterator.next)
考虑传入长度为1的列表时的行为,然后考虑长度为2的列表的行为,并确保它确实可以正常工作。
答案 3 :(得分:0)
为了解决Anon所说的问题,你不要只是循环它们。您在类中维护状态,以便了解每个数组的最后一个索引。逻辑是相同的,但您不会在连续循环中运行。伪代码逻辑将是:
get_next() { oldn3 = this.n3; oldn2 = this.n2; oldn1 = this.n1; if(this.n3 == this.a3.Count) this.n3 = 0; else this.n3++; if(oldn3 > this.n3) if(this.n2 == this.a2.Count) this.n2 = 0; else this.n2++; if(oldn2 > this.n2) if(this.n1 == this.a1.Count) this.n1 = 0; else this.n1++; if(oldn1 > this.n1) return NO_MORE_PERMS; return [n1,n2,n3]; } getCurrent() { return [n1,n2,n3]; }