Алгоритм перестановки Кнута Странное поведение - PullRequest
0 голосов
/ 23 июня 2010

Я приложил код, который дает странные результаты, основанные на выражениях cout. Эта программа по существу вычисляет Перестановки Кнута.

Ввод: run1 Код выполняется для первого прохода нормально: Трассировка звонка будет:
r un1
ур n1
нур 1
1 нур
n1ur
nu1r
nur1
После этого выполнения кода вызов возвращается правильно к шагу, где
urn 1
есть, но он не обрабатывает код ниже оператора «RETURN».

Кроме того, если в цикле, где выполняются перестановки, предполагается, что cout существует, он даже не печатает cout ниже оператора return

Пожалуйста, дайте мне знать, есть ли какой-либо фундаментальный недостаток в моем коде или логическая ошибка?

    #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 ) );
}

Спасибо!

Ответы [ 3 ]

2 голосов
/ 28 июля 2010

Если это не для личного образования, вам действительно следует использовать предопределенную функцию next_permutation. Это довольно легко использовать:

#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;
}

И если вам действительно нужно начать перестановки с run1, вы все равно можете сгенерировать перестановки vector<int>, содержащие {0, 1, 2, 3}, а затем построить промежуточную строку с помощью этого кода:

#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;
}
1 голос
/ 23 июня 2010

Для C ++ вы должны использовать string класс в заголовке <string>. Это сделает ваш код намного безопаснее и лучше читаемым. Может быть, вы можете обнаружить свои ошибки лучше, чем тогда.

1 голос
/ 23 июня 2010

Используйте отладчик типа gdb и построчно просматривайте программу, проверяя значения.

...