'Every possible combination of string [duplicate]

I have to get every possible combination of given string. The string I get can be of various sizes but always contains only 1 and 0.

For example, Combinations I want to get with "101" as the input :

"000" "001" "010" "100" "110" "101" "011" "111".

I tried using std::next_permutation (c++20), I'm getting close but this not exactly not what I want.

The final goal is to store every combination inside a string vector.

Below is what I tried with next_permutation

// I'm not using *using namespace std* no need to mention it
std::vector<std::string>    generate_all_combinations(std::string base)
{
   std::vector<std::string> combinations;
   do {
       combinations.push_back(base);
   } while (std::next_permutation(base.begin(), base.end()));
   return combinations;
}

When I print the vector's content I have : "011" "101" "110".

The base strings "000" and "111" are not a problem I can generate those pretty easily. But I'm still lacking other combinations like "001" "010" "100".



Solution 1:[1]

Maybe this is not the answer you expect, but if you want every binary combination for a specified count of bits, this is one possible solution:

  void getCombinations(std::vector<std::string>& str_list, int len)
  {
    uint64_t comb_count = 1ull << len;

    std::string str;

    for(uint64_t i = 0; i < comb_count; ++i) {

      str.clear();

      for(int j = 0; j < len; ++j)
        str += ((i >> j) & 0x1) ? "1" : "0";

      str_list.push_back(str);
    }
  }

Solution 2:[2]

std::next_permutation won't work here, you will have to craft your own function here.

For example, for a symbol list "ab" where the permutations have a length of 3, you can get the 4th permutation by converting the number 4 to base 2 (length of symbol list) and use that as an index table for your permutation.

so 4 becomes 100 in base 2, so the indices are {1, 0, 0} and for the symbol list that is 'b', 'a', 'a' therefore the string "baa".


Here is a possible implementation of this, and it takes a symbol list, permutation length and current number of permutation. You can manually convert to any base by diving by base^position and taking modulus of base. The base is simply the length of the symbol list:

template<std::integral T>
constexpr T int_pow(T b, T e) {
    return (e == 0) ? T{ 1 } : b * int_pow(b, e - 1);
}

std::string get_permutation(const std::string& symbols, std::size_t permutation_size, std::size_t position) {
    std::string permutation;
    permutation.resize(permutation_size);

    auto base = symbols.length();

    for (std::size_t i = 0u; i < permutation_size; ++i) {

        auto index = (position / int_pow(base, i)) % base;
        permutation[permutation_size - i - 1] = symbols[index];
    }
    return permutation;
}

so calling this:

std::cout << get_permutation("ab", 3u, 4u) << '\n';

prints out

baa

with this function you can make a list_permutations function, that adds all permutations to a vector:

std::vector<std::string> list_permutations(const std::string& symbols, std::size_t permutation_size) {

    auto result_size = std::size_t(std::pow(symbols.length(), permutation_size));
    std::vector<std::string> result(result_size);

    for (std::size_t i = 0u; i < result.size(); ++i) {
        result[i] = get_permutation(symbols, permutation_size, i);
    }

    return result;
}

int main() {
    auto list = list_permutations("01", 3u);
    for (auto& i : list) {
        std::cout << i << '\n';
    }
}

output:

000
001
010
011
100
101
110
111

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2