Chinaunix首页 | 论坛 | 博客
  • 博客访问: 988893
  • 博文数量: 150
  • 博客积分: 3017
  • 博客等级: 少校
  • 技术积分: 3829
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-19 14:40
个人简介

Now in Baidu WISE team

文章分类

全部博文(150)

文章存档

2014年(8)

2013年(31)

2012年(111)

分类: C/C++

2012-12-20 00:13:21

给定一个无重复字符串字符串,程序输出该字符串的所有排列。
回溯算法。
codepad.org已验证
 
Dec 21th 2012 update
根据socay2 提醒 增加30 31行free释放内存,更改标题
 
Jan 2rd 2013 update
1.代码中其实无需使用malloc,这样就减少了free的负担,直接在栈上开辟空间然后memcopy即可。
2.对于含重复字符的解法,查找到了基于交换元素的回溯解决方案,具体分析和代码参见
3.根据2的解法,对本文给出的基于选择的回溯法进行了改进,以处理重复字符串,同时精简了代码。代码见第二部分。
//无重复字符

点击(此处)折叠或打开

  1. #include <memory.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. void append(char *src, char app){
  6.     if(src == NULL) return;
  7.     char* start = src;
  8.     while(*start)start++;
  9.     *start = app;
  10.     start++;
  11.     *start = '\0';
  12. }
  13. void allCombine(const char* word, int len, char* set){

  14.     if(word == NULL) return;
  15.     if(strlen(set) == len){
  16.         printf("%s \n", set);
  17.         return;
  18.     }
  19.     int i = 0;
  20.     for(;i<len;i++){
  21.         if(word[i]){
  22.             char* afterselect = (char*)malloc(sizeof(char)*(len+1));
  23.             memcpy(afterselect,word,len);
  24.             afterselect[i]= '\0';
  25.             char *newset = (char*)malloc(sizeof(char)*(len+1));
  26.             memcpy(newset, set,len);
  27.             append(newset, word[i]);
  28.             allCombine(afterselect,len,newset);
  29.             free(newset);
  30.             free(afterselect);
  31.         }
  32.     }

  33. }

  34. int main(){
  35.     
  36.     char *word = "abcde";
  37.         char set[strlen(word)+1];
  38.         set[0] = '\0';
  39.     allCombine(word, strlen(word),set);
  40.     return 0;
  41. }

//有重复字符

点击(此处)折叠或打开

  1. #include <memory.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>

  5. void allCombine(char* word, int len, char* set){
  6.     if(word == NULL) return;
  7.     if(strlen(set) == len){
  8.         printf("%s \n", set);
  9.         return;
  10.     }
  11.     char record[256] = {0};
  12.     int i = 0;
  13.     for(;i<len;i++){
  14.         if(word[i] && record[word[i]]!= 1 ){
  15.             record[word[i]] = 1;
  16.             int tlen = strlen(set);
  17.             set[strlen(set)] = word[i];
  18.                         set[tlen+1] = '\0';
  19.             char tmp = word[i];
  20.             word[i] = '\0';
  21.             allCombine(word,len,set);
  22.             word[i] = tmp;
  23.             set[tlen] = '\0';
  24.         }
  25.     }
  26. }

  27. int main(){
  28.     char word[] = "aab";
  29.     char set[strlen(word)+1];
  30.         set[0] = '\0';
  31.     allCombine(word, strlen(word),set);
  32.     printf("%s \n", set);
  33.     return 0;

  34. }
阅读(2049) | 评论(3) | 转发(1) |
给主人留下些什么吧!~~

runningdark2013-01-08 16:09:35

socay2: 博主,你的程序存在问题。
比如: str = "aaaaa";
其实结果就一种,但是你还是有 5*4*3*2*1 = 120 种

还有一个问题,程序存在严重的内存泄露.....
已经增加了处理重复字符的代码。 :)

runningdark2012-12-21 17:28:53

socay2: 博主,你的程序存在问题。
比如: str = "aaaaa";
其实结果就一种,但是你还是有 5*4*3*2*1 = 120 种

还有一个问题,程序存在严重的内存泄露.....
原题是没有重复char的,我还没想到有啥简便的方式处理。另外内存泄露确实没注意哈,谢谢提醒,我收拾收拾。

socay22012-12-21 13:30:48

博主,你的程序存在问题。
比如: str = "aaaaa";
其实结果就一种,但是你还是有 5*4*3*2*1 = 120 种

还有一个问题,程序存在严重的内存泄露问题!