C语言打印一窜数字的所有组合
有一窜数字1233456778.按要求打印组合。1:打印所有组合,不能有重复,且数字组合中不能有重复出现的数字。2:打印所有组合,不能有重复,但数字组合中可以有重复出现的...
有一窜数字1233456778.按要求打印组合。
1:打印所有组合,不能有重复,且数字组合中不能有重复出现的数字。
2:打印所有组合,不能有重复,但数字组合中可以有重复出现的数字(即一种组合中,3与7最多可以同时出现2个。但其余数字不能有重复)。
3:打印所有组合,不能有重复,但数字组合中可以有重复出现的数字(即一种组合中,3与7最多可以同时出现2个。但其余数字不能有重复)。且地三位不能是3,第七位不能是7。
只要可以帮我解答到问题的都有分,全部问题都解答完的,我把我全部分都给你。 展开
1:打印所有组合,不能有重复,且数字组合中不能有重复出现的数字。
2:打印所有组合,不能有重复,但数字组合中可以有重复出现的数字(即一种组合中,3与7最多可以同时出现2个。但其余数字不能有重复)。
3:打印所有组合,不能有重复,但数字组合中可以有重复出现的数字(即一种组合中,3与7最多可以同时出现2个。但其余数字不能有重复)。且地三位不能是3,第七位不能是7。
只要可以帮我解答到问题的都有分,全部问题都解答完的,我把我全部分都给你。 展开
1个回答
展开全部
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);//排列输出
}
数字用上的全排列,就是没有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);//排列输出
}
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询