C语言 全排列······晕

作者&投稿:茅谦 (若有异议请与网页底部的电邮联系)
c语言全排列(给个简单点的程序,网上的我简直看晕了)~


//以下为代码文件,思路就是交换数字,递归
  #include
  int n = 1;
  int ans[1000];
  void swap(int *a, int *b)
  {
  int m;
  m = *a;
  *a = *b;
  *b = m;
  }
  void perm(int list[], int k, int m)
  {
  int i,tmp=0;
  if(k > m)
  {
  for(i = 0; i <= m; i++)
  {
  tmp=tmp*10+list[i];
  
  }
  ans[n]=tmp;
  n++;
  }
  else
  {
  for(i = k; i <= m; i++)
  {
  swap(&list[k], &list[i]);
  perm(list, k + 1, m);
  }
  }
  }
  int main()
  {
  int list[] = {1, 2, 3};
  int i;
  perm(list, 0, 2);
  for(i=1;i<n;i++)printf("%d
",ans[i]);
  return 0;
  }

给,已经编译运行确认:
#include
#include
char a[20];
int lenth;
long count=0;
void main()
{void move(int,int);
int i,j=0;
printf("input:");gets(a);
lenth=strlen(a);
for(i=0;i<lenth;i++)
move(j,i);//move a[i] to the front of a[j];
printf("
total=%d
",count);
}
void move(int here,int which)//move a[which] to the front of a[here];
{char b[20];
char temp;
int m,n;
if(here<lenth-1)
{if(here!=which)
{for(m=0;m<lenth;m++)
b[m]=a[m];
temp=a[which];
for(m=which;m>here;m--)
a[m]=a[m-1];
a[m]=temp;
}
for(n=here+1;n<lenth;n++)
move(here+1,n);
if(here!=which)
for(m=0;m<lenth;m++)
a[m]=b[m];
}
else
{printf("%-10s",a);
count++;}
}

首先,我下面的叙述是建立在楼主明白什么是递归调用的基础上的。对递归毫无了解的话,请先看看百度百科。
然后,进入正题。

第一个return:就是返回这个函数的调用者,这个函数执行完毕。这是一个if判断,当带排列的数列长度为1时,只有一种可能,输出,则排列结束,返回。长度不只1的时候,执行以下for。

未完待续

接着讲这个
for(i=0;i<n;i++){----------这个循环到底怎么个看法和顺序?
anagram(d,n-1); 怎么输出的??(这块都不明白)
temp=d[0];
for(j=1;j<=n-1;j++){
d[j-1]=d[j];

}
d[n-1]=temp;

}

先讲这个算法的思想,比如对abc进行全排列,那么可以看做:ab的全排列+c和ac的全排列+b和bc的全排列+a三个的组合。然后再细化,ab的全排列可以看出a的全排列+b,和b的全排列+a两个的组合。当只有一个时,就是调用if=1的那个情况,直接print。不是1的时候,就是递归调用,进行不断地分解。

这是算法思想,未完待续

两个for循环,里面的for执行一边后就是把数组的元素挨个往前挪一位,第一位到最后位,然后对前n-1位进行全排列,递归进行。从上面的算法思想中我们可以看出这样的目的和意义,就是一个类似对上面abc的分解过程,一次a到最后排bc,一次b到最后排ac,一次c到最后排ab。

就先说这么多吧。纯手打,望采纳!有问题可以补充,或者百度hi我。

我帮你改了一下代码,加了几行printf,希望可以解决你的那几个问题:

#include<stdio.h>
#define NUM 3
void anagram(int[],int);
void print(int[]);
void main()
{
int d[NUM];
int i;
for(i=0;i<NUM;i++)
d[i]=i + 1;
printf("初始化后的数组顺序是:");
print(d);

anagram(d,NUM);
}
void anagram(int d[],int n)
{
int i,j,temp;
int p;
if(n==1){
print(d); //打印函数
return;//-------------return返回哪?
} // 和下面的for怎么联系起来?

for(i=0;i<n;i++){//----------这个循环到底怎么个看法和顺序?
printf("\ni = %d,n = %d, 准备调用aragram(d,%d)\n",i,n,n-1);
printf("这时候的数组顺序是:");
print(d);
anagram(d,n-1); // 怎么输出的??(这块都不明白)
temp=d[0];
for(j=1;j<=n-1;j++){
d[j-1]=d[j];

}
d[n-1]=temp;

}
}
void print(int d[]){
int i;

for(i=0;i<NUM;i++){
printf("%d",d[i]);
}

printf("\n");

}

PS:
改动:1、print函数原来是逆序输出,改成正序输出,有利于理解;2、数组原来初始化为321,改为123,有利于理解。就改了这两个地方,加了一些printf。

你可以运行一下。

输出结果:
初始化后的数组顺序是:123

i = 0,n = 3, 准备调用aragram(d,2)
这时候的数组顺序是:123

i = 0,n = 2, 准备调用aragram(d,1)
这时候的数组顺序是:123
123

i = 1,n = 2, 准备调用aragram(d,1)
这时候的数组顺序是:213
213

i = 1,n = 3, 准备调用aragram(d,2)
这时候的数组顺序是:231

i = 0,n = 2, 准备调用aragram(d,1)
这时候的数组顺序是:231
231

i = 1,n = 2, 准备调用aragram(d,1)
这时候的数组顺序是:321
321

i = 2,n = 3, 准备调用aragram(d,2)
这时候的数组顺序是:312

i = 0,n = 2, 准备调用aragram(d,1)
这时候的数组顺序是:312
312

i = 1,n = 2, 准备调用aragram(d,1)
这时候的数组顺序是:132
132
请按任意键继续. . .

首先,我下面的叙述是建立在楼主明白什么是递归调用的基础上的。对递归毫无了解的话,请先看看百度百科。
然后,进入正题。
第一个return:就是返回这个函数的调用者,这个函数执行完毕。这是一个if判断,当带排列的数列长度为1时,只有一种可能,输出,则排列结束,返回。长度不只1的时候,执行以下for。
未完待续
接着讲这个
for(i=0;i<n;i++){----------这个循环到底怎么个看法和顺序?
anagram(d,n-1);
怎么输出的??(这块都不明白)
temp=d[0];
for(j=1;j<=n-1;j++){
d[j-1]=d[j];
}
d[n-1]=temp;
}
先讲这个算法的思想,比如对abc进行全排列,那么可以看做:ab的全排列+c和ac的全排列+b和bc的全排列+a三个的组合。然后再细化,ab的全排列可以看出a的全排列+b,和b的全排列+a两个的组合。当只有一个时,就是调用if=1的那个情况,直接print。不是1的时候,就是递归调用,进行不断地分解。
这是算法思想,未完待续
两个for循环,里面的for执行一边后就是把数组的元素挨个往前挪一位,第一位到最后位,然后对前n-1位进行全排列,递归进行。从上面的算法思想中我们可以看出这样的目的和意义,就是一个类似对上面abc的分解过程,一次a到最后排bc,一次b到最后排ac,一次c到最后排ab。
就先说这么多吧。纯手打,望采纳!有问题可以补充,或者百度hi我。
我帮你改了一下代码,加了几行printf,希望可以解决你的那几个问题:
#include<stdio.h>
#define
NUM
3
void
anagram(int[],int);
void
print(int[]);
void
main()
{
int
d[NUM];
int
i;
for(i=0;i<NUM;i++)
d[i]=i
+
1;
printf("初始化后的数组顺序是:");
print(d);
anagram(d,NUM);
}
void
anagram(int
d[],int
n)
{
int
i,j,temp;
int
p;
if(n==1){
print(d);
//打印函数
return;//-------------return返回哪?
}
//
和下面的for怎么联系起来?
for(i=0;i<n;i++){//----------这个循环到底怎么个看法和顺序?
printf("\ni
=
%d,n
=
%d,
准备调用aragram(d,%d)\n",i,n,n-1);
printf("这时候的数组顺序是:");
print(d);
anagram(d,n-1);
//
怎么输出的??(这块都不明白)
temp=d[0];
for(j=1;j<=n-1;j++){
d[j-1]=d[j];
}
d[n-1]=temp;
}
}
void
print(int
d[]){
int
i;
for(i=0;i<NUM;i++){
printf("%d",d[i]);
}
printf("\n");
}
PS:
改动:1、print函数原来是逆序输出,改成正序输出,有利于理解;2、数组原来初始化为321,改为123,有利于理解。就改了这两个地方,加了一些printf。
你可以运行一下。
输出结果:
初始化后的数组顺序是:123
i
=
0,n
=
3,
准备调用aragram(d,2)
这时候的数组顺序是:123
i
=
0,n
=
2,
准备调用aragram(d,1)
这时候的数组顺序是:123
123
i
=
1,n
=
2,
准备调用aragram(d,1)
这时候的数组顺序是:213
213
i
=
1,n
=
3,
准备调用aragram(d,2)
这时候的数组顺序是:231
i
=
0,n
=
2,
准备调用aragram(d,1)
这时候的数组顺序是:231
231
i
=
1,n
=
2,
准备调用aragram(d,1)
这时候的数组顺序是:321
321
i
=
2,n
=
3,
准备调用aragram(d,2)
这时候的数组顺序是:312
i
=
0,n
=
2,
准备调用aragram(d,1)
这时候的数组顺序是:312
312
i
=
1,n
=
2,
准备调用aragram(d,1)
这时候的数组顺序是:132
132
请按任意键继续.
.
.

本人比较懒:你提的4点我下面就用1-4代替了:
return是返回进入函数前(即跳出本次调用函数),程序所运行到的位置,然后接着执行下面的语句
函数第一次进入anagram 时 记作

anagram----0
此时,传入的参数n=NUM=3
if条件不满足,进入 3 中的for循环
此时,第二次调用anagram ,但第一次的anagram 还未运行完

anagram----1
n=n-1=2
if条件不满足,还是进入 3 中的for循环(i=0)
此时,第三次调用anagram ,同理第二次的anagram 也未运行完

anagram----2
if条件满足,print d数组=(321)
由于print是逆序输出
所以,结果为 123
然后,return 返回 anagram----1 中的 4 后面的 temp=d[0]接着执行
第三次调用没有运行后面的 for 循环语句
即:将d数组中的元素循环左移一次,变成(231)

进入 anagram----1 中的第二次 for 循环(i=1)
anagram----3
再输出一次数组的元素 132
同理 后面的我就不写里

总结一下:
anagram----0 中要运行3次 anagram----1
而anagram----1 又2次调用了 anagram()函数
所以,一共输出6次

这是函数的递归调用。return用于向上层层层反回。如果还不明白请仔细看函数的递归调用一节,我用手机不方便

去看看递归方面的资料吧..


那曲县19521787337: C语言 全排列······晕 -
粱政畅诺: 首先,我下面的叙述是建立在楼主明白什么是递归调用的基础上的.对递归毫无了解的话,请先看看百度百科.然后,进入正题.第一个return:就是返回这个函数的调用者,这个函数执行完毕.这是一个if判断,当带排列的数列长度为1时,只...

那曲县19521787337: 一个C语言全排列的算法. 比如,输入3,则将123的全排列全部输出:123,132,213,231 -
粱政畅诺: #include main() { int a1,a2,a3,a4,a5,a6,a7,a8,a9,n,t=0; scanf("%d",&n); for(a1=1;a1<=n;a1++) if(n==1){printf("%d\n",a1);t=t+1;}else for (a2=1;a2<=n;a2++)if(a2!=a1) {if(n==2) {printf("%d%d\n",a1,a2);t=t+1;} else for (a3=1;a3<=n;a3++)if(...

那曲县19521787337: c语言 给出一个数怎样输出该数的全排列 -
粱政畅诺: 递归法:设输入的数为n,N={1,2,...n} 不断选择数字i,把i从N中剔除,直到N为空集即可 代码如下:#include <stdio.h>#include <stdlib.h>#include <string.h> int N; bool *mark; int *output, pos = 0; void AddNumber(int i) {bool finish = true; mark[i] = ...

那曲县19521787337: 急!!!如何用C语言编写打出1~n个数的全排. -
粱政畅诺: 递归,比较简单,10个数全排如下#include<stdio.h> void swap(int k,int i,int a[]) { int t; t=a[k]; a[k]=a[i]; a[i]=t; } void pailie(int a[],int i,int n) {int k,t; if(i==n) { for(t=0;t<n;t++) printf("%3d",a[t]); printf("\n"); } elsefor(k=i;k<n;k++) { swap(i,k,a); pailie(a...

那曲县19521787337: 用c语言实现 ABCDE按照全排列输出所有结果 -
粱政畅诺: #include <stdio.h> #include <stdlib.h> void main() {char i,j,k,m,n;for(i='A';i<='E';i++)for(j='A';j<='E';j++)for(k='A';k<='E';k++)for(m='A';m<='E';m++)for(n='A';n<='E';n++)if(i!=j&&i!=k&&i!=m&&i!=n&&j!=k&&j!=m&&j!=n&&k!=m&&k!=n&&m!=n)...

那曲县19521787337: 用c语言编写全部排列 -
粱政畅诺: void chang(char str[],int m) /*定义循环左移函数(我没有用左移函数)*/{int i,j;char temp=str[0];for (i=0;i<m;i++) str[i]=str[i+1];str[i]=temp;} void pai(char str[],int m,int n) /*定义全排列函数*/ {int k;void chang(char str[],int m);if (m<n) /* 定 义 递 ...

那曲县19521787337: 全排列用C语言实现 -
粱政畅诺: 给,已经编译运行确认: #include<stdio.h> #include<string.h> char a[20]; int lenth; long count=0; void main() {void move(int,int); int i,j=0; printf("input:");gets(a); lenth=strlen(a); for(i=0;i<lenth;i++) move(j,i);//move a[i] to the front of a[j]; printf("\...

那曲县19521787337: 用C语言编程求1、2、3到n的全排列 -
粱政畅诺: #include <stdio.h> int main() { int n, nn; printf("input a number: "); scanf("%d", &n); for (int i = 1; i <= n; ++i) { nn = 1; for (int j = 1; j <= i; ++j) { nn = nn * j; } printf("%d! = %d\n", --j, nn); } return 0; }

那曲县19521787337: c语言中全排列问题 -
粱政畅诺: //输入一个数输出这个数所有的排列,递归做法#include<stdio.h> int a[100]; int n; void output() { int i; for(i=1;i<=n;i++) printf("%3d",a[i]); printf("\n"); } void Swap(int &a,int &b) //注意取地址 { int t; t=a; a=b; b=t; } void pailie(int t) { int i; if(t==n) //输...

那曲县19521787337: c语言全排列 -
粱政畅诺: 基本思想是用回溯法来搜索每一种排列 不过楼主对问题的说明不是很详细,所以我只好写个普适性比较大的了 下面这个程序读取一行字符串,然后对该字符串中的所有字符进行全排列输出 注:输入的字符串不要太长,因为不存在能够在短时间...

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网