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);
        }
    }

      

  • 相关阅读:
    【工具篇】抓包中的王牌工具—Fiddler (2-工具介绍)
    SQL注入攻击的常见方式及测试方法
    Xshell访问和连接Linux
    【户口篇】换房过程中,户口怎么迁移?
    【计算机篇】二维码解析、短地址生成器
    【工具篇】Sublime Text 2/3 安装汉化破解、插件包安装教程详解
    【通用】登录功能测试用例
    【工具篇】接口测试神器 -- Postman 入门教程
    【生活篇】微信运动刷步,高达98000!微信运动计步作弊教程!
    关于The C compiler "arm-none-eabi-gcc" is not able to compile a simple test program. 的错误自省...
  • 原文地址:https://www.cnblogs.com/tractorman/p/4089612.html
Copyright © 2011-2022 走看看