1. 程式人生 > >陣列10——陣列的壓縮儲存2——上三角陣的壓縮儲存

陣列10——陣列的壓縮儲存2——上三角陣的壓縮儲存

 

編寫一個演算法,將一個以行為主序儲存的一維陣列轉換為以列為主序壓縮儲存的一維陣列。例如,設有n×n的上三角矩陣A的上三角元素已按行為主序連續存放在陣列b中,請設計一個演算法Trans將b中元素按列為主序存放在陣列c中。當n=5時,

矩陣A如圖所示:

其中b=(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15),c=(1,2,6,3,7,10,4,8,11,13,5,9,12,14,15)


【分析】

本題是軟體設計師考試題目和上海交通大學考研題目,主要考察特殊矩陣的壓縮儲存中對陣列下標的靈活使用程度。用i和j分別表示矩陣中元素的行列下標,用k表示壓縮矩陣b元素的下標。本題最重要是找出以行為主序和以列為主序的對應關係,即

c[j*(j+1)/2+i]=b[k];

其中,j*(j+1)/2+i就是根據等差數列得出的。根據這個對應關係,直接把b中的元素賦值給c中對應的位置即可。但是讀出c中一列即b中的一行之後,還要改變行下標i和列下標,開始讀6,7,8元素時,列下標j需要從1開始,行下標也需要增加1,依此類推,可以得出以下修改行下標和列下標的辦法:

當一行還沒有結束時,j++;否則i++修改下一行的元素個數及i、j的值,直到k=n(n+1)/2為止。
main.cpp

#include<iostream>
#include<iomanip>
using namespace std;
#define MAX 200
void CreateArray(int a[][MAX], int n);
void PrintArray(int a[MAX][MAX], int n);
void Trans(int b[], int c[], int n);
int PriorRow(int a[][MAX], int n, int b[]);
void main()
{
	int a[MAX][MAX], b[MAX], c[MAX], n, m, i;
	cout << "請輸入一個整數(<100):" << endl;
	cin >> n;
	CreateArray(a, n);
	cout << "二維陣列為:" << endl;
	PrintArray(a, n);
	m = PriorRow(a, n, b);
	cout << "陣列b中的元素:" << endl;
	for (i = 0; i < m; i++)
		cout << setw(4) << b[i];
	cout << endl;
	Trans(b, c, n);
	cout << "陣列c中的元素:" << endl;
	for (i = 0; i < m; i++)
		cout << setw(4) << c[i];
	cout << endl;


	system("pause");
}
int PriorRow(int a[MAX][MAX], int n, int b[])
//行優先儲存上三角矩陣到b中
{
	int i, j, k = 0;
	for (i = 0; i < n; i++)
		for (j = i; j < n; j++)
			b[k++] = a[i][j];
	return k;
}
void CreateArray(int a[][MAX], int n)
//建立一個上三角1-n的二維陣列(矩陣)
{
	int i, j, m;
	m = 1;
	for (i = 0; i < n; i++)
	{
		for (j = 0; j < i; j++)
			a[i][j] = 0;
		for (j = i; j < n; j++)
			a[i][j] = m++;
	}
}
void PrintArray(int a[MAX][MAX], int n)
//列印矩陣
{
	int i, j;
	for (i = 0; i < n; i++)
	{
		for (j = 0; j < n; j++)
			cout << setw(4) << a[i][j];
		cout << endl;
	}
}
void Trans(int b[], int c[], int n)
{
	int step = n, count = 0, i = 0, j = 0, k;
	for (k = 0; k < n*(n + 1) / 2; k++)
	{
		count++;			/*記錄一行是否讀完*/
		c[j*(j + 1) / 2 + i] = b[k];/*把以行為主序的數存放到對應以列為主序的陣列中*/
		if (count == step)/*一行讀完後*/
		{
			step--;
			count = 0;/*下一行重新開始計數*/
			i++;/*下一行的開始行*/
			j = n - step;/*一行讀完後,下一輪的開始列*/
		}
		else
			j++;/*一行還沒有讀完,繼續下一列的數*/
	}
}

結果: