Ваш пример показывает, что вы хотите выводить не только каждое подмножество вашего входа ( Power set ), но и все перестановки каждого набора.
Мне не известен конкретный термин, используемый для этого, но OEIS A000522 называет эти "договоренности".
Чтобы получить то, что вам нужно, вы должны по существу объединить свой код с частичным ответом Джарода (или любой другой реализацией набора мощности, которую вы можете найти здесь):
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 циклом ЦП на каждый выход комфортно с этим.