5

I want to make simple sorting algorithm.

given the input "abcde", I would like the output below. could you tell me the algorithm for that?

arr[0] = "a"
arr[1] = "ab"
arr[2] = "ac"
arr[3] = "ad"
arr[4] = "ae"
arr[5] = "abc"
arr[6] = "abd"
arr[7] = "abe"
...
arr[n] = "abcde"

arr[n+1] = "b"
arr[n+2] = "bc"
arr[n+3] = "bd"
arr[n+4] = "be"
arr[n+5] = "bcd"
arr[n+5] = "bce"
arr[n+5] = "bde"
...
arr[n+m] = "bcde"
...
...
0

3 Answers 3

7

An algorithm for "generating Power Set" from an array is what you are looking for. You can try Google or some other search engine to find the algorithm that best fits your needs.

Sign up to request clarification or add additional context in comments.

1 Comment

+1 cause sometimes people feel that they need to google for something but do not know the name of the algorithm.
6

In C++ given the following routine:

template <typename Iterator>
bool next_combination(const Iterator first, Iterator k, const Iterator last)
{
   /* Credits: Mark Nelson http://marknelson.us */
   if ((first == last) || (first == k) || (last == k))
      return false;
   Iterator i1 = first;
   Iterator i2 = last;
   ++i1;
   if (last == i1)
      return false;
   i1 = last;
   --i1;
   i1 = k;
   --i2;
   while (first != i1)
   {
      if (*--i1 < *i2)
      {
         Iterator j = k;
         while (!(*i1 < *j)) ++j;
         std::iter_swap(i1,j);
         ++i1;
         ++j;
         i2 = k;
         std::rotate(i1,j,last);
         while (last != j)
         {
            ++j;
            ++i2;
         }
         std::rotate(k,i2,last);
         return true;
      }
   }
   std::rotate(first,k,last);
   return false;
}

You can then proceed to do the following:

std::string s = "abcde";
for(std::size_t i = 1; i != s.size(); ++i)
{
   do
   {
      std::cout << std::string(s.begin(),s.begin() + i) << std::endl;
   }
   while(next_combination(s.begin(),s.begin() + i,s.end()));
}

Note: That you should expect to see 2^n-1 combinations, where n is the length of the array or string.

3 Comments

The website you cited does not appear to contain this program.
you should try a little harder: marknelson.us/2002/03/01/next-permutation on the page search for the term: "next_combination"
@Beh: Incorrect. I put next_combination in the search bar, it auto-completed, and returned no results marknelson.us/… . I suspect you used Google. In any case, that page doesn't contain that program, there are only comments with links to various similar programs. The closest I see to an explanation is codeguru.com/cpp/cpp/algorithms/combinations/article.php/c5117 but it doesn't have this particular code. Having reposted someone's code, you should provide clearer credits.
5

You are describing a power set. Here is some C++ code:

#include <vector>
#include <string>
#include <algorithm>
#include <functional>
using namespace std;

vector< string > string_powerset( string const &in ) {
    vector< string > result(1); // start output with one empty string
    result.reserve( 1 << in.size() ); // output size = 2^( in.size() )
    if ( result.capacity() != 1<<in.size() ) throw range_error( "too big" );

    for ( string::const_iterator it = in.begin(); it != in.end(); ++ it ) {
        size_t middle = result.size(); // duplicate what we have so far
        result.insert( result.end(), result.begin(), result.end() );

          // append current character onto duplicated output
        for_each( result.begin() + middle, result.end(),
           bind2nd( mem_fun_ref( &string::push_back ), * it ) );
    }
    return result;
}

Tested working :v) . The range check isn't the best, but whatever.

This code will tend to overflow, due to the exponential growth of the powerset, so you should only pass it short strings. The other posted answer avoids this problem by generating and returning one string at a time. However, this is easier to understand, and using a far larger and more confusing piece of code would be premature optimization unless you actually have an overflow problem.

EDIT: I wrote up a next_subset answer, and it looks nothing like Ben's.

4 Comments

I voted you up, because you make nice use of STL. But there are some things i would critize, but these are style issues. First, using namespace std is not a good Idea. Second, using the shift operator for power of 2 is a bit unclear. Third, why string const & in instead of const string & in (I have never seen that)?
1. I felt I earned some laziness by fixing the question and writing all this code. OP doesn't strike me as likely to have large-codebase issues. This isn't a header file. 2. So I commented on it and also noted dismay on the overflow situation. 3. My const style is more uniform. const attaches to the preceding identifier or modifier, unless const is the first token of the type. I avoid the special case. Also, saying string first "gets down to business faster."
For the record, this answer now has 3 upvotes and 3 downvotes. No downvoter has left a comment.
I upvoted you for the reason they downvoted. I myself use style presented by you, and if someone tells me that he never saw this before I just don't know what to say.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.