今天同学笔试,碰到了一个问题:从100个数中选出任意10个数,打印出所有可能。
这是排列,组合的问题,上网查了一下,挺多这方面的资料的,这是介绍一个组合算法:
假设从0-----5中选出3个数,那么可定义一个数组,数组下标为数据值,数组存储0,1,1表示选中,0表示未选中:
1 1 1 0 0
1 1 0 1 0
1 0 1 1 0
0 1 1 1 0
1 1 0 0 1
1 0 1 0 1
0 1 1 0 1
1 0 0 1 1
0 1 0 1 1
0 0 1 1 1
根据这个算法,自己写了一个程序(但是不知道到底为什么这样,如果有谁知道,请指教):
#include
<
stdio.h
>
#include < stdlib.h >
int * NUM; // 指向实际的数值
char * NUMFLAG; // 指向标志位
static int number; // 存储总个数
int sum = 0 ; // 记录有多少次
#define MAXNUM 5
#define NUM(i) (*(NUM+(i))) // 第i个所存储的值
#define NUMFLAG(i) (*(NUMFLAG+(i))) // 表示第i个是否被选中,保存的为0,1
#define swap(x,y) do {(x)=(x)^(y);(y)=(x)^(y);(x)=(x)^(y);}while(0);
void set ( int num, int Allnum) // 设置小于num的为1,大于的为0
{
int i;
for (i = 0 ;i < Allnum;i ++ )
{
if (i < num)
NUMFLAG(i) = ' 1 ' ;
else
NUMFLAG(i) = ' 0 ' ;
}
}
int init()
{
int i;
printf( " there are %d number,please input the number you want to take out:\n " ,MAXNUM);
scanf( " %d " , & number);
if (number > MAXNUM)
{
printf( " sorry,the number is too big!\n " );
return 1 ;
}
NUM = ( int * )(malloc( sizeof ( int ) * MAXNUM));
NUMFLAG = ( char * )(malloc( sizeof ( char ) * MAXNUM));
set (number,MAXNUM);
for (i = 0 ;i < MAXNUM;i ++ )
{
NUM(i) = i;
}
return 0 ;
}
void print()
{
int i = 0 ;
sum ++ ;
while (i < MAXNUM)
{
if (NUMFLAG(i) == ' 1 ' )
printf( " %d " ,NUM(i));
i ++ ;
}
printf( " \n " );
}
void assemble()
{
int j = 0 ,k = 0 ,number_0 = 0 ,number_1 = 0 ;
print();
do {
if (NUMFLAG(k) == ' 1 ' && NUMFLAG(k + 1 ) == ' 0 ' )
{
swap(NUMFLAG(k),NUMFLAG(k + 1 )); // 交换1,0
set (number_1,k); // 将所有1移到最左
print();
number_1 = 0 ;
number_0 = 0 ;
k = 0 ;
} else { // 并不是连续的1,0
if (NUMFLAG(k) == ' 1 ' )
number_1 ++ ; // 记录之前1的个数
else number_0 ++ ; // 记录0的个数
k ++ ;
}
} while ((k + 1 ) < MAXNUM);
}
int main()
{
init();
assemble();
printf( " there are %d\n " ,sum);
}
#include < stdlib.h >
int * NUM; // 指向实际的数值
char * NUMFLAG; // 指向标志位
static int number; // 存储总个数
int sum = 0 ; // 记录有多少次
#define MAXNUM 5
#define NUM(i) (*(NUM+(i))) // 第i个所存储的值
#define NUMFLAG(i) (*(NUMFLAG+(i))) // 表示第i个是否被选中,保存的为0,1
#define swap(x,y) do {(x)=(x)^(y);(y)=(x)^(y);(x)=(x)^(y);}while(0);
void set ( int num, int Allnum) // 设置小于num的为1,大于的为0
{
int i;
for (i = 0 ;i < Allnum;i ++ )
{
if (i < num)
NUMFLAG(i) = ' 1 ' ;
else
NUMFLAG(i) = ' 0 ' ;
}
}
int init()
{
int i;
printf( " there are %d number,please input the number you want to take out:\n " ,MAXNUM);
scanf( " %d " , & number);
if (number > MAXNUM)
{
printf( " sorry,the number is too big!\n " );
return 1 ;
}
NUM = ( int * )(malloc( sizeof ( int ) * MAXNUM));
NUMFLAG = ( char * )(malloc( sizeof ( char ) * MAXNUM));
set (number,MAXNUM);
for (i = 0 ;i < MAXNUM;i ++ )
{
NUM(i) = i;
}
return 0 ;
}
void print()
{
int i = 0 ;
sum ++ ;
while (i < MAXNUM)
{
if (NUMFLAG(i) == ' 1 ' )
printf( " %d " ,NUM(i));
i ++ ;
}
printf( " \n " );
}
void assemble()
{
int j = 0 ,k = 0 ,number_0 = 0 ,number_1 = 0 ;
print();
do {
if (NUMFLAG(k) == ' 1 ' && NUMFLAG(k + 1 ) == ' 0 ' )
{
swap(NUMFLAG(k),NUMFLAG(k + 1 )); // 交换1,0
set (number_1,k); // 将所有1移到最左
print();
number_1 = 0 ;
number_0 = 0 ;
k = 0 ;
} else { // 并不是连续的1,0
if (NUMFLAG(k) == ' 1 ' )
number_1 ++ ; // 记录之前1的个数
else number_0 ++ ; // 记录0的个数
k ++ ;
}
} while ((k + 1 ) < MAXNUM);
}
int main()
{
init();
assemble();
printf( " there are %d\n " ,sum);
}