字符串的排列 【微软面试100题 第五十三题】

题目要求:

  输入一个字符串,打印出该字符串中字符的所有排列。

  例如输入字符串abc,则输出字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab、cba。

  参考资料:剑指offer第28题。

题目分析:

  1. 输出的字符串必须包含原字符串的所有字符,只是字符顺序换了;

  2. 考虑有字符重复的情况;

  3. 思路是:

    1) 分别把第一个字符和后面的字符交换;

    2) 固定第一个字符,求后面字符的排列;

    3) 把第二个字符和后面的字符交换,然后固定.......

代码实现:

#include <iostream>



using namespace std;



void PrintAllPermutation(char *pStr);



int main(void)

{

    char pStr[] = "aaab";

    PrintAllPermutation(pStr);

    return 0;

}

void PrintAllPermutation(char *pStr,char *pStart)

{

    int flag = 0;

    if(*pStart=='\0')

        cout << pStr << endl;

    else

    {

        for(char *pCh = pStart;*pCh != '\0';++pCh)

        {

            //有重复的就不交换,也不递归

            for(char *p = pStart;p!=pCh;++p)

            {

                if(*p == *pCh)

                {

                    flag = 1;

                    break;

                }

            }

            if(flag)

            {

                flag = 0;

                continue;

            }

            char tmp = *pCh;

            *pCh = *pStart;

            *pStart = tmp;



            PrintAllPermutation(pStr,pStart+1);



            tmp = *pCh;

            *pCh = *pStart;

            *pStart = tmp;

        }

    }

}

void PrintAllPermutation(char *pStr)

{

    if(pStr==NULL)

        return;

    PrintAllPermutation(pStr,pStr);

}

扩展问题:

  若是输出所有组合,又怎么求?

  如输入abc,则所有组合为:a、b、c、ab、ac、bc、abc

问题分析:

  1. 如果有相同字符,怎么办?可以把先输出的组合存储起来,当新的字符需要输出的时候与存储比较,如果有相同的就不输出

  2. 可以用位运算来求:如果输入为3个字符,则位运算方法就为3位二进制(1~7),一次遍历1~7这七个数,输出数中为1对应的字符即可;

代码实现:

 

#include <iostream>

#include <string>

#include <set>

using namespace std;



set<string> store;



void SubSet(char *pStr);



int main(void)

{

    char pStr[] = "aaabc";

    SubSet(pStr);

    return 0;

}

void Print(char *pStr,int n,int data)

{

    char *p = new char[n];

    int j = 0;

    for(int i = 0;i<n;i++)

    {

        if(data&(1<<i))

            p[j++] = pStr[i];

    }

    p[j] = '\0';



    if(store.find(p) == store.end())

    {

        store.insert(p);

        cout << p << endl;

    }

    

    delete []p;

}

void SubSet(char *pStr)

{

    if(pStr==NULL)

        return;

    int len = strlen(pStr);

    for(int i = 1;i<(1<<len);i++)

    {

        Print(pStr,len,i);

    }

}

 

 

 

  

你可能感兴趣的:(字符串)