数组中字符的排列

时间:2011-06-18 06:04:21

标签: c++

我输入了一个字符数组,希望将该数组的所有可能组合作为输出。 例如,如果我输入字符数组='a,b,c', 我希望以这种形式输出:

a b c,
a c b,
b a c,
b c a,
c a b,
c b a

同样如果我输入4个字符,我想从中获得24个组合。我为此创建了一个代码,但它只返回输入字符数量的2倍组合。也就是说,如果我输入3个字符(右边),代码返回6个组合,但如果我输入4个字符,它只返回8个可能的组合而不是24个组合。 我的代码如下:

#include <iostream>
#include<string.h>
#include<stdio.h>
using std::cout;
void getCombination(char *);

int main()
{
    const int maxStringSize = 26;
    char thisString[maxStringSize];
    cout<<"Enter String = ";
    gets (thisString);
    getCombination(thisString);
    return 0;
}

void getCombination(char *thisString)
{
    int stringSize=strlen(thisString);
    for(int i = 0; i<stringSize; i++)
    {
        for(int j = 0; j<stringSize; j++)
        {
            cout<<thisString[(i+j)%stringSize];
        }
        cout<<"\n";
        for(int k = stringSize-1; k>=0; k--)
        {
            cout<<thisString[(i+k)%stringSize];
        }
    cout<<"\n";
    }
}

5 个答案:

答案 0 :(得分:2)

http://www.sgi.com/tech/stl/next_permutation.html

std :: next_permutation可以帮助你前进

答案 1 :(得分:2)

为什么您的代码失败了?

您的代码会产生2次排列,因为这就是您正在做的事情。您正在选择一个前缀,然后按顺序和相反的顺序打印字符串,即每个前缀的两个输出。总数= n * 2。 (这样你怎么可能打印所有排列?)

<强>解决方案<!/强>

你需要的是std :: next_permutation。请记住在将数组传递给next_permutation之前对其进行排序,它会按递增顺序生成排列,这是您需要的(根据您的示例)。

您可以阅读有关生成正确输出的递归实现以及如何在C ++ here中实现next_permutation。

答案 2 :(得分:1)

关于术语的评论:这些被称为排列而不是组合。

那是因为你只关注由以下形成的排列:

  • 选择第一个字母和
  • 将其余部分按顺序排列,或
  • 将其余部分按相反顺序排列

特别是,您永远不能以acbd的方式形成abcd

我建议尝试使用递归解决方案作为第一个传递(选择第一个字母,然后查看其余部分的所有排列)。

然后,从递归解决方案中,如果您担心由于过多的递归调用导致的堆栈溢出,您可以创建一个使用堆栈等数据结构的解决方案。

答案 3 :(得分:1)

您可以使用标准库的算法部分中的std::next_permutation来执行此操作。有关示例,请参阅下面的代码段。请注意,我先排序theString,因为next_permutation需要找到所有组合。

#include <iostream>
#include <algorithm>

int main()
{
    std::string theString = "abc";

    std::sort(theString.begin(), theString.end()); 

    do
    {
        std::cout << theString << std::endl;
    }
    while (std::next_permutation(theString.begin(), theString.end()));

    return 0;
}

答案 4 :(得分:0)

我想可以这样做:

void swap( char &a, char &b) {
char c=a;
a = b;
b = c;
}


void get_Combination( string word, int d ) {
if (d == word.size()) {
    cout<<word<<endl;
    return;
}

for (int i=d; i< word.size(); ++i) {
    swap(word[i],word[d]);
    get_combination( word, d+1 );
    swap(word[i],word[d]);
}
}

说明: 你首先调用get_combination(word,0)。现在要查找字符串的所有排列,每个位置的每个字符都应出现在一个或其他排列的第一个位置。因此,我们从d = 0开始并交换每个字符,直到字符串结尾,字符为d。在第一个字符到位后,我们通过调用get_combination(word,d + 1)重复从第二个字符开始的过程。还要注意第二次交换,这是将最初交换的字符恢复到原始位置然后用位置d处的字符交换下一个字符所需的。

示例:

给定字符串abc,这里是递归树,gc = get_combination

gc("abc",0)

   gc(abc,1)

      gc(abc,2)

        cout<<"abc"

      gc(acb,2)

        cout<<"acb"

   gc(bac,1)

      gc(bac,2)

        cout<<"bac"

      gc(bca,2)

        cout<<"bca"

  gc(cba,1)

      gc(cba,2)

        cout<<"cba"

      gc(cab,2)

        cout<<"cab"