C++递归求排列组合,在线等

deliah_ann 2012-05-04 08:20:25
给定两个自然数n(1~9)和r(n>r),请编程输出从1~n中按降序排序取r个自然数的所有组合。如n=5,r=3时,输出结果为:543,542,541,532,531,432,431,421,321。(递归函数
#include<iostream>
#include<cstring>
using namespace std;
int C(int n,int k) //计算从n各种选k个的取法
{
int product=1;
for(int x=n;x>n-k;x--) product*=x;
for(int x=1;x<=k;x++) product/=x;
return product;
}
void combination(int n,int r,char *a[])
{
if(r==1)//r=1的情况
{
for(int i=0;i<n;i++) a[i][0]=n-i+'0';
}
else if(n==r)//n=r时,只有一种排列方式
{
for(int i=0;i<n;i++) a[0][i]=n-i+'0';
}
else //一般情况,利用C(n,r)=C(n-1,r-1)(即第一个元素为n,再从1至n-1中挑r-1个)+C(n-1,r)(从1至n-1中挑r个)
{
char **p=new char*[C(n-1,r-1)];//为此种情况做准备:C(n,r)=C(n-1,r-1)(即第一个元素为n,再从1至n-1中挑r-1个)
for(int i=0;i<C(n-1,r-1);i++) p[i]=new char[r-1];

char **q=new char*[C(n-1,r)];//为此种情况做准备:C(n-1,r)(从1至n-1中挑r个)
for(int i=0;i<C(n-1,r);i++) q[i]=new char[r];

//第一种情况
combination(n-1,r-1,p);
for(int i=0;i<C(n-1,r-1);i++)
{
a[i][0]=n+'0';
for(int j=0;j<r-1;j++) a[i][j+1]=p[i][j];
}
for(int i=0;i<C(n-1,r-1);i++) delete[] p[i];
delete[] p;
//第二种情况
combination(n-1,r,q);
for(int i=C(n-1,r-1);i<C(n,r);i++)
{
for(int j=0;j<r;j++) a[i][j]=p[i-C(n-1,r-1)][j];
}
for(int i=0;i<C(n-1,r);i++) delete[] q[i];
delete[] q;
}
}
int main()
{
//输入
int n,r;
do
{
cout<<"请输入两个自然数n(1~9)和r(n>r),以编程输出从1~n中按降序排序取r个自然数的所有组合:"<<endl;
cin>>n>>r;
}while(n<=r||r<1||n>9);

//处理
char **a=new char*[C(n,r)];
for(int i=0;i<C(n,r);i++) a[i]=new char[r];
combination(n,r,a);

//输出
cout<<"组合方式如下:"<<endl;
for(int i=0;i<C(n,r);i++)
{
for(int j=0;j<r;j++) cout<<a[i][j];
cout<<"\t";
}


//善后
for(int i=0;i<C(n,r);i++) delete[] a[i];
delete[] a;
return 0;
}
请问问题出在哪里??
...全文
503 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
deliah_ann 2012-05-04
  • 打赏
  • 举报
回复
实验
deliah_ann 2012-05-04
  • 打赏
  • 举报
回复
怎么在回复中设代码格式?
hello_world000 2012-05-04
  • 打赏
  • 举报
回复
修改下,C++中,现在的编译器new失败会抛出异常,所以不用判断是不是为NULL

#include<iostream>

using namespace std;

void func(int n, const int r, int res[], int cnt = 0)
{
if (r == cnt || 0 == n)
{
if (r == cnt)
{
for (int i = 0; i < r; ++i)
{
cout<<res[i];
}
cout<<endl;
}
}
else
{
res[cnt] = n;
func(n - 1, r, res, cnt + 1);
func(n - 1, r, res, cnt);
}
}

int main()
{
int n, r;
cout<<"input n, r :"<<endl;
cin>>n>>r;

if (n < 1 || r < 1 || n < r)
{
return -1;
}
res = new int[r];

func(n, r, res);

delete[]res;
res = NULL;

system("pause");
return 0;
}

hello_world000 2012-05-04
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]
楼上的代码真简洁漂亮啊。。只是我没学过C,直接学的C++,很多看不懂。。但是十分感谢!!我会努力学习的!!
[/Quote]
下面算是C++吗?

#include<iostream>

using namespace std;

void func(int n, const int r, int res[], int cnt = 0)
{
if (r == cnt || 0 == n)
{
if (r == cnt)
{
for (int i = 0; i < r; ++i)
{
cout<<res[i];
}
cout<<endl;
}
}
else
{
res[cnt] = n;
func(n - 1, r, res, cnt + 1);
func(n - 1, r, res, cnt);
}
}

int main()
{
int n, r, *res;
cout<<"input n, r :"<<endl;
cin>>n>>r;

if (n < 1 || r < 1 || n < r)
{
return -1;
}
if (NULL == (res = new int[r]))
{
return -1;
}

func(n, r, res);

delete[]res;
res = NULL;

system("pause");
return 0;
}

deliah_ann 2012-05-04
  • 打赏
  • 举报
回复
晕,我说的楼上不是自己。。。
deliah_ann 2012-05-04
  • 打赏
  • 举报
回复
楼上的代码真简洁漂亮啊。。只是我没学过C,直接学的C++,很多看不懂。。但是十分感谢!!我会努力学习的!!
deliah_ann 2012-05-04
  • 打赏
  • 举报
回复
我自己改好了~~~~~撒花~~~
//给定两个自然数n(1~9)和r(n>r),请编程输出从1~n中按降序排序取r个自然数的所有组合。如n=5,r=3时,输出结果为:543,542,541,532,531,432,431,421,321。(递归函数
#include<iostream>
using namespace std;
int C(int n,int k) //计算从n各种选k个的取法
{
int product=1;
for(int x=n;x>n-k;x--) product*=x;
for(int x=1;x<=k;x++) product/=x;
return product;
}
void combination(int n,int r,int **a)
{
if(r==1)//r=1的情况
{
for(int i=0;i<n;i++) a[i][0]=n-i;
}
else if(n==r)//n=r时,只有一种排列方式
{
for(int i=0;i<n;i++) a[0][i]=n-i;
}
else //一般情况,利用C(n,r)=C(n-1,r-1)(即第一个元素为n,再从1至n-1中挑r-1个)+C(n-1,r)(从1至n-1中挑r个)
{
int **p=new int*[C(n-1,r-1)];//为此种情况做准备:C(n,r)=C(n-1,r-1)(即第一个元素为n,再从1至n-1中挑r-1个)
for(int i=0;i<C(n-1,r-1);i++) p[i]=new int[r-1];

int **q=new int*[C(n-1,r)];//为此种情况做准备:C(n-1,r)(从1至n-1中挑r个)
for(int i=0;i<C(n-1,r);i++) q[i]=new int[r];

//第一种情况
combination(n-1,r-1,p);
for(int i=0;i<C(n-1,r-1);i++)
{
a[i][0]=n;
for(int j=0;j<r-1;j++) a[i][j+1]=p[i][j];
}
for(int i=0;i<C(n-1,r-1);i++) delete[] p[i];
delete[] p;
//第二种情况
combination(n-1,r,q);
for(int i=C(n-1,r-1);i<C(n,r);i++)
{
for(int j=0;j<r;j++) a[i][j]=q[i-C(n-1,r-1)][j];
}
for(int i=0;i<C(n-1,r);i++) delete[] q[i];
delete[] q;
}
}
int main()
{
//输入
int n,r;
do
{
cout<<"请输入两个自然数n(1~9)和r(n>r),以编程输出从1~n中按降序排序取r个自然数的所有组合:"<<endl;
cin>>n>>r;
}while(n<=r||r<1||n>9);

//处理
int **a=new int*[C(n,r)];
for(int i=0;i<C(n,r);i++) a[i]=new int[r];
combination(n,r,a);

//输出
cout<<"组合方式如下:"<<endl;
for(int i=0;i<C(n,r);i++)
{
for(int j=0;j<r;j++) cout<<a[i][j];
cout<<"\t";
}


//善后
for(int i=0;i<C(n,r);i++) delete[] a[i];
delete[] a;
return 0;
}
hello_world000 2012-05-04
  • 打赏
  • 举报
回复

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

void func(int n, const int r, int res[], int cnt)
{
if (r == cnt || 0 == n)
{
if (r == cnt)
{
int i;
for (i = 0; i < r; ++i)
{
printf("%d", res[i]);
}
printf("\n");
}
}
else
{
res[cnt] = n;
func(n - 1, r, res, cnt + 1);
func(n - 1, r, res, cnt);
}
}

int main()
{
int n, r;
int *res;
puts("input n, r :");
scanf("%d%d", &n, &r);

if (n < 1 || r < 1 || n < r)
{
return -1;
}
if (NULL == (res = (int *)malloc(sizeof(int) * r)))
{
return -1;
}

func(n, r, res, 0);

free(res);
res = NULL;

system("pause");
return 0;
}
deliah_ann 2012-05-04
  • 打赏
  • 举报
回复
不是。老是说某个内存冲突,是只读什么的。我思路有点问题,不会用指针啊。而且好像用数组就行,我先自己改改。
早恋 2012-05-04
  • 打赏
  • 举报
回复
我这里总之iostream和cstring都找不到,不知道什么原因。但是我想你遇到的不是这个问题吧?
早恋 2012-05-04
  • 打赏
  • 举报
回复
你执行的时候显示了什么问题?

64,647

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧