0

I have attached a code which gives weird outputs basing on cout statements. This program essentially computes the Knuth's Permutations.

Input is say: run1 The code runs for first pass fine: Call trace will be:
r un1
ur n1
nur 1
1nur
n1ur
nu1r
nur1
After this run of code, the call returns correctly to step where
urn 1
is there but it doesnt proceess the code below the "RETURN" statement.

Also, if there is suppose a cout within the loop where permutations are done, it doesnt even print the cout below the return statement

Please let me know if there is any fundamental flaw in my code or a logical bug ?

    #include <iostream>
using namespace std;

void swap( char *l, char *m )
{
 char t = *l;
 *l = *m;
 *m = t;
}
void Permute( char *result, char *temp, int len )
{
 int k = 0;
 int j = 0;
 char d[ 1000000];
 int i = 0;
 //cout << " Start of Perm " << result << " Stack: " << temp << endl;
 while( result[ i ] != '\0' )
 {
  if( temp[ k ] !='\0' )
  {
   cout << " Start of Perm " << result << " Stack: " << temp << endl;
   strncpy( d, &temp[ k ], sizeof( char ) ); 
   strncat( d, result, sizeof( result )  );
   strncat( d, "\0", sizeof( char ) );
   cout << " Principal: " << d << endl;
   k = k + 1;
   if( temp[ k ] != '\0' )
    Permute( d, &temp[ k ], len );
   else
   {
    char d1[ 10000 ];
    strncpy( d1, &temp[ k ], sizeof( char ) ); 
    strncat( d1, d, sizeof( d )  );
    strncat( d, "\0", sizeof( char ) );
    strncpy( d, d1, sizeof( d ) );
    //cout << "Final Level: " << d << endl;
    strncpy( result, d, sizeof( d ) );
   }
  }
  //cout << strlen( result ) << " == length which is " << len << " and result is: " << result << endl;
  if( strlen( result ) >= len )
  {
   //cout << " Permutation Sets" << endl;
   char result1[ 1000 ];
   memcpy( result1, result, sizeof( result ) );
   for( int p = 0; result1[ p ] != '\0'; p++ )
   {
    cout << "End : " << result1 << endl;
    if( result1[ p + 1 ] != '\0' )
     swap( &result1[ p ], &result1[ p + 1 ] );
   }
   return;
  }
  cout << " Value of I is: " << i <<  " and value of K is: " << k << endl;
  if( result[ i + 1 ] != '\0' )
  {
   swap( &result[ i ], &result[ i + 1 ] );
   k = 0;
   d[ 0 ] = '\0';
   cout << "New Branch: Value = " << result << " and stack = " << temp << endl;
  }
  i = i + 1;
 }
}



int main( int argc, char *argv[] )
{
 char c[100], temp[100];
 cin >> c;
// cout << c << endl;
 memcpy( temp, c, sizeof(c) );
// cout << temp << endl;
 char c1[2];
 c1[0] = c[0];
 c1[1] = '\0';
 Permute( c1, &temp[1], strlen( c ) );
}

Thanks!

Roland Illig
  • 40,703
  • 10
  • 88
  • 121
RMR
  • 13
  • 6
  • 1
    A better description of what it should output and what it's really outputting would be useful. – Adam Crume Jun 23 '10 at 07:30
  • 6
    Please provide information on the behaviour you're seeing and what you actually expect. As it stands this isn't a question, and will probably be closed ("please review my code" isn't a question, sorry). – Binary Worrier Jun 23 '10 at 07:33
  • Input is say: run1 The code runs for first pass fine: Call trace will be: r un1 ur n1 nur 1 1nur 1nur n1ur nu1r nur1 After the last set, the call returns correctly to step where urn 1 is there but it doesnt proceess the things below the "RETURN" statement. – RMR Jun 23 '10 at 07:42
  • Also, if there is suppose a cout within the loop where permutations are done, it doesnt even print the cout below the return statement. – RMR Jun 23 '10 at 07:43
  • Edit your question instead of expanding it in the comments. Maybe it's interesting, but the your formatting will shadow the content. – miku Jun 23 '10 at 07:45
  • Can you tell me which algorithm are you talking about, is it algorithm p (plain changes)? _maybe can help_ – Ramadheer Singh Jul 11 '11 at 08:20

3 Answers3

2

If this isn't for personal education, you should really use the predefined function next_permutation. It's quite easy to use:

#include <algorithm>
#include <iostream>
#include <string>

using std::string;
using std::cout;
using std::sort;

int main() {
  string s("run1");

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

  do {
    cout << s << "\n";
  } while (next_permutation(s.begin(), s.end()));

  return 0;
}

And if you really need to start the permutations with run1, you can still generate the permutations of the vector<int> containing {0, 1, 2, 3} and then build the intermediate string by this code:

#include <algorithm>
#include <cstddef>
#include <iostream>
#include <string>
#include <vector>

using std::cout;
using std::string;
using std::vector;

int main() {
  string s("run1");

  vector<int> indexes;
  for (size_t i = 0; i < s.size(); i++)
    indexes.push_back(i);

  do {
    string tmp("");
    for (size_t i = 0; i < indexes.size(); i++)
      tmp += s[indexes[i]];
    cout << tmp << "\n";
  } while (next_permutation(indexes.begin(), indexes.end()));

  return 0;
}
Roland Illig
  • 40,703
  • 10
  • 88
  • 121
  • 1
    If you want to start and end with "run1", don't check whether `next_permutation` returns `false`, but check for the starting value. I.e. `do { .... ; next_permuation(s.begin(), s.end()); } while (s != "run1");` – MSalters Jul 28 '10 at 08:54
1

Use a debugger like gdb and step through the program line by line, while checking the values.

Sjoerd
  • 74,049
  • 16
  • 131
  • 175
1

For C++ you should use string class in the <string> header. This will make your code much safer and better readable. Maybe you can spot your errors better then.

codymanix
  • 28,510
  • 21
  • 92
  • 151