views:

130

answers:

3

Lets say, we have string "ABCAD", now we need to iterate through all possible arrangement of this string in both clockwise and counter-clockwise direction.

My ugly implementation looks like this:

string s = "ABCAD";
string t ="";
 for(int i = 0; i < sz(s); i++){
    t = s[i];
  for(int j = i+1; ; j++){
      if((j) == sz(s)){
         j = 0;
        }
       if(j == i){
          break;
        }
       t+= s[j];
     }
     cout<<t<<" ";
   }
reverse(all(s));
 for(int i = 0; i < sz(s); i++){
    t = s[i];
  for(int j = i+1; ; j++){
      if((j) == sz(s)){
         j = 0;
        }
       if(j == i){
          break;
        }
       t+= s[j];
     }
     cout<<t<<" ";
   }

Output:

AHSAU HSAUA SAUAH AUAHS UAHSA UASHA ASHAU SHAUA HAUAS AUASH

I know that too naive,AFAIK a circular list would be a better choice, could somebody implement the same thing more efficiently using STL ?

+2  A: 

The best solution is not a data structure but an algorithm - see next_permutation

anon
Total number of permutation of "ABCAD" will be 5!/2! = 60,where as I need only 10.
nthrgeek
@nthrgeek Do you mean unique permutations? In that case save each one in a std::set as it is generated.
anon
It's just all rotation clockwise and counter-clockwise :)
nthrgeek
@nthrgeek How can "direction" make a difference? If I have "AB" the only possible unique permutations "AB" and "BA".
anon
Please enlighten me bu solving the problem using next permutation. :)
nthrgeek
+4  A: 

In pseudocode, I'd go this route:

function rearrange (string s) {
  string t = s + s;
  for (int i = 0; i < length(s); ++i)
    print t.substring(i, length(s));
}

input = "ABCAD"

rearrange(input);
rearrange(reverse(input));

There's probably a way to rewrite rearrange() using functors, but my STL-fu is rusty.

Lars
Yeah that's lovely :) You know I just got it myself and then I saw your answer :)
nthrgeek
Anyways +1 ,and accepted:)
nthrgeek
You can do it in one call to `rearrange` like this : `function rearrange (string s) { string t = s + s; string q = reverse(s) + reverse(s); for (int i = 0; i < length(s); ++i){ print t.substring(i, length(s)); print q.substring(i, length(s)); }}`
nthrgeek
+2  A: 

I believe what you are looking for is the rotate algorithm. For the reverse ones, you'll need to do the reverse as you did in your own code.

Untested code to do what yours does:

std::string s = "ABCAD"

for (int i = 0; i < s.size(); ++i)
{
  std::cout << s << std::endl;
  std::rotate(s.begin(), s.begin() + 1, s.end());
}

reverse(s.begin(), s.end());

// same loop as above for reverse "arrangements"
Peter Alexander
Put the for loop in its own function and I'm sold.
Mark Ruzon