打印排列-字符串
给出一个字符串,找到并打印输入字符串的所有可能排列。注意:排列顺序并不重要。只需将它们打印在不同的行中即可。
样本输入:
abc
样本输出:
abc acb bac bca cab cba
#include <iostream>
#include <string>
using namespace std;
void printCurrentString(string input, string result, int count[], int level)
{
if (level == input.size())
{
cout << result << endl;
return;
}
else
{
for (int i = 0; i < input.size(); i++)
{
if (count[i] == 0)
continue;
else
{
result[level] = input[i];
count[i]--;
printCurrentString(input, result, count, level + 1);
count[i]++;
}
}
}
}
void printPermutations(string input)
{
char *result = new char[input.size()];
int *count = new int[input.size()];
for (int i = 0; i < input.size(); i++)
count[i] = 1;
printCurrentString(input, result, count, 0);
}
int main()
{
string input;
cin >> input;
printPermutations(input);
return 0;
}
两个主要问题,都导致undefined behavior:
首先通过printPermutations
功能:
char *result = new char[input.size()];
如我的评论中所述,这将分配内存,但不会以任何方式对其进行初始化。从此内存创建std::string
是UB(不确定行为)的原因之一。
第二个在printCurrentString
功能中,您在这里
result[level] = input[i];
由于您不知道result
中字符串的实际大小,因此您不知道level
是否是有效索引。可能会超出范围。超出范围的索引也会导致UB。
您可以通过一个简单的更改就可以解决这两个问题:在printPermutations
函数中,请不要按照您的方式动态创建结果字符串。而是创建一个具有正确长度的适当std::string
对象,并将其传递给它:
printCurrentString(input, string(input.length()), count, 0);
[考虑到您有内存泄漏(您没有delete[]
您的内存new[]
),我也建议您将std::vector<int>
用作count
,并通过引用传递此向量。