• 字符串的排列


     
    题目:输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab、cba。

    求整个字符串的排列,可以看成两步

    1. 首先求所有可能出现在第一个位置的字符,即把第一个字符和后面所有的字符交换。下图就是分别把第一个字符a和后面b、c等字符交换的情形。
    2. 第二步固定第一个字符(如图a所示),求后面所有字符的排列。这个时候我们仍把后面的所有字符分成两部分:后面字符的第一个字符,以及这个字符之后的所有字符。然后把第一个字符逐一和它后面的字符交换(如图b所示)。。。

    分析到这里,其实可以看出,这就是很典型的递归思路

    实现代码如下:

    void Permutation(char* pStr)
    {
        if(pStr == NULL)
            return;
    
        Permutation(pStr, pStr);
    }
    
    void Permutation(char* pStr, char* pBegin)
    {
        if(*pBegin == '')
        {
            printf("%s
    ", pStr);
        }
        else
        {
            for(char* pCh = pBegin; *pCh != ''; ++ pCh)
            {
                char temp = *pCh;
                *pCh = *pBegin;
                *pBegin = temp;
    
                Permutation(pStr, pBegin + 1);
    
                temp = *pCh;
                *pCh = *pBegin;
                *pBegin = temp;
            }
        }
    }
    

     在函数Permutation(char* pStr, char* pBegin)中,指针pStr指向整个字符串的第一个字符,pBegin指向当前我们做排列操作的字符串的第一个字符。在每一次递归的时候,我们从pBegin向后扫描每一个字符(即指针pCh指向的字符)。在交换pBegin和pCh指向的字符之后,我们再对pBegin后面的字符递归地做排列操作,直至pBegin指向字符串的末尾。

    测试代码如下:

    #include<stdio.h>
    
    void Permutation(char* pStr, char* pBegin);
    
    void Permutation(char* pStr)
    {
        if(pStr == NULL)
            return;
    
        Permutation(pStr, pStr);
    }
    
    void Permutation(char* pStr, char* pBegin)
    {
        if(*pBegin == '')
        {
            printf("%s
    ", pStr);
        }
        else
        {
            for(char* pCh = pBegin; *pCh != ''; ++ pCh)
            {
                char temp = *pCh;
                *pCh = *pBegin;
                *pBegin = temp;
    
                Permutation(pStr, pBegin + 1);
    
                temp = *pCh;
                *pCh = *pBegin;
                *pBegin = temp;
            }
        }
    }
    
    // ====================测试代码====================
    void Test(char* pStr)
    {
        if(pStr == NULL)
            printf("Test for NULL begins:
    ");
        else
            printf("Test for %s begins:
    ", pStr);
    
        Permutation(pStr);
    
        printf("
    ");
    }
    
    int main(int argc, char* argv[])
    {
        Test(NULL);
    
        char string1[] = "";
        Test(string1);
    
        char string2[] = "a";
        Test(string2);
    
        char string3[] = "ab";
        Test(string3);
    
        char string4[] = "abc";
        Test(string4);
    
        return 0;
    }
    

    扩展1:如果不是求字符的所有排列,而是求字符的所有组合,应该怎么办呢?当输入的字符串中含有相同的字符串时,相同的字符交换位置是不同的排列,但是同一个组合。举个例子,如果输入abc,它的组合有a、b、c、ab、ac、bc、abc。(字符串的组合

    扩展2:输入一个含有8个数字的数组,判断有没有可能把这8个数字分别放到正方体的8个顶点上,使得正方体上三组相对的面上的4个顶点的和相等。

  • 相关阅读:
    loj 3285 「USACO 2020 US Open Platinum」Circus
    UOJ Round #19 简要题解
    AtCoder Grand Contest 043 简要题解
    JOISC 2020 部分题目简要题解
    HNOI 2019 简要题解
    十二省联考 2019 简要题解
    九省联考 2018 简要题解
    loj 6391 「THUPC2018」淘米神的树 / Tommy
    loj 6703 小 Q 的序列
    Goodbye Jihai 部分题目简要题解
  • 原文地址:https://www.cnblogs.com/heyonggang/p/3405948.html
Copyright © 2020-2023  润新知