输入字符串012,正确的输出结果是:
012
021
102
120
201
210
先看一下错误的代码,错误的输出结果是:
000
001
002
010
011
012
020
021
022
100
101
102
110
111
112
120
121
122
200
201
202
210
211
212
220
221
222
你可能会笑这种很愚蠢的输出结果,哈哈哈,但是代码的思路很好理解,看懂这个代码,后面的正确的代码就是根据这个错误改进的.
#include <stdio.h>
#include <string.h>
char a[100];
int n;
char temp[100]; // 用来存放缓冲变量
void fun(int step){
if(step==n) //走到n时就要输出temp字符串
{
temp[n]='\0';
printf("%s \n",temp);
return;
}
else{
int i;
for(i=0;i<n;i++){
temp[step]=a[i]; // 把第i个字符放进去,走到n时就要输出temp字符串
fun(step+1);
}
}
}
int main() {
scanf("%s",a);
n=strlen(a); // 长度
printf("\n\n");
fun(0); //从第0个开始扔进去字符
return 0;
}
上面的思路:
先用全局变量char a[100];存储输入的字符,
然后想着for循环n次,每次往char temp[] 里面挨个扔进去a[0],a[1],a[2]
上面的错误原因是没有标记已访问导致重复, 所以再加上visited[]数组标记已访问就可以解决问题了.
根据上面的错误代码加上标记已访问就可以写出来了:
#include <stdio.h>
#include <string.h>
char a[100];
int n;
char temp[100]; // 用来存放缓冲变量
bool visited[100]={false}; //标记是否访问,默认未访问
void fun(int step){
if(step==n) //走到n时就要输出temp字符串
{
temp[n]='\0';
printf("%s \n",temp);
return;
}
else{
int i;
for(i=0;i<n;i++){
if(visited[i]==false){ // 如果第i个字符未访问,才去访问
visited[i]=true; //标记已经访问,以防重复
temp[step]=a[i]; // 把第i个字符放进去,走到n时就要输出temp字符串
fun(step+1);
// 收回标记未访问,以便下一次再把这个字符放进去
visited[i]=false;
}
}
}
}
int main() {
scanf("%s",a);
n=strlen(a);
printf("\n\n");
fun(0);
return 0;
}
思路:
先用全局变量char a[100];存储输入的字符,
然后想着for循环n次,每次往char temp[] 里面挨个扔进去a[0],a[1],a[2]…
分情况讨论:
-
第一次循环扔进去a[0],就是0, 然后递归,再来for循环3次 :
-
第一次还是要扔进去a[0],幸好a[0]标记已经访问了,已访问就跳过这次循环,否则会像上面一样输出000这种情况
-
第二次扔进去a[1], 再把a[1]标记已经访问,再去for循环3次:
- 第一次还是要扔进去a[0],幸好a[0]标记已经访问了,跳过这次循环,不然会输出010不符合
- 第二次要扔进去a[1], 幸好a[1]已经访问了,跳过这次循环,不然会输出011不符合
- 第三次要扔进去a[2], a[2]没有访问,再去递归,这时候step==n,直接输出012符合条件
-
第三次扔进去a[2],再把a[2]标记已经访问, 这时候已经是02… 再去递归for循环:
这里循环,有的已经访问跳过,只有输出021了
-
-
第二次循环扔进去a[1],就是1,标记a[1]已经访问,这时候已经是1…再去递归三次循环:
- 第一次循环扔进去a[0],这时候已经是10…再去递归只有输出102了
- 第二次循环扔进去a[1],已经访问过了
- 第三次循环扔进去a[2],这时候已经是12…再去递归只有输出120了
-
第三次循环扔进去a[2],就是2
- 第一次循环扔进去a[0],这时候已经是20…再去递归只有输出201了
- 第二次循环扔进去a[1],这时候已经是21…再去递归只有输出210了
- 第三次循环发现a[2]已经访问过了.
最后发现这个算法时间复杂度很高,是O(n^n),只能用于10个字符以下,还多占用了一个数组,但是思路简单,考试很容易写出来答案,哪怕背也能背出来.
附录:
https://blog.youkuaiyun.com/xky140610205/article/details/68961286
别人的时间复杂度为O(n!),但是输出结果是:
0 1 2
0 2 1
1 0 2
1 2 0
2 1 0
2 0 1
结果没有按照规定的顺序排列.