[英]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.