【问题标题】:Knuth Permutation Algorithm Weird behaviourKnuth 置换算法奇怪的行为
【发布时间】:2010-06-23 07:27:38
【问题描述】:

我附上了一个代码,它根据 cout 语句给出奇怪的输出。这个程序本质上是计算 Knuth 的排列。

输入说:run1 代码运行良好: 呼叫跟踪将是:
r un1
你的 n1
努尔 1
1nur
n1ur
nu1r
nur1
在此代码运行之后,调用正确返回到步骤 where
urn 1
存在,但它不处理“RETURN”语句下方的代码。

另外,如果假设循环中有一个 cout 完成了排列,它甚至不会在 return 语句下面打印 cout

请让我知道我的代码中是否存在任何基本缺陷或逻辑错误?

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

谢谢!

【问题讨论】:

  • 更好地描述它应该输出什么以及它真正输出什么会很有用。
  • 请提供有关您所看到的行为和您实际期望的信息。就目前而言,这不是一个问题,并且可能会被关闭(“请检查我的代码”不是一个问题,抱歉)。
  • Input is say: run1 第一遍代码运行良好: 调用跟踪将是: r un1 ur n1 nur 1 1nur 1nur n1ur nu1r nur1 最后一次设置后,调用正确返回到 urn 所在的步骤1 存在,但它不处理“RETURN”语句下方的内容。
  • 另外,如果假设循环中有一个 cout 完成排列,它甚至不会在 return 语句下面打印 cout。
  • 编辑您的问题,而不是在 cmets 中展开它。也许这很有趣,但您的格式会影响内容。

标签: c++ permutation knuth


【解决方案1】:

如果这不是为了个人教育,你真的应该使用预定义的函数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开始排列,你仍然可以生成包含{0, 1, 2, 3}vector&lt;int&gt;的排列,然后通过这段代码构建中间字符串:

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

【讨论】:

  • 如果要以“run1”开始和结束,不要检查next_permutation是否返回false,而是检查起始值。 IE。 do { .... ; next_permuation(s.begin(), s.end()); } while (s != "run1");
【解决方案2】:

使用 gdb 之类的调试器,逐行执行程序,同时检查值。

【讨论】:

    【解决方案3】:

    对于 C++,您应该在 &lt;string&gt; 标头中使用 string 类。这将使您的代码更安全、更易读。也许你可以更好地发现你的错误。

    【讨论】:

      猜你喜欢
      • 2016-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多