首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

这几行代码越看越晕,搞的小弟我头都大了,哪位大侠讲讲?多谢

2012-02-11 
这几行代码越看越晕,搞的我头都大了,哪位大侠讲讲?谢谢输入一个字符串,打印出该字符串中字符的所有排列。例

这几行代码越看越晕,搞的我头都大了,哪位大侠讲讲?谢谢
输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则输出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba

void   Permutation(char*   pStr,   char*   pBegin);

/////////////////////////////////////////////////////////////////////////
//   Get   the   permutation   of   a   string,  
//   for   example,   input   string   abc,   its   permutation   is  
//   abc   acb   bac   bca   cba   cab
/////////////////////////////////////////////////////////////////////////
void   Permutation(char*   pStr)
{
            Permutation(pStr,   pStr);
}

/////////////////////////////////////////////////////////////////////////
//   Print   the   permutation   of   a   string,  
//   Input:   pStr       -   input   string
//                 pBegin   -   points   to   the   begin   char   of   string  
//                                   which   we   want   to   permutate   in   this   recursion
/////////////////////////////////////////////////////////////////////////
void   Permutation(char*   pStr,   char*   pBegin)
{
            if(!pStr   ||   !pBegin)
                        return;

            //   if   pBegin   points   to   the   end   of   string,
            //   this   round   of   permutation   is   finished,  
            //   print   the   permuted   string
            if(*pBegin   ==   '\0 ')
            {
                        printf( "%s\n ",   pStr);
            }
            //   otherwise,   permute   string
            else
            {
                        for(char*   pCh   =   pBegin;   *pCh   !=   '\0 ';   ++   pCh)   //这段最不明白???
                        {
                                    //   swap   pCh   and   pBegin
                                    char   temp   =   *pCh;
                                    *pCh   =   *pBegin;
                                    *pBegin   =   temp;

                                    Permutation(pStr,   pBegin   +   1);//   递归   什么意思啊



                                    //   restore   pCh   and   pBegin
                                    temp   =   *pCh;
                                    *pCh   =   *pBegin;
                                    *pBegin   =   temp;
                        }
            }
}


也知道大概的意思,就是不怎么清晰

麻烦大侠赐教,多谢!!奉上最后的50分


[解决办法]
下班了,回去看,帮顶
[解决办法]
abc
acb

bac
bca

cab
cba

规律是大循环遍历所有的元素(a,b,c),在每次遍历的时候发现如果是最后两个元素则交换位置,如果不是则重复遍历和交换的过程(递归)。
[解决办法]
这是典型的回溯法。
for(char* pCh = pBegin; *pCh != '\0 '; ++ pCh) //这段最不明白???
{
// swap pCh and pBegin
char temp = *pCh;//这三句表示改变
*pCh = *pBegin;
*pBegin = temp;

Permutation(pStr, pBegin + 1);// 递归 什么意思啊---在pBegin位更改的情况下,递归将问题变成pBegin+1开始处的全部排列的过程

// restore pCh and pBegin
temp = *pCh;//这三句是回溯结束的扫尾动作,将字符串复原,为的是下一次递归
*pCh = *pBegin;
*pBegin = temp;
}
记住,1.回溯往往都要有记录本次改变,2.递归处理 3.将记录改回来
[解决办法]
for(char* pCh = pBegin; *pCh != '\0 '; ++ pCh) //这段最不明白???--pBegin也是指向pStr的,表示从pStr从pBegin一直到最后循环一道
{
// swap pCh and pBegin--随着pCh从pStr的pBegin到pStr的尾巴,pBegin这个位置排列了所有可能的字符
char temp = *pCh;
*pCh = *pBegin;
*pBegin = temp;

Permutation(pStr, pBegin + 1);// 递归 什么意思啊---对于每个pBegin的一个固定选择,再去排列pBegin+1之后的

// restore pCh and pBegin
temp = *pCh;
*pCh = *pBegin;
*pBegin = temp;
}
[解决办法]
void Union(char* src, char* tep = NULL) {

if (tep == NULL)
tep = src;

if (!*tep)
cout < <src < <endl;

for (size_t i = 0; i < strlen(tep); ++i)
{
swap(tep[i], tep[0]);
Union(src, ++tep);
--tep;
swap(tep[i], tep[0]);
}
}

int main()
{
char src[] = "abc ";

Union(src);

return 0;
}
[解决办法]
自己设计递归函数的时候,有几点需要注意的:
1、一次调用,要设法将递归的范围缩小或者与递归的目标接近。
2、一次调用,缩小范围或者接近目标之后,必须处于与起始状态相似的条件下,这是为了下一次递归。
3、找到一个递归终结的条件。

下面根据这三点来分析一下void Permutation(char* pStr, char* pBegin)这个递归函数的目的:
1、可以看出Permutation函数的目的为了将从pBegin这个地址开始到 '\0 '结束的字符串进行排列,而参数pStr在递归中根本没有用到,仅仅是为了最终打印结果而已。
所以得到结论,Permutation函数的目的是为了对pBegin起始的字符串进行排列。
2、从那个for循环可以看出,pBegin的第一个字符与其他所有字符都交换了一遍,并且每次交换以后都会继续调用Permutation。因为第一个字符被选择了,那么只剩后面的字符需要排列,这样就缩小了范围,符合注意1。缩小范围之后,又刚好与原先的状况相同,所以符合注意2。


3、至于注意3这条,当然是到 '\0 '结束了(这也是废话)。
4、在这个问题中,因为Permutation的目的仅仅是将第一个字符与其他字符交换来达到遍历的目的,后面的字符排列应该是要交给下一层的Permutation处理的,所以在调用完下一层Permutation的时候,务必将原先交换的字符交换回来,否则与设计Permutation这个函数的初衷就不同了。

另外附加一句,没测试过,不过似乎不交换回来也可以遍历的样子,不过对于设计这个函数的人来说,交换回来思路确实清晰很多。如果让我来写,就算交换回来是多余的,也要画蛇添足一下。

热点排行