簡體   English   中英

排列的矩陣和子矩陣

[英]Matrix and submatrix of permutations

我需要N個元素的所有排列的矩陣。 實際上,其尺寸將為N x N! 該矩陣的一個特殊屬性是每個子矩陣的尺寸為K x K! (K <N)必須是K個元素的所有排列的矩陣。 顯然有許多有效的解決方案,但是我對最簡單(但有效)的純C樣式算法感興趣,該算法僅生成這種類型的矩陣(沒有STL和其他高級庫)。

為了澄清這個問題,這里是生成矩陣的形式。 第二列以“ 2”開頭,第三列以“ 3”開頭,第i列以(i-1)開頭! 元素“ i”。 對排列的順序沒有其他要求,只需使算法簡單即可。

1 2 3 4 5 ...
2 1 3 4 5 ...
* * * 4 5 ...
* * * 4 5 ...
* * * 4 5 ...
* * * 4 5 ...
* * * * 5 ...
...

我希望我理解了這個問題;-)-解決方案是基於對KxK的觀察! 可以通過以下方式擴展錨定在a [1,1]上的子矩陣:a)將K + 1加到K! 行,b)復制第一個K!的行向量! 重復,即K次,排成K + 1 ..(K + 1)!行,同時替換每組K! 將值1..K乘以K + 1並將K存儲到列K + 1中。

#include <stdio.h>
#define N 6
#define NF (1*2*3*4*5*6)

int p[NF][N];

int main( int argc, char* args[] ){
  int n, i, k, iCol, iRow;
  int row = 0;

  for( n = 0; n < N; n++ ){
    if( n == 0 ){
      p[row][n] = n+1;
      row++;
    } else {
      // add new value n+1 to all existing rows
      for( i = 0; i < row; i++ ){
        p[i][n] = n+1;
      }
      // for all numbers 1..n
      int nextRow = row;
      for( k = 1; k <= n; k++ ){
        // pass through all rows so far
        for( iRow = 0; iRow < row; iRow++ ){
          // copy row
          for( iCol = 0; iCol < n; iCol++ ){ 
            int h = p[iRow][iCol];
            p[nextRow][iCol] = h == k ? n+1 : h;
          }
          p[nextRow][n] = k;
          nextRow++;
        }
      }
      row = nextRow;
    }
  }
  for( iRow = 0; iRow < NF; iRow++ ){
    for( iCol = 0; iCol < N; iCol++ ){
      printf( "%3d", p[iRow][iCol] );
    }
    printf( "\n" );
  }
}

這是使用來自問題的算法的工作程序, 提高了給定字符串的所有排列的時間復雜度

#include <stdio.h>
#define N 6
#define NF (1*2*3*4*5*6)

int p[NF][N];

void swap (int *a, int i, int j)
{
   int tmp;
   tmp = a[i];
   a[i] = a[j];
   a[j] = tmp;
}
void permute(int *a, int i, int n)
{
   int j;
   static int k=0;
   if (i == n) {
     for (j=0; j<N; j++) p[k][j] = a[N-j-1];
     k++;
   }
   else for (j=i; j<=n; j++) {
      swap(a,i,j);
      permute(a,i+1,n);
      swap(a,i,j);
   }
}
int main() {
  int i,j,a[N];
  for (i=0; i<N; i++) a[i] = N-i;
  permute(&a,0,N-1);
  for(i=0;i<NF;i++) {
    for(j=0;j<N;j++) {
      printf("%3d",p[i][j]);
    }
    printf("\n");
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM