我有一个像[0,2,3,0,1]
这样的数组作为输入,我需要找到{0}x{0,1,2}x{0,1,2,3}x{0}x{0,1}
的笛卡尔积,更确切地说我需要输出如下。
输入:
[0, 2, 3, 0, 1]
输出:
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 1]
[0, 0, 1, 0, 0]
[0, 0, 1, 0, 1]
[0, 0, 2, 0, 0]
[0, 0, 2, 0, 1]
[0, 0, 3, 0, 0]
[0, 0, 3, 0, 1]
[0, 1, 0, 0, 0]
[0, 1, 0, 0, 1]
[0, 1, 1, 0, 0]
[0, 1, 1, 0, 1]
[0, 1, 2, 0, 0]
[0, 1, 2, 0, 1]
[0, 1, 3, 0, 0]
[0, 1, 3, 0, 1]
[0, 2, 0, 0, 0]
[0, 2, 0, 0, 1]
[0, 2, 1, 0, 0]
[0, 2, 1, 0, 1]
[0, 2, 2, 0, 0]
[0, 2, 2, 0, 1]
[0, 2, 3, 0, 0]
[0, 2, 3, 0, 1]
我需要一般的算法。任何的想法 ?我想用c ++编写它。 感谢
答案 0 :(得分:1)
硬编码解决方案将是:
for (int a1 : {0}) {
for (int a2 : {0,1,2}) {
for (int a3 : {0,1,2,3}) {
for (int a4 : {0}) {
for (int a5 : {0,1}) {
do_job(a1, a2, a3, a4, a5);
}
}
}
}
}
您可以使用以下方法进行通用方式(将所有a
放入向量中):
bool increase(const std::vector<std::size_t>& v, std::vector<std::size_t>& it)
{
for (std::size_t i = 0, size = it.size(); i != size; ++i) {
const std::size_t index = size - 1 - i;
++it[index];
if (it[index] > v[index]) {
it[index] = 0;
} else {
return true;
}
}
return false;
}
void iterate(const std::vector<std::size_t>& v)
{
std::vector<std::size_t> it(v.size(), 0);
do {
do_job(it);
} while (increase(v, it));
}
答案 1 :(得分:1)
从您的示例中,您似乎想要使用混合基数,并且您的输入是每个位置的最大数字值。
一种简单的方法是使用算术编码,特别处理最大数字0位置。这是没有0个最大数字的情况下的伪代码:
System.Timers.Timer
我将0的处理作为一个位置的最大数字,作为练习。 :)
我不记得在C ++标准库中对此有任何特别相关的支持。即它主要是一个与语言无关的问题,与C ++无关,与排列无关,与数组无关。只要我对它的解释是正确的:用语言来描述问题会更好,而不仅仅是一个例子。
答案 2 :(得分:0)
递归似乎是解决此问题的最简单方法,因为您可能不知道输入向量的长度。像这样:
import java.util.ArrayList;
import java.util.Arrays;
public class Cartesian {
public static void printCartesian(String head, ArrayList<Integer> array) {
if (array.size() == 0) {
System.out.println(head);
return;
}
if (array.size() == 1) {
for (int i = 0; i <= array.get(0); ++i) {
System.out.println(head + i + "]");
}
return;
}
// assert array.size() > 1
int a0 = array.get(0);
ArrayList<Integer> array0 = new ArrayList<Integer>(array);
array0.remove(0);
for (int i = 0; i <= a0; ++i) {
printCartesian(head + i + ", ", array0);
}
}
public static void main(String[] args) {
Integer[] input = { 0, 2, 3, 0, 1 };
ArrayList<Integer> array = new ArrayList<Integer>(Arrays.asList(input));
printCartesian("[", array);
}
}
初始调用将是printCartesian("[", a)
,其中a
是一个ArrayList,按顺序包含数组的元素。必须为if
添加额外的size == 1
子句,否则会打印太多逗号。
将其转换为C ++数据结构应该不难。