有项目需求将二维数组转换笛卡尔积。
直接贴代码
public static void main(String[] args) {
Integer[][] arras = new Integer[][] { { 1, 2, 3, 4 }, { 5, 6, 7 }, { 8, 9 } };
Integer[][] indexAndLength = new Integer[2][arras.length];
for (int i = 0; i < arras.length; i++) {
indexAndLength[0][i] = 0;
indexAndLength[1][i] = arras[i].length;
}
getOptions(arras, indexAndLength);
}
private static void getOptions(Integer[][] arras, Integer[][] indexAndLength) {
for (int i = 0; i < arras.length; i++) {
System.out.print(arras[i][indexAndLength[0][i]] + " ");
}
System.out.println();
if (addIndex(indexAndLength, arras.length)) {
getOptions(arras, indexAndLength);
}
// return;
}
private static boolean addIndex(Integer[][] indexAndLength,Integer index) {
if (index <= 0) {
return false;
}
if((indexAndLength[0][index-1] = indexAndLength[0][index-1] +1) <indexAndLength[1][index-1]){
return true;
}
indexAndLength[0][index - 1] = 0;
return addIndex(indexAndLength, index - 1);
}
输出结果
1 5 8
1 5 9
1 6 8
1 6 9
1 7 8
1 7 9
2 5 8
2 5 9
2 6 8
2 6 9
2 7 8
2 7 9
3 5 8
3 5 9
3 6 8
3 6 9
3 7 8
3 7 9
4 5 8
4 5 9
4 6 8
4 6 9
4 7 8
4 7 9
上面的两次递归容易造成堆栈溢出
将getOptions方法修改while(true)模式
private static void getOptions(int[][] arras,int[][] indexAndLength){
long c = 0;
long start = System.currentTimeMillis();
while (true){
// for (int i = 0; i < arras.length; i++) {
// System.out.print(arras[i][indexAndLength[0][i]] + " ");
// }
// System.out.println();
c++;
if (!addIndex(indexAndLength,arras.length)) {
break;
}
}
System.out.println(c);
System.out.println(System.currentTimeMillis() - start);
}
测试代码如下
public static void main(String[] args) {
int[] chars = new int[]{1,2,3,4,5,6,7,8,9,0};
int passwordLength = new Scanner(System.in).nextInt();
if(passwordLength <=0 || passwordLength >= 20){
throw new RuntimeException("password length error");
}
int[][] arras = new int[passwordLength][];
int[][] indexAndLength = new int[2][passwordLength];
for(int i=0;i<passwordLength;i++){
arras[i] = chars;
indexAndLength[0][i] = 0;
indexAndLength[1][i] = arras[i].length;
}
getOptions(arras,indexAndLength);
}
测试结果 输入passwordLength=10(10的10次方的笛卡尔积)
10
Disconnected from the target VM, address: '127.0.0.1:50360', transport: 'socket'
10000000000
54758
10的10次方的笛卡尔积耗费54秒
addIndex方法改变数组下标的index过程如下图3*2的二维数组
可以在addIndex方法返回true之前 打印 System.out.println(Arrays.toString(indexAndLength[0])); 查看index数组