C 一组字符串的所有布置
C++ all arrangements of a set of strings
我正在尝试生成向量中的所有字符串。例如,对于
vector<string> vs = { "a", "b", "c"};
我写了以下代码:
do{
for (string s : vs)
cout << s << " ";
cout << endl;
} while (std::next_permutation(vs.begin(), vs.end()));
我的输出是:
a b c
A C B
b a c
b c a
c a b
C B A
但是,我缺少
之类的组合a
A B
b a
c
等。
我想修改我的代码,以便也包括这些安排。怎么做?谢谢!
您的示例表明,您不仅要输出输入的每个子集(电源集(,还要输出每个集合的所有排列。
我不知道为此使用的特定术语,但是OEI A000522称之为这些"安排"。
要获得所需的东西,您必须将代码与JAROD的部分答案(或您可以在此处找到的任何其他电源集实现(结合起来:
void outputAllPermutations(std::vector<std::string> input)
{
// assert(std::is_sorted(input.begin(), input.end()));
do
{
for (std::string s : input)
std::cout << s << " ";
std::cout << std::endl;
} while (std::next_permutation(input.begin(), input.end()));
}
bool isBitSet(unsigned bitset, std::size_t i)
{
return (bitset & (1 << i)) != 0;
}
void outputAllArrangements(const std::vector<std::string>& input)
{
// assert(std::is_sorted(input.begin(), input.end()));
// assert(input.size() < std::sizeof(unsigned) * 8);
unsigned bitset = 0;
std::vector<std::string> subset{};
subset.reserve(input.size());
for (unsigned bitset = 0; bitset < (1 << input.size()); ++bitset)
{
subset.clear();
for (std::size_t i = 0; i != input.size(); ++i)
if (isBitSet(bitset, i))
subset.push_back(input[i]);
outputAllPermutations(subset);
}
}
演示包括示例输出
我使用了unsigned
而不是std::vector<bool>
,因为我发现整体增量逻辑更容易理解。从理论上讲,该代码将代码"限制"到小于32个字符串(或64个字符串,取决于平台(,但是看到输入长度22已经需要数千年的时间才能以每次输出为1 CPU周期输出,我对此感到满意。
您可以用:
实现电源集bool increase(std::vector<bool>& bs)
{
for (std::size_t i = 0; i != bs.size(); ++i) {
bs[i] = !bs[i];
if (bs[i] == true) {
return true;
}
}
return false; // overflow
}
template <typename T>
void PowerSet(const std::vector<T>& v)
{
std::vector<bool> bitset(v.size());
do {
for (std::size_t i = 0; i != v.size(); ++i) {
if (bitset[i]) {
std::cout << v[i] << " ";
}
}
std::cout << std::endl;
} while (increase(bitset));
}
演示
然后进行每组的置换,例如:
bool increase(std::vector<bool>& bs)
{
for (std::size_t i = 0; i != bs.size(); ++i) {
bs[i] = !bs[i];
if (bs[i] == true) {
return true;
}
}
return false; // overflow
}
template <typename T, typename F>
void PowerSet(const std::vector<T>& v, F f)
{
std::vector<bool> bitset(v.size());
do {
f(v, bitset);
} while (increase(bitset));
}
template <typename T, typename F>
void AllArrangements(const std::vector<T>& v, F f)
{
PowerSet(v, [f](const std::vector<T>& v, const std::vector<bool>& bitset){
std::vector<T> toPermute;
for (std::size_t i = 0; i != v.size(); ++i) {
if (bitset[i]) {
toPermute.push_back(v[i]);
}
}
do {
f(toPermute);
} while (std::next_permutation(toPermute.begin(), toPermute.end()));
});
}
demo