笛卡尔积的一种Java求法

在做一个算法的时候,某个函数由若干函数组合而成(如相加、减、乘、除等),例如下面函数g:

g(x1,x2,x3)=f1(x1)+f2(x2)+f3(x3)

假设x1的取值为离散变量的集合A{1,2,3}、x2的取值为集合B{1,2,3,4}、x3的取值为集合B{1,2,3,4,5}

那么函数g的参数取值将有3x4x5=60种组合,那如何求得这60种组合呢,这其实应该就是集合A、B、C的笛卡尔积

算法思路:

1)先求得AB=AxB

2)再求ABC=ABxC

实际上只需解决(1)就可以了,因为(2)和(1)的计算是一样的。

  • 因为结果集合是一个2维数组,为统一起见,需要将(1)中的一维数组转换成二维数组

                 这个简单,可通过trans2DimMatrix(int d[])加以转换

  • 需要设置两个计数器c1、c2,c1计数第一个集合的取值,c2计数第二个集合的取值,

                  当c2达到第二个集合的长度后重新从0计数,同时c1加1,当c1达到第一个集合长度时结束循环

代码如下:


public class t {
   
    //将一维数组d转换成二维数组,统一结果
	public static int[][] trans2DimMatrix(int d[])
	{
		int r[][]=new int[d.length][1];
		for(int i=0;i<d.length;i++)
			r[i][0]=d[i];
		return r;
	}
    //dom X dom X dom ...
    //注意,第一个参数是二维数组,第二个是一维数组
	public static int[][] decare(int dom1[][],int dom2[])
	{
	   	int l=dom1.length*dom2.length; //组合个数
	   	int r[][]=new int[l][dom1[0].length+1]; //增加一列
	    int c1=0,c2=0,i=0;
	    while(c1<dom1.length) //c1对第一个数组进行计数
	    {
	       	for(int k=0;k<dom1[0].length;k++) //拷贝第一个数组
	       		r[i][k]=dom1[c1][k];
	    	r[i][dom1[0].length]=dom2[c2]; //附加上去
	       	i++;
	       	c2++;
	       	if(c2==dom2.length) {c2=0;c1++;} //c2重新计数,c1加1
	       }
	   	return r;
	}
	
	public static void main(String[] args) {  //测试
		// TODO Auto-generated method stub
         int dom1[]= {1,2,3};
         int dom2[]= {1,2,3,4};
         int dom3[]= {1,2,3,4,5};
         int y[][]=decare(trans2DimMatrix(dom1),dom2);
         int x[][]=decare(y,dom3);
         for(int i=0;i<x.length;i++)
         {
             System.out.print(i+":");
        	 for(int j=0;j<x[i].length;j++)
        		 System.out.print(x[i][j]+" ");
        	 System.out.println();
         }
	}

}

测试结果如下:

0:1 1 1 
1:1 1 2 
2:1 1 3 
3:1 1 4 
4:1 1 5 
5:1 2 1 
6:1 2 2 
7:1 2 3 
8:1 2 4 
9:1 2 5 
10:1 3 1 
11:1 3 2 
12:1 3 3 
13:1 3 4 
14:1 3 5 
15:1 4 1 
16:1 4 2 
17:1 4 3 
18:1 4 4 
19:1 4 5 
20:2 1 1 
21:2 1 2 
22:2 1 3 
23:2 1 4 
24:2 1 5 
25:2 2 1 
26:2 2 2 
27:2 2 3 
28:2 2 4 
29:2 2 5 
30:2 3 1 
31:2 3 2 
32:2 3 3 
33:2 3 4 
34:2 3 5 
35:2 4 1 
36:2 4 2 
37:2 4 3 
38:2 4 4 
39:2 4 5 
40:3 1 1 
41:3 1 2 
42:3 1 3 
43:3 1 4 
44:3 1 5 
45:3 2 1 
46:3 2 2 
47:3 2 3 
48:3 2 4 
49:3 2 5 
50:3 3 1 
51:3 3 2 
52:3 3 3 
53:3 3 4 
54:3 3 5 
55:3 4 1 
56:3 4 2 
57:3 4 3 
58:3 4 4 
59:3 4 5 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值