递归练习(一)

全排列在笔试面试中很热门,因为它难度适中,既可以考察递归实现,又能进一步考察非递归的实现,便于区分出考生的水平。所以在百度和迅雷的校园招聘以及程序员和软件设计师的考试中都考到了,因此本文对全排列作下总结帮助大家更好的学习和理解。对本文有任何补充之处,欢迎大家指出。
首先来看看题目是如何要求的(百度迅雷校招笔试题)。
一、字符串的排列
用C++写一个函数, 如 Foo(const char *str), 打印出 str 的全排列,
如 abc 的全排列: abc, acb, bca, dac, cab, cba

一、全排列的递归实现

为方便起见,用123来示例下。123的全排列有123、132、213、231、312、321这六种。首先考虑213和321这二个数是如何得出的。显然这二个都是123中的1与后面两数交换得到的。然后可以将123的第二个数和每三个数交换得到132。同理可以根据213和321来得231和312。因此可以知道——全排列就是从第一个数字起每个数分别与它后面的数字交换。找到这个规律后,递归的代码就很容易写出来了:

#include<iostream>  
using namespace std;  
#include<assert.h>  
  
void Permutation(char* pStr, char* pBegin)  
{  
    assert(pStr && pBegin);  
  
    if(*pBegin == '\0')  
        printf("%s\n",pStr);  
    else  
    {  
        for(char* pCh = pBegin; *pCh != '\0'; pCh++)  
        {  
            swap(*pBegin,*pCh);  
            Permutation(pStr, pBegin+1);  
            swap(*pBegin,*pCh);  
        }  
    }  
}  
  
int main(void)  
{  
    char str[] = "abc";  
    Permutation(str,str);  
    return 0;  
} 

另外一种写法:

//k表示当前选取到第几个数,m表示共有多少个数  
void Permutation(char* pStr,int k,int m)  
{  
    assert(pStr);  
  
    if(k == m)  
    {  
        static int num = 1;  //局部静态变量,用来统计全排列的个数  
        printf("第%d个排列\t%s\n",num++,pStr);  
    }  
    else  
    {  
        for(int i = k; i <= m; i++)  
        {  
            swap(*(pStr+k),*(pStr+i));  
            Permutation(pStr, k + 1 , m);  
            swap(*(pStr+k),*(pStr+i));  
        }  
    }  
}  
  
int main(void)  
{  
    char str[] = "abc";  
    Permutation(str , 0 , strlen(str)-1);  
    return 0;  
} 
如果字符串中有重复字符的话,上面的那个方法肯定不会符合要求的,因此现在要想办法来去掉重复的数列。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值