zoukankan      html  css  js  c++  java
  • 字符串的排列 【微软面试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=='')
            cout << pStr << endl;
        else
        {
            for(char *pCh = pStart;*pCh != '';++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] = '';
    
        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);
        }
    }

      

  • 相关阅读:
    Windows系统安装mysql5.7*时mysql服务启动失败的解决方法
    安装MySQL出现 This application requires Visual Studio 2013 x64 Redistributable.Please install the Redistributable then run this installer again
    Fiddler抓包流程
    C#使用NPOI根据模板生成Word文件功能实现
    .NET nhibernate 添加新的表运行报is not mapped的问题
    二进制原码、反码、补码和位运算
    【英语】面试常用语整理
    【检测分割算法整理】
    【Leetcode方法比较】DP/滑窗/前缀和
    【Leetcode】数学系列
  • 原文地址:https://www.cnblogs.com/tractorman/p/4089612.html
Copyright © 2011-2022 走看看