您的位置:首页 > 其它

C基础抽象思想之递归演练(1)

2012-08-06 12:05 183 查看
递归思想运用很灵活,有时可以显而易见,有时却需要深入琢磨,这里我们练习一个题目,题目内容是输出n个字符的所有排列。

利用前面博客中回顾的递归知识,深入分析此题目,

我们先依次取n个字符中的一个作为第一位上的值,问题则转化为求得剩下n-1个字符的所有排列,依此类推,问题越来越简化,简化,最简单情况就是各位置上字符都被确定,排列结束。

代码示例:

/* arrangement.c ---
*
* Filename: arrangement.c
* Description: 列出长度为n的字符串的所有排列
* Author: magc
* Maintainer:
* Created: 一  8月  6 08:49:16 2012 (+0800)
* Version:
* Last-Updated: 一  8月  6 11:17:26 2012 (+0800)
*           By: magc
*     Update #: 94
* URL:
* Keywords:
* Compatibility:
*
*/

/* Commentary:
* 由递归思想来分析化解此问题
* 分解第一步:先依次从n个字符中选择1个字符,即先确定1位,然后再求得剩下n-1个字符的所有排列,可以发现重复的递归子问题,但原问题与子问题也是不尽相同。
* 针对这种原问题与递归子问题不对称时,可以通过一个函数包装器,然后再通过一个辅助函数来解决更普遍的子问题。
* 巧妙运用字符交换来实现某位置上字符值
*/

/* Change Log:
*
*
*/

/* Code: */
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
typedef char * string;

void arrange(string mystr,int p);
void swapCharactor(string mystr,int i,int k);

int main(int argc, char * argv[])
{
string str;
char s[] = "ABCD";
str = s;
arrange(str,0);
printf("\n");

}
/*************************************************************************
*功能描述:排列字符
*参数列表:mystr是指定的字符串;p是指字符串中已经确定的位数
*返回类型:
**************************************************************************/
void arrange(string mystr,int p){

int i;
int len = strlen(mystr);
if(p == len){                         //当所有位都已经确定是,当前排列结束,输出内容
printf("%s,",mystr);
}else{
for(i = p;i < len;i++){           //由已经确定位数,找出未确定字符的所有组合
swapCharactor(mystr,p,i)  ;
arrange(mystr,p + 1);
swapCharactor(mystr,i,p);//还原前面的交换结果,为了是后面继续与其它字符交换
}
}

}
/*************************************************************************
*功能描述:交换两个位置上的字符
*参数列表:
*返回类型:
**************************************************************************/
void swapCharactor(char * mystr,int i,int k){
char temp ;
temp = mystr[i];
mystr[i] = mystr[k];
mystr[k] = temp;

}

/* arrangement.c ends here */


在GCC下编译输出的结果:



注:
1)体会分析问题,找到递归子问题,遇到原问题与递归子问题不对称的时候可以借助函数包装器,再用一个辅助函数专门处理递归子问题,
2)找到递归问题的最简单情景(即作为递归出口),然后使问题朝此情景不断转化,
3) 体会这个通过字符交换的方式来实现某位置字符更换

此题目参考自《程序设计抽象思想--C语言描述》,在此对作者二十年前的作品表示敬意.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: