参数的排列组合
比如一个参数的取值范围是[a,b,c,d],那么有哪些组合呢?
个数 | 取值可能 | 组合的个数 |
---|---|---|
一个值 | a,b,c,d | 4 |
两个值 | ab,ac,ad,bc,bd,cd | 6 |
三个值 | 无a,无b,无c,无d | 4 |
四个值 | abcd | 1 |
如果ab,和ba算不同,那么有多少种可能呢?
个数 | 取值可能(factorial) | 排列组合的个数 | 重复的遍数(ab和ba算重复) |
---|---|---|---|
一个值 | 4 | 4 | 1个元素的排列(1的阶乘) |
两个值 | 4*3 | 12 | 2个元素的排列(2的阶乘) |
三个值 | 4*3*2 | 24 | 3个元素的排列(3的阶乘) |
四个值 | 4*3*2*1 | 24 | 4个元素的排列(4的阶乘) |
为什么n个元素的排列数就是n的阶乘呢?
首先明白什么是阶乘?
1的阶乘是1
2的阶乘是2*1
3的阶乘是3*2*1
6的阶乘是6*5*4*3*2*1
我们有n个盒子,分别放置n个元素
第一回:我们从n个里面选择一个:有n种可能
第二回:我们从n-1个里面选择一个:有n-1种可能
第三回:我们从n-2个里面选择一个:有n-2种可能
第四回:我们从n-3个里面选择一个:有n-3种可能
……
最后我们只有一个可选
/***
* 部分阶乘
* @param base
* @param times
* @return
*/
public static int factorial(int base,int times){
int sum=1;
for(int i=0;i<times;i++){
sum=sum*base;
base--;
if(base==0){
break;
}
}
return sum;
}
/***
* 排列
* @param n
* @return
*/
public static int arrayArrange(int n){
if(n<2){
return 1;
}else{
return n*arrayArrange(n-1);
}
}
@Test
public void test_arg(){
int argCount=4;
Assert.assertEquals(1,getParameterSum(1));
Assert.assertEquals(3,getParameterSum(2));
Assert.assertEquals(7,getParameterSum(3));
Assert.assertEquals(15,getParameterSum(4));
System.out.println(getParameterSum(argCount));
}
/***
* 参数的取值个数,ab和ba算一种
* @param argCount
* @return
*/
public static int getParameterSum(int argCount){
int sum=0;
for(int i=0;i<argCount;i++){
int count=i+1;//参数组合的个数
sum+=(factorial(argCount,count)/arrayArrange(count));
}
return sum;
}