递归之全排列

用递归方法解决全排列问题(来自牛客网)

一、题意

  给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列。
  我们假设对于小写字母有’a’ < ‘b’ < … < ‘y’ <‘z’,而且给定的字符串中的字母已经按照从小到大的顺序排列。

二、思路

  递归的思路是把一个大的问题化解为一个一个小问题,凡是能把大的问题化解为更小问题的都可以用递归解决。
  考虑能否用递归解决问题时,不要从第一个或中间某个出发考虑问题,而要从最后一个出发看待问题,从总体看待问题开始,在具体问题时常从N开始,根据题意规则演化推理到N-1,这时,N-1与N时面临相同的问题,递归由此可行了。
  在确定使用递归时,主要有两个关键点:

  1. N与N-1的关系。类似数列递推式,不必知道N和N-1的的具体取值情况,知道N与N-1的关系式就能从一开始推到N;
  2. 递归出口。经常为N=1或N=0时,所求结果的取值,类比数列赋初值。

  在进行实际编程时,面临的问题根据所求的结果常分为两类:

  1. 所求结果为第N问题的结果,即中间某过程的结果不需要保留,如汉诺塔求移动次数问题,这样的问题往往不需要不需要模拟具体操作,自己推理出递推关系,直接编程即可。
  2. 所求结果要求保留中间每个过程的结果。这时,一般要模拟题意进行操作,记录每次迭代的结果,如全排列问题,要求记录每次迭代的字母并输出。

三、代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int b[6];//标记
int n;
char s[6];//原字符串
char res[6];//存结果
void A(int cnt)
{

 if(cnt ==n-1)//递归出口
    {
        for(int j=0;j<n;j++)
        {
            if(b[j]==0)
            {

             res[cnt]=s[j];
              printf("%s\n",res);
            }
        }

    }
 else {
        for(int j=0;j<n;j++)
        {
            if(b[j]==0)
            {
                b[j]=1;
                res[cnt]=s[j];
                A(cnt+1);//不能用cnt++或++cnt,迭代回来时会出错
                b[j]=0;
            }
        }
    }

}
int cmp(const void *a,const void *b)
{
    return *(char *)a-*(char *)b;
}
int main()
{
memset(b,0,sizeof(b));
while(scanf("%s",s)!=EOF)
{
    n=strlen(s);
    int cnt =0;//计数
    qsort(s,n,sizeof(s[0]),cmp);//排序
    if(n==1)
        printf("%s\n",s);
    for(int i=0;i<n;i++)
    { cnt =0;
        b[i]=1;
        res[cnt]=s[i];
        A(cnt+1);
        b[i]=0;

    }
    printf("\n");
    memset(s,0,sizeof(s));

}

}

四、结果

在这里插入图片描述

五、易错点

  1. printf函数要放在递归出口;
  2. 用全局变量数组迭代时没有字符串连接的麻烦;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值