Get all combinations without duplicates

前端 未结 2 801
[愿得一人]
[愿得一人] 2021-01-26 23:40

Give all possible combinations of a string without duplicates in c++. Example input: \"123\" and output combinations will be:

 1,12,123,13,2,23,3.
相关标签:
2条回答
  • 2021-01-27 00:01

    What the OP is looking for is equivalent to the Power Set minus the Empty Set. The desired output can easily be achieved without recursion. Here is a simple approach:

    #include <vector>
    #include <string>
    #include <cmath>
    #include <iostream>
    
    void GetPowerSet(std::string v) {
    
        std::string emptyString;
        std::vector<std::string> powerSet;
        int n = (int) std::pow(2.0, (double) v.size()); // Get size of power set of v
        powerSet.reserve(n);
        powerSet.push_back(emptyString); // add empty set
    
        for (std::string::iterator it = v.begin(); it < v.end(); it++) {
            unsigned int tempSize = powerSet.size();
            for (std::size_t j = 0; j < tempSize; j++)
                powerSet.push_back(powerSet[j] + *it);
        }
    
        // remove empty set element
        powerSet.erase(powerSet.begin());
    
        // print out results
        std::cout << "Here is your output : ";
        for (std::vector<std::string>::iterator it = powerSet.begin(); it < powerSet.end(); it++)
            std::cout << *it << ' ';
    }
    
    int main() {
        std::string myStr;
        std::cout << "Please enter a string : ";
        std::cin >> myStr;
        GetPowerSet(myStr);
        return 0;
    }
    

    Here is the output:

    Please enter a string : 123
    Here is your output : 1 2 12 3 13 23 123
    

    Explanation:

    We first note that the size of the power set is given by 2^n where n is the size of the initial set. For our purposes, our final vector will only contain 2^n - 1 elements, however we still need to reserve 2^n in order to prevent resizing as the "empty" element is needed to construct our result.

    The real work is carried out inside the two for loops in the middle of GetPowerSet. We start with a blank element. We then iterate over each character in our original vector creating subsets of our power set along the way. E.g

    1. Initialize power set with the empty set: powerSet = {}
    2. Add the first element of v to every element of the power set above: '' + '1' = '1' .
      • powerSet = {{}, '1'}
    3. Add the second element of v to every element of the power set above: '' + '2' = '2', '1' + '2' = '12'
      • powerSet = {{}, '1', '2', '12'}
    4. Add the third element of v to every element of the power set above: '' + '3' = '3', '1' + '3' = '13', '2' + '3' = '23', '12' + '3' = '123'
      • powerSet = {{}, '1', '2', '12', '3', '13', '23', '123'}
    5. Now remove first element in the power set above.
      • powerSet = {'1', '2', '12', '3', '13', '23', '123'}

    And we're done.

    0 讨论(0)
  • 2021-01-27 00:22

    Thought I'd add an answer from @Caninonos in the comments. I just simplified it slightly removing templates etc. This is a recursive solution.

    #include <iostream>
    #include <vector>
    using namespace std;
    
    void get_substrings_aux(vector<string>& subs, string str ,unsigned int cnt) {
    
        if(cnt == str.size())
        return;
    
        int n = subs.size();
        char c = str[cnt];
        for(int i = 0 ; i < n ; ++i) {
            subs.push_back(subs[i] + c);
            cout << subs[i] + c << endl;
        }
        get_substrings_aux(subs, str, ++cnt);
    }
    
    vector<string> get_substrings(const string& str) {
        vector<string> subs(1);
        int cnt=0;
        get_substrings_aux(subs, str, cnt);
        subs.erase(subs.begin());
        return subs;
    }
    
    int main() {
        string str("1234");
        vector<string> subs = get_substrings(str);
        return 0;
    }
    
    0 讨论(0)
提交回复
热议问题