"abc" full arrange - III
来源:互联网 发布:java cookie 编辑:程序博客网 时间:2024/04/27 23:42
前两篇的算法仅在数组无重复元素时成立,在出现重复元素如 “abb”、 “aabc” 这样的输入下均会产生错误的结果。例如“abb” 会产生“abb”、 “abb”、 “bab”、 “bba”、 “bab”、 “bba” 六种结果,其中3个为重复结果。
错误的原因在于程序没能识别相同元素的存在,即对ab(1)b(2)进行全排列时,对ab(2)b(1)又进行了一次全排列,对b(1)**和b(2)**也进行了重复排列。因此在排列时将重复的元素仅取一个,其他采取跳过的方式,便可轻松解决这个问题。
递归和回溯的代码如r.arrange.c和b.arrange.c所示。
r.arrange.c
/******************************************************************************** **** --------------------------- file information ---------------------------- **** @file : r.arrange.c **** @created : Flee Elf - QQ 892737105 **** @date_crt : 2015/08/21 **** @modified : Flee Elf **** @date_mod : 2015/08/24 **** @version : v1.0.2 **** @brief : "abc" full arrange in recursion **** ------------------------------------------------------------------------- **** ********************************************************************************/#include <stdio.h>#include <string.h>#include <stdlib.h>#include "r.arrange.h"/******************************************************************************** **** Inside Variable Definition **** ********************************************************************************/static char *str; /* point to a copy of src-string 'p' */static int len; /* count of char of 'p' without '\0' *//******************************************************************************** **** Function Definition **** ********************************************************************************//******************************************************************************** **** Note: **** > if there is a mid-result list below **** aabcccd & index = 0 **** then **** 0 123456 **** a abcccd _r_arrange(1) **** b aacccd _r_arrange(1) **** c aabccd _r_arrange(1) **** d aabccc _r_arrange(1) **** **** > if there is a mid-result list below **** cbaaccd & index = 2 **** then **** 01 2 3456 **** cb a accd _r_arrange(3) **** cb c aacd _r_arrange(3) **** cb d aacc _r_arrange(3) **** **** > if there is a mid-result list below **** cbadacc & index = 4 **** then **** 0123 4 56 **** cbad a cc _r_arrange(5) **** cbad c ac _r_arrange(5) **** ********************************************************************************//** @Function : _r_arrange ** @created : Flee Elf ** @brief_crt: get full arrange by use index to recur ** @modified : Flee Elf ** @brief_mod: the same iterm will be jumped in recursion ** "aabccc" will get right answer ** @param : index - current child-string-head's index number, start with 0 ** @retval : None **/static void _r_arrange(int index){ int index_last = len - 1; int index_next = index + 1; int i; char tmp; if (index == index_last) /* one char one arrange, show result */ { puts(str); return ; } _r_arrange(index_next); /* 1st char child-string arrange */ for (i = index_next; i <= index_last; i++) { if (str[i] == str[index])/* jump the same iterm */ { continue; } tmp = str[i]; str[i] = str[index]; str[index] = tmp; _r_arrange(index_next); /* 2nd arrange ===> last arrange */ } tmp = str[index]; for (i = index; i < index_last; i++) { str[i] = str[i + 1]; } str[index_last] = tmp; /* recover string data after recur */}/******************************************************************************** **** Interface Definition **** ********************************************************************************//** @Interface: r_arrange ** @created : Flee Elf ** @brief_crt: show full arrange of string 'p' in resursion ** @modified : ** @brief_mod: ** @param : p - point to a string & been sorted ** @retval : None **/void r_arrange(char *p){ if ((len = strlen(p)) == 0) { fprintf(stderr, "char string length is 0 !\n"); return ; } if ((str = malloc(sizeof(char) * (len + 1))) == NULL) { fprintf(stderr, "malloc fault !\n"); return ; } strcpy(str, p); // we sure that str is big enough _r_arrange(0); free(str);}
图1 递归程序运行截图
/******************************************************************************** **** --------------------------- file information ---------------------------- **** @file : b.arrange.c **** @created : Flee Elf - QQ 892737105 **** @date_crt : 2015/08/24 **** @modified : Flee Elf **** @date_mod : 2015/08/25 **** @version : v1.1.2 **** @brief : "abc" full arrange in backtracking **** ------------------------------------------------------------------------- **** ********************************************************************************/#include <stdio.h>#include <string.h>#include <stdlib.h>#include "b.arrange.h"/******************************************************************************** **** Inside Variable Definition **** ********************************************************************************/static char *str; /* point to a copy of src-string 'p' */static int len; /* count of char of 'p' without '\0' */static int *b_i; /* index of each backtracking *//******************************************************************************** **** Function Definition **** ********************************************************************************//******************************************************************************** **** Note: **** > there is a example below shows the process in _b_arrange **** str = "abb" = {'a', 'b', 'b', '\0'}; **** b_i = { 0 , x , x }; **** len = 3; **** **** index_last = 2; **** **** --------------------------------------------------------------- **** **** |index|mode| i | str | b_i | **** **** | start | **** | 0 | f | x | a b b | 0 x x | **** +-----+----+---+-------+---------+ **** | 1 | f | 0 | a b b | 1 1 x | **** | 2 | f | 1 | a b b | 1 -1 2 | **** | 2 | b | 1 | a b b | 1 -1 2 | puts abb **** | 1 | b | 1 | a b b | 1 -1 2 | **** | 0 | f | 1 | a b b | 1 -1 2 | **** +-----+----+---+-------+---------+ **** | 1 | f | 1 | b a b |-1 1 2 | **** | 2 | f | 1 | b a b |-1 2 2 | **** | 2 | b | 1 | b a b |-1 2 2 | puts bab **** | 1 | f | 1 | b a b |-1 2 2 | **** +-----+----+---+-------+---------+ **** | 2 | f | 2 | b b a |-1 -1 2 | **** | 2 | b | 2 | b b a |-1 -1 2 | puts bba **** | 1 | b | 2 | b b a |-1 -1 2 | **** +-----+----+---+-------+---------+ **** | 0 | b | 2 | b a b |-1 -1 2 | **** | end | **** **** --------------------------------------------------------------- **** ********************************************************************************//** @Function : _b_arrange ** @created : Flee Elf ** @brief_crt: get full arrange in backtracking ** @modified : Flee Elf ** @brief_mod: the same iterm will be jumped in backtracking ** "abb" will get right answer ** @param : None ** @retval : None **/static void _b_arrange(void){ int index_last = len - 1; int index = 0; /* current child-string-head's index */ int i; int s; char mode = 'f'; /* 'f' front 'b' back */ char tmp; while (1) { switch (mode) { case 'f': /* like call function in recursion */ if (index == index_last) /* one char one arrange, show result */ { puts(str); mode = 'b'; break; } /* get current arrange index & update to next arrange index */ i = b_i[index]; b_i[index] = -1; for (s = i + 1; s <= index_last; s++) { if (str[s] != str[i]) /* jump the same iterms */ { b_i[index] = s; break; } } tmp = str[i]; /* set child-string ready */ str[i] = str[index]; str[index] = tmp; index++; /* go next */ b_i[index] = index; /* set child-string entrance */ break; case 'b': /* like return or } in recursion */ if (index == 0) /* current child-str-head's index = 0*/ { return ; /* next backtracking is -1 means end */ } tmp = str[index]; /* recover child-string in sorted */ for (i = index; i < index_last; i++) { str[i] = str[i + 1]; } str[index_last] = tmp; /* get back index & judge mode 'f' or 'b' */ mode = (b_i[--index] == -1) ? 'b' : 'f'; break; default : fprintf(stderr, "backtracking unknown error !\n"); return; } }}/******************************************************************************** **** Interface Definition **** ********************************************************************************//** @Interface: b_arrange ** @created : Flee Elf ** @brief_crt: show full arrange of string 'p' in backtracking ** @modified : ** @brief_mod: ** @param : p - point to a string & been sorted ** @retval : None **/void b_arrange(char *p){ int i; if ((len = strlen(p)) == 0) { fprintf(stderr, "char string length is 0 !\n"); return ; } if ((str = malloc(sizeof(char) * (len + 1))) == NULL) { fprintf(stderr, "malloc string fault !\n"); return ; } if ((b_i = malloc(sizeof(int) * len)) == NULL) { fprintf(stderr, "malloc index array fault !\n"); free(str); /* it's necessary */ return ; } strcpy(str, p); /* we sure that str is big enough */ b_i[0] = 0; /* initialise entrance */ _b_arrange(); free(str); free(b_i);}
图2 回溯程序运行截图
网上有些版本在全排列前添加了排序,保证数组的顺序性,关于排序的部分请看客自行搜索排序的相关博文,在此不再赘述。
0 0
- "abc" full arrange - III
- "abc" full arrange - I
- "abc" full arrange - II
- Arrange
- abc
- abc
- abc
- abc
- abc
- abc
- abc
- abc
- abc
- abc
- abc
- abc
- ABC
- ABC
- 软件版本号规范说明
- 陈焕生:深入理解Oracle 的并行执行
- [poj3984]
- Android修改init.rc和init.xx.rc文件
- java 自带的MD5、SHA1算法演示
- "abc" full arrange - III
- UVALive 6655 Two Points Revisited
- Objective-C 苹果开发文档 09 Dealing with Errors
- Qt入门学习——Qt快速入门(vim纯代码编写)
- 微信JS SDK Demo
- IOS学习之OC面向对象—多态
- 从0到100——知乎架构变迁史
- 一个池塘里漂浮着一只装有石块的木船,当把石块扔到池塘后,石块下沉,问池塘中的水面高度将如何变化?
- Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解