"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   递归程序运行截图


    b.arrange.c

/********************************************************************************                                                                           **** --------------------------- 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   回溯程序运行截图


    网上有些版本在全排列前添加了排序,保证数组的顺序性,关于排序的部分请看客自行搜索排序的相关博文,在此不再赘述。


    代码规范:C语言编程规范-参考

0 0
原创粉丝点击