定义两个函数 分别输出m个数中n个数的排列 与组合
例如 1 2 3 这三个数 两个数的排列与组合
排列: 1 2; 1 3;2 1; 2 3;3 1;3 3;
组合:1 2; 1 3; 2 3;
跪求编程原理 注意 是原理啊 即使没有代码 也行!!! 我要的是方法!!1
[解决办法]
#include <stdio.h>#include <stdlib.h>bool find_arr( int a[], int length , int value ){ for( int i = 0; i < length; ++i ) { if( a[i] == value ) return true; } return false;}int main(){ int len; int *arr; int i = 0, j = 0; printf("input the array numbers: "); scanf("%d",&len); arr = new int[len]; for( i = 0; i < len; ++i ) { printf("input the %d number: ",i + 1); scanf("%d",&arr[i]); } printf("排列:"); for( i = 0; i < len; ++i ) { for( j = 0; j < len; ++j ) { if( arr[i] != arr[j] ) { printf("%d %d ;",arr[i],arr[j]); } } } printf("\n组合:"); for( i = 0; i < len; ++i ) { for( j = i + 1; j < len; ++j ) { printf("%d %d ;",arr[i],arr[j]); } } printf("\n"); return 0;}
[解决办法]
/*求(1...m)中,n个数的组合本程序的思路是开一个数组,其下标表示1到m个数,数组元素的值为1表示其下标代表的数被选中,为0则没选中。 首先初始化,将数组前n个元素置1,表示第一个组合为前n个数。 然后从左到右扫描数组元素值的“10”组合,找到第一个“10”组合后将其变为“01”组合, 同时将其左边的所有“1”全部移动到数组的最左端。 当第一个“1”移动到数组的m-n的位置,即n个“1”全部移动到最右端时,就得到了最后一个组合。 例如求5中选3的组合: 1 1 1 0 0 //1,2,3 1 1 0 1 0 //1,2,4 1 0 1 1 0 //1,3,4 0 1 1 1 0 //2,3,4 1 1 0 0 1 //1,2,5 1 0 1 0 1 //1,3,5 0 1 1 0 1 //2,3,5 1 0 0 1 1 //1,4,5 0 1 0 1 1 //2,4,5 0 0 1 1 1 //3,4,5 */#include <stdio.h>#include <malloc.h>//输出void output(int *num, int m){ int i; for(i = 0; i < m; ++i) if(*(num+i) == 1) printf("%d ", i+1); printf("\n");}//检测n个“1”是否全部移动到最右端//是则返回1int check(int *num, int m, int n){ int i, flag = 1; for(i = m-1; i > m-n-1; --i) { if(*(num+i) == 0) { flag = 0; break; } } return flag;}void chooseNum(int m, int n){ int *num, i, j, count; num = (int*)malloc(sizeof(int)*m); for(i = 0; i < n; ++i)//前n个元素置1 *(num+i) = 1; if(m == n) { output(num, m); return; } for(i = n; i < m; ++i)//后面m-n个元素置0 *(num+i) = 0; output(num, m); while(1) { count = 0; //找到第一个“10”组合后将其变为“01”组合 for(i = 0; i < m-1; ++i) { if(*(num+i) == 1 && *(num+i+1) == 0) { *(num+i) = 0; *(num+i+1) = 1; break; } if(*(num+i) == 1) ++count; } //将其左边的所有“1”全部移动到数组的最左端 for(j = 0; j < i; ++j) { if(j < count) *(num+j) = 1; else *(num+j) = 0; } output(num, m); if(check(num, m, n) == 1) break; } free(num); }int main(){ int m = 3, n = 2; //scanf("%d%d", &m, &n); chooseNum(m, n); return 0;}
[解决办法]
#include <stdio.h>#include <stdlib.h>#define MAX_NUM 26int comb[MAX_NUM];int c1,c2;void combination(int m, int n){ int i, j; for (i = m; i >= n; i--){ comb[n] = i; /* 选择当前的“头”元素 */ if (n > 1){ /* 进入下一次更小的组合问题 */ combination(i - 1, n - 1); }else{ /* 满了需要的组合数,输出 */ for (j = comb[0]; j > 0; j--){ printf("%c", 65+c1-comb[j]); } printf("\n"); } } return;}int main(int argc, char *argv[]){ if (argc<3) { printf("%s 组合下标 组合上标\n",argv[0]); return 0; } c1=atoi(argv[1]); if (c1<1||26<c1) { printf("1<=组合下标<=26\n"); return 0; } c2=atoi(argv[2]); if (c2<1||c1<c2) { printf("1<=组合上标<=组合下标\n"); return 0; } comb[0]=c2; combination(c1, c2); /* C(4, 2) */ return 0;}