重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
答:因为解决组合问题要用到阶乘,计算机系统不可能直接计算较大数的阶乘。如:本机: ULLONG_MAX = 18446744073709551615 为20位数,最大可计算 20! = 2432902008176640000 为19位数,以上是64位计算机、windows7(32位)、gcc10编译器的情况,所以不可能解决输入任意多个元素的问题。必须根据自己的系统来决定最多可以求多少元素的组合问题。
我们提供的服务有:成都做网站、成都网站建设、微信公众号开发、网站优化、网站认证、明溪ssl等。为上1000+企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的明溪网站制作公司
long long permutation(int m, int n)
{
int i;
long long result = 1;
for (i = m; i m - n; i--)
result *= i;
return result;
}
这个函数计算A(n,m),即n(n-1)(n-2)……(n-m+1)
主要的错误在于函数的参数传递理解上,如果要修改实参的值,应该采用地址传递,而程序设计的函数采用的是值传递,这种方式实参只向形参传递数据,而形参是无法向实参传递的
#includestdio.h
int main()
{
int factorial(int x);
printf("请输入n和m的值,他们分别作为排列组合的符号的上角标和小角标。n,m必须大于等于零。\n");
printf("标注:n代表“参与选择的元素个数”,m表示“元素的总个数”,用C来表示“排列组合”。\n");
int C,n,m,t,a,b;
printf("n=");
scanf("%d",n);
a=n;
n=factorial(n);//这里只是将n的值传递给x,并不修改n的值,必须显示进行赋值
printf("m=");
scanf("%d",m);
b=m;
m=factorial(m);//这里只是将m的值传递给x,并不修改m的值,必须显示进行赋值
t=a-b;
t=factorial(t);//这里只是将t的值传递给x,并不修改t的值,必须显示进行赋值
C=n/(m*t);
printf("本次排列组合输出的结果=%d,即有%d种排列方法。\n",C,C);//漏了一个变量
return 0;
}
int factorial(int x)
{
int i;
i=x-1;
if(x==0||x==1)x=1;//当n为0时,n的阶乘结果为1。且当x=1是,阶乘应为1。
else
{
while(i=1)
{
x=x*i;
i--;
}
}
return(x);
}
#include stdio.h
#include stdlib.h
int n = 0;
void swap(int *a, int *b)
{
int m;
m = *a;
*a = *b;
*b = m;
}
void perm(int list[], int k, int m)
{
int i;
if(k m)
{
for(i = 0; i = m; i++)
printf("%d ", list[i]);
printf("\n");
n++;
}
else
{
for(i = k; i = m; i++)
{
swap(list[k], list[i]);
perm(list, k + 1, m);
swap(list[k], list[i]);
}
}
}
int main()
{
int k;//输入自然数的个数
printf("请输入连续自然数的个数:");
scanf("%d",k);
int *list = (int *)malloc(k);
for (int i = 0; i k; i ++)
{
list[i] = i + 1;
}
// int list[] = {1, 2, 3, 4, 5};
perm(list, 0, k-1);
printf("total:%d\n", n);
return 0;
}
该程序的输入为一个任意自然数n,将输出从1到n的全排列。
扩展资料:
C语言的基本数的排列法
1、冒泡排序:每次相邻两个数比较,若升序,则将大的数放到后面,一次循环过后,就会将最大的数放在最后。
#include stdio.h
int main(void)
{
int a[1001];
int n,i,j,t;
scanf("%d",n);//n为要排序的数的个数
//输入要排序的数
for(i=0;in;++i)
scanf("%d",a+i);
//接下来进行排序
for(i=0;in-1;++i)//n个数,总共需要进行n-1次
{ //n-1个数排完,第一个数一定已经归位
//每次会将最大(升序)或最小(降序)放到最后面
for(j=0;jn-i-1;++j)
{
if(a[j]a[j+1])//每次冒泡,进行交换
{
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
for(j=0;jn;++j)
printf("%-5d ",a[j]);
printf("\n\n");
}
return 0;
}
2、选择排序:从第一个数开始,每次和后面剩余的数进行比较,若升序,则如果后边的数比当前数字小,进行交换,和后面的所有的数比较、交换后,就会将当前的最小值放在当前的位置。
#include stdio.h
int main(void)
{
int a[1001];
int n,i,j,t;
scanf("%d",n);//n为要排序的数的个数
//输入需要排序的数
for(i=0;in;++i)
scanf("%d",a+i);
//接下来进行排序
for(i=0;in-1;++i)//因为每次需要和a[i]后面的数进行比较,所以到a[n-2](倒数第2个元素)就行
{
for(j=i+1;jn;++j)//j从i后一个开始,a[i]与a[j]进行比较
{
if(a[i]a[j])//a[i]为当前值,若是比后面的a[j]大,进行交换
{
t=a[i];
a[i]=a[j];
a[j]=t;
}
}//每排序一次,就会将a[i](包括a[i])之后的最小值放在a[i]的位置
for(j=0;jn;++j)
printf("%-5d",a[j]);
printf("\n\n");
}
return 0;
}
#includestdio.h
#includestring.h
void
Show(int
n,int
len
,char
str[],
char
p[],int
*i)
{
/*函数功能说明: 密码穷举法
递归算法
参数说明:
len
密码可选元素的个数,实际等于
strlen(str);
n
密码位数。
STR[]密码表。
*p
密码排列组合的临时存档
*/
int
a;
n--;
for(a=0;
a
len;
a++)
{
p[n]=str[a];
if(n==0)printf("%d:%s
",(*i)++,p);
if(n0)Show(n,len
,
str,p,i);
}
} /*驱动程序
用于测试*/
int
main(void)
{
char
str[]="abcdef";//密码表
可选元素集合可根据选择修改
int
n=4; //密码位数,根据具体应用而定。
int
len=strlen(str);//用于密码元素集合计数。
char
p[20]; //存放排列组合的密码,用于输出。
int
num=0;//存放统计个数的整数值,
int
*i=num;//计数器
地址。
p[n]='\0';//这个不用说啦。 Show(
n,len
,str,
p
,i);
printf("\n%d
位密码,每个密码有%d个选择的话,共有:%d个组合。\n",n,len,*i); return
0;
}
#includestdio.h
int com(int m,int n)//m中取n个
{
int i,j,sum=1;
for (i=m,j=0;jn;j++,i--)
{
sum=sum*i/(j+1);
}
return sum;
}
int main()
{
int i;
i=com(5,3);
printf("%d",i);
return 0;
}