数组中字符的排列
Permutations of characters in an array
我输入了一个字符数组,并希望获得该数组的所有可能组合作为输出。例如,如果我输入字符数组=‘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";
}
}
http://www.sgi.com/tech/stl/next_permutation.html
std::next_preputation应该有助于您进行
为什么您的代码失败
你的代码会产生2次排列,因为这就是你正在做的。您要选择一个前缀,然后按顺序和相反顺序打印字符串,也就是说,每个前缀有两个输出。总数=n*2。(这样你怎么可能打印所有排列?)
解决方案
您需要的是std::next_placement。记住在下一次传递数组之前对数组进行排序,它会按递增顺序生成排列,这正是您所需要的(根据您的示例)。
您可以在这里阅读有关生成正确输出的递归实现,以及next_placement是如何在C++中实现的。
关于术语的评论:这些被称为排列,而不是组合。
这是因为你只看到由以下组成的排列:
- 选择第一个字母
- 将其余部分整理好,或者
- 把剩下的倒过来
特别是,你永远不能用这种方式从abcd
形成acbd
。
我建议第一次尝试递归解决方案(选择第一个字母,然后查看其余字母的所有排列)。
然后,如果您担心过多的递归调用会导致堆栈溢出,那么从递归解决方案中,您可以创建一个使用类似堆栈的数据结构的解决方案。
您可以使用标准库的算法部分中的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;
}
我想可以这样做:
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]);
}
}
说明:U首先调用get_combination(word,0)。现在要找到字符串的所有排列,每个位置的每个字符都应该出现在一个或其他排列的第一个位置。因此,我们从d=0开始,并交换每个字符,直到字符串末尾的字符为d。在第一个字符就位后,我们通过调用get_combination(单词,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"
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- C++字符*缓冲区的大小
- HEX值到wchar_t字符(UTF-8)的转换
- 为什么 Serial.println(<char[]>);返回随机字符?
- 在 CPP 中打印具有重复项的选定长度字符的所有排列
- 给定字符的排列算法,具有条件C++的重复
- 如何用单词排列向量中的每个字符升序?
- 有没有办法在不使用任何迭代的情况下将字符的字母顺序排列
- 如何找到通过仅移动相邻字符创建的字符串的排列?-C++
- 取消随机排列整数/字符数组
- 给定一组字符和长度的排列
- 打印可以由一组n个字符组成的长度为k的所有排列
- 当相应字符不在同一位置时,字符串的所有排列
- 字符的递归排列生成器
- 使用算术记数法横向排列一串字符
- 如何排列打印字符
- 如何生成具有重复字符的排列
- 在特定排列中连接字符串的字符
- 通过重新排列字符找到字符串中的所有回文子字符串
- 数组中字符的排列