【问题标题】:Generating permutations of a given string that have a condition生成具有条件的给定字符串的排列
【发布时间】:2019-12-09 18:12:19
【问题描述】:
在对给定字符串(例如字符串“ABC”)进行排列时,如果 B 不能在 A 之后(B 总是必须在 A 之前使用)这样的条件,我将如何设置位置条件,这将导致仅在:
BAC
BCA
CBA
代替:
ABC
ACB
BAC
BCA
CAB
CBA
如果不先生成所有排列然后只测试条件,这怎么可能? (我想跳过路线而不是测试排列后缀主要是通过更长的字符串所需的时间。)
目前我正在使用回溯来摆脱 B 直接在 A 之后的组合并跳过路线,但是我在测试字符串 ACB 中 A 之后的任何位置是否仍会显示时遇到问题。
【问题讨论】:
标签:
c++
string
conditional-statements
permutation
【解决方案1】:
你可以独立地构造你的前缀和后缀,比如:
void foo(std::string prefix, std::string suffix)
{
do
{
do
{
std::cout << prefix << "B" << suffix << std::endl;
} while (std::next_permutation(suffix.begin(), suffix.end()));
} while (std::next_permutation(prefix.begin(), prefix.end()));
}
std::pair<std::string, std::string> split(const std::string& letters, unsigned int flag)
{
std::string prefix{"A"};
std::string suffix;
for (auto c : letters) {
if (flag & 1) {
prefix.push_back(c);
} else {
suffix.push_back(c);
}
flag >>= 1;
}
return {std::move(prefix), std::move(suffix)};
}
void foo(std::string letters)
{
//assert(letters.size() < 31); // else would require some dynamic bitset
auto max = 1 << letters.size();
std::sort(letters.begin(), letters.end());
for (int i = 0; i != max; ++i) {
auto [prefix, suffix] = split(letters, i);
foo(prefix, suffix);
}
}
Demo