c语言所有组合
‘壹’ c语言 跪求:输入M个数从中取N个数进行组合并输出所有组合项
典型的组合问题,解法有递归、回溯等等
递归法较简单,代码如下:
void combine(int a[], int n, int m, int b[], int M);
参数:
a 存放候选数字
n 总项数
m 取出项数
b 存放选出结果
M = m
#include "stdio.h"
#define MAX 100
void combine(int a[], int n, int m, int b[], int M);
int main(void)
{
int i;
int a[MAX], b[MAX];
for (i = 1; i < 100; i++)
a[i - 1] = i;
combine(a, 5, 4, b, 4);
}
void combine(int a[], int n, int m, int b[], int M)
{
int i, j;
for (i = n; i >= m; i--)
{
b[m - 1] = i - 1;
if (m > 1)
combine(a, i - 1, m - 1, b, M);
else
{
for (j = M - 1; j >= 0; j--)
printf("%d ", a[b[j]]);
printf("\n");
}
}
}
其他方法可查阅相关资料。
‘贰’ C语言 排列组合
发个C#的代码:
int[] a = { 1 , 2 , 3 , 4 , 5 , 6 };
int weishu = 6;
int weishu2 = weishu - 1;
int zuida = (int)Math.Pow( 2 , weishu2 );
List<int[]> list = new List<int[]>();
for ( int i = 0 ; i < zuida ; i++ )
{
int[] b = (int[])a.Clone();
for ( int j = 0 ; j < weishu2 ; j++ )
{
int c = i >> j;
if ( (c & 1) == 1 )
{
int tmp = b[ j ];
b[ j ] = b[ j + 1 ];
b[ j + 1 ] = tmp;
}
}
list.Add( b );
}
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.AppendLine( string.Format( "共 {0} 个结果" , list.Count ) );
foreach ( int[] aa in list )
{
for ( int i = 0 ; i < aa.Length ; i++ )
{
sb.Append( aa[ i ] );
if ( (i & 1) == 1 )
sb.Append( '\t' );
}
sb.AppendLine();
}
Console.WriteLine( sb.ToString() );
运行结果:
共 32 个结果
12 34 56
21 34 56
13 24 56
23 14 56
12 43 56
21 43 56
13 42 56
23 41 56
12 35 46
21 35 46
13 25 46
23 15 46
12 45 36
21 45 36
13 45 26
23 45 16
12 34 65
21 34 65
13 24 65
23 14 65
12 43 65
21 43 65
13 42 65
23 41 65
12 35 64
21 35 64
13 25 64
23 15 64
12 45 63
21 45 63
13 45 62
23 45 61
‘叁’ C语言求所有组合
STL的next_permuatation
试试罗
‘肆’ 跪求一个C语言程序,实现功能:任意输入3个数,求出全部的组合。如365,全部组合有27种
3个的 要写多个的也可以改
#include <stdio.h>
#include "string.h"
main()
{
int i,j,k,nLen,count=0;
char a3="\0";
gets(a);
nLen = strlen(a);
for (i=0;i<nLen;i++)
{
for (j=0;j<nLen;j++)
{
for (k=0;k<nLen;k++)
{
printf("%c%c%c ",ai,aj,ak);
count++;
if (count%9==0)
{
printf("\n");
}
}
}
}
}
‘伍’ C语言如何实现任意数排列组合,新手求助,急
求排列组合没有简单方法。方法只有一个,枚举。
有几个位置需要列举,就需要几个循环。如果循环数量太多,可以用函数递归来枚举。
例程:
#include<stdio.h>
intmain(){
inta[4]={1,3,4,7};//第一个位置
intb[4]={2,5,8,10};//第二个位置
intc[4]={6,9,11,12};//第三个位置
inti,j,k;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
for(k=0;k<4;k++)
printf("%d%d%d ,",a[i],b[j],c[k]);//输出一种排列
getch();
return0;
}
‘陆’ 用c语言编制一程序,列出0--9十个数的所有排列组合
这个是排列,如果是组合最后一个循环判断时候有相等的:
#include<stdio.h>
int
main()
{
for(int
i0=0;i0<9;i0++)
for(int
i1=0;i1<9;i1++)
for(int
i2=0;i2<9;i2++)
for(int
i3=0;i3<9;i3++)
for(int
i4=0;i4<9;i4++)
for(int
i5=0;i5<9;i5++)
for(int
i6=0;i6<9;i6++)
for(int
i7=0;i7<9;i7++)
for(int
i8=0;i8<9;i8++)
for(int
i9=0;i9<9;i9++)
printf("\n%d%d%d%d%d%d%d%d%d%d",i0,i1,i2,i3,i4,i5,i6,i7,i8,i9);
}
‘柒’ C语言打印一窜数字的所有组合
1.楼主的数太多了,我的机器有点落伍,显示的时间有点漫长~~~~,我把数改成了1,2,3,3,4,7,7。显示上也简单点,原理是一样的。。。另外不是很清楚楼主的所有组合是不是包括取出一部分字符串做排列组合,我弄的是所有
数字用上的全排列,就是没有12,13这样的组合数,楼主如果是需要显示这样的数,只要在主函数中做循环,分别取出1至7个数再运行deal和排列函数就行(注,调试环境是VC++6.0)
#include "stdio.h"
#include "stdlib.h"
#define NUM 30
#define N 7 //数组元素个数
static int cnt=0;//用于记录重复数字的个数
void print(int n,int arr[]){
int i;
static int count=0;
printf("%d:",++count);
for(i=0;i<n;i++)
printf("%d",arr[i]);
printf("\t");
if(count%5==0)
printf("\n");
}
void arrange(int size,int arr[],int p){
//算法思想:采用经典回溯法,先确定第一个位置,再对余下的n-1位数字做全排列
//每组全排列后均把所有参与此次全排列的数与这次全排列的第一个数交换后再重复排列
//例如递归到排列1234后回溯一次即排列34,将4与3交换,再回溯至排列234分别将34与2交换后排列
//直至排列完成后,再分别将234与1交换后排列
//不过算法效率在数字过大后就比较低下了,楼主可以去网上找找更高效的算法
int i,temp;
if(p+1==size){//排列完成后打印
print(size,arr);
return;
}
for(i=p;i<size;i++){//交换
temp=arr[p];
arr[p]=arr[i];
arr[i]=temp;
arrange(size,arr,p+1);//递归调用排列
temp=arr[p];
arr[p]=arr[i];
arr[i]=temp;
}
}
void deal(int a[],int b[]){
//将重复数字去掉,方便全排列
int i,j;
for(i=0;i<N;i++){
if(a[i]>0){
for(j=i+1;j<N;j++){
if(a[i]==a[j]){
a[j]=-1;//重复标志
cnt++;
}
}
}
}
j=0;
for(i=0;i<=N;i++){
if(a[i]>0){
b[j++]=a[i];
}
}
}
void main(){
int a[N]={1,2,3,3,4,7,7};
int b[NUM];
deal(a,b);//处理数组
arrange(N-cnt,b,0);//排列输出
}
2.和第一问一样,我只选了1,2,3,3,4,7,7。程序上只是打印函数改了下,deal函数做了调整,本来想在第一问的排列基础上再在特定的位置上插入3和7,后来发现会重复,做了很久的无用功啊。。print中的循环太多了,看起来有点累,不过主要的就是两个大的东西,两个循环实际是一样的原理,楼主有兴趣可试着把循环换成一个函数,可读性会强点。下面的代码适用性还是很广的。
#include "stdio.h"
#include "stdlib.h"
#define NUM 30
#define N 7
static int cnt=0;//用于记录重复数字的个数
static int t[N];//用于记录重复数字
void print(int n,int arr[]){
//算法思想:对有重复的数字组合排列,将它看成是对空余位置填充数字
//先将重复的数字进行填充,即在空余位置中取定重复数的位置,再对余下的位置进x行全排列填充
//按此思想得到的个数为 =1260个
int a1[N-2],a2[N];
static int count=0;
for(int i=0;i<N-cnt/2-1;i++){
//取5个数,包括完全没重复的数再加上重复的数(例如:1,2,4,3,3)
//对这5个数按照算法思想排列
a1[i]=t[0];
for(int j=i+1;j<=N-cnt/2-1;j++){
a1[j]=t[0];
for(int k=0;k<i;k++)
a1[k]=arr[k];
for(int m=i+1;m<j;m++)
a1[m]=arr[m-1];
for(int p=j+1;p<N-cnt/2;p++)
a1[p]=arr[p-2];
for(int s=0;s<N-1;s++){//将7个数取出按照算法排列
a2[s]=t[1];
for(int r=s+1;r<=N-1;r++){
a2[r]=t[1];
for(int y=0;y<s;y++)
a2[y]=a1[y];
for(int x=s+1;x<r;x++)
a2[x]=a1[x-1];
for(int h=r+1;h<N;h++)
a2[h]=a1[h-2];
printf("%d:",++count);
for(int c=0;c<N;c++)//将该排列打印出来
printf("%d",a2[c]);
printf("\t");
if(count%5==0)
printf("\n");
}
}
}
}
}
void arrange(int size,int arr[],int p){
int i,temp;
if(p+1==size){//排列完成后打印
print(size,arr);
return;
}
for(i=p;i<size;i++){//交换
temp=arr[p];
arr[p]=arr[i];
arr[i]=temp;
arrange(size,arr,p+1);//递归调用排列
temp=arr[p];
arr[p]=arr[i];
arr[i]=temp;
}
}
void deal(int a[],int b[]){
//将数组处理成只剩不重复排列的数
int i,j,k=0;
for(i=0;i<N;i++){
if(a[i]>0){
for(j=i+1;j<N;j++){
if(a[i]==a[j]){
t[k++]=a[i];//记录重复数
a[i]=-1;
a[j]=-1;
cnt+=2;
}
}
}
}
j=0;
for(i=0;i<=N;i++){
if(a[i]>0){
b[j++]=a[i];
}
}
}
void main(){
int a[N]={1,2,3,3,4,7,7};
int b[NUM];
deal(a,b);//处理数组
arrange(N-cnt,b,0);//排列输出
}
3.第三问比较简单,在第二问打印程序上加上限制条件(即第三位不能是3,第七位不能是七)
#include "stdio.h"
#include "stdlib.h"
#define NUM 30
#define N 7
static int cnt=0;//用于记录重复数字的个数
static int t[N];//用于记录重复数字
void print(int n,int arr[]){
int a1[N-2],a2[N];
static int count=0;
for(int i=0;i<N-cnt/2-1;i++){
a1[i]=t[0];
for(int j=i+1;j<=N-cnt/2-1;j++){
a1[j]=t[0];
for(int k=0;k<i;k++)
a1[k]=arr[k];
for(int m=i+1;m<j;m++)
a1[m]=arr[m-1];
for(int p=j+1;p<N-cnt/2;p++)
a1[p]=arr[p-2];
for(int s=0;s<N-1;s++){
a2[s]=t[1];
for(int r=s+1;r<=N-1;r++){
a2[r]=t[1];
for(int y=0;y<s;y++)
a2[y]=a1[y];
for(int x=s+1;x<r;x++)
a2[x]=a1[x-1];
for(int h=r+1;h<N;h++)
a2[h]=a1[h-2];
if(a2[2]!=t[0]&&a2[6]!=t[1]){
printf("%d:",++count);
for(int c=0;c<N;c++)
printf("%d",a2[c]);
printf("\t");
if(count%5==0)
printf("\n");
}
}
}
}
}
}
void arrange(int size,int arr[],int p){
int i,temp;
if(p+1==size){//排列完成后打印
print(size,arr);
return;
}
for(i=p;i<size;i++){//交换
temp=arr[p];
arr[p]=arr[i];
arr[i]=temp;
arrange(size,arr,p+1);//递归调用排列
temp=arr[p];
arr[p]=arr[i];
arr[i]=temp;
}
}
void deal(int a[],int b[]){
//将数组处理成只剩不重复排列的数
int i,j,k=0;
for(i=0;i<N;i++){
if(a[i]>0){
for(j=i+1;j<N;j++){
if(a[i]==a[j]){
t[k++]=a[i];//记录重复数
a[i]=-1;
a[j]=-1;
cnt+=2;
}
}
}
}
j=0;
for(i=0;i<=N;i++){
if(a[i]>0){
b[j++]=a[i];
}
}
}
void main(){
int a[N]={1,2,3,3,4,7,7};
int b[NUM];
deal(a,b);//处理数组
arrange(N-cnt,b,0);//排列输出
}
‘捌’ C语言编程实现 凑15的所有组合
#include<stdio.h>
#include<string.h>
#define MAX 11
bool used[MAX]={false};
int a[MAX];
int ok(int a[])
{
int i;
for(i=0;i<9;i+=3)
{
if(a[i]+a[i+1]+a[i+2]!=15)return false;
}
for(i=0;i<3;i++)
{
if(a[i]+a[i+3]+a[i+6]!=15)return false;
}
if(a[0]+a[4]+a[8]!=15)return false;
if(a[6]+a[4]+a[2]!=15)return false;
return true;
}
void DFS(int deep)
{
int i;
if(deep==9)
{
if(ok(a))
{
puts("start");
for(i=0;i<9;i+=3)
{
printf("%d %d %d\n",a[i],a[i+1],a[i+2]);
}
puts("end");
}
return ;
}
for(i=1;i<10;i++)
{
if(used[i])continue;
used[i]=true;
a[deep]=i;
DFS(deep+1);
used[i]=false;
}
}
int main(void)
{
DFS(0);
return 0;
}
‘玖’ c++/c语言 枚举所有组合并输出
楼上的递归实现确实不错,但是坏处是不方便将所有的排列组合结果保存起来,除非用上全局变量或静态变量。
如果nCount是固定的,问题就会变得非常简单,比如当nCount=3的时候,用上3个for循环即可。我借用宏来简化定义不同nCount情况下的代码,没有楼上的递归函数方法高明,但是执行效率应该会更高些,且方便收集所有的组合结果。
voidcombineAll(inta[],intnBegin,intnEnd,intnCount)
{
int*buf=newint[nCount*2+1];
int*end=buf,*arr=buf+nCount+1;//intend[nCount];intarr[nCount+1];
end[0]=nEnd-nCount+1;
for(intk=1;k<nCount;k++)
end[k]=end[k-1]+1;
arr[-1]=nBegin-1;
#defineLOOP(k)for(arr[k]=arr[k-1]+1;arr[k]<end[k];arr[k]++)
#defineSTORE{for(intk=0;k<nCount;k++)printf("%d",a[arr[k]]);printf("");}//orwecanpusha[arr[0~nCount]]toavector
switch(nCount){
case1:
LOOP(0)STOREbreak;
case2:
LOOP(0)LOOP(1)STOREbreak;
case3:
LOOP(0)LOOP(1)LOOP(2)STOREbreak;
case4:
LOOP(0)LOOP(1)LOOP(2)LOOP(3)STOREbreak;
case5:
LOOP(0)LOOP(1)LOOP(2)LOOP(3)LOOP(4)STOREbreak;
default:
throw;//orwecanusearecursivefunction
}
#undefLOOP
#undefSTORE
delete[]buf;
}
intmain()
{
inta[]={0,1,2,3,4,5};
intnBegin=0,nEnd=6,nCount=3;
PrintAll(a,nBegin,nEnd-1,nCount,"");
printf(" -------------------- ");
combineAll(a,nBegin,nEnd,nCount);
returngetchar();
}