Ten days - 压缩数组

目录

压缩数组的理解:

压缩数组的实现:

代码定义:

初始化:

普通数组转化成压缩:

压缩转化为普通数组:

 压缩数组的转置:

路思:

总代码:


---这次是压缩数组,其中有数组压缩、压缩数组还原、以及压缩数组的转置。

压缩数组的理解:

为什么需要压缩数组呢?为了节省空间如图:

就是利用数组存储,有效数据所在位置

压缩数组的实现:

代码定义:

typedef struct Triple {//用与记录 
	int i;
	int j;
	elem e; 
}Triple, *TriplePtr;

typedef struct CompressedMatrix {//压缩数组
	int rows, columns, numElements;
	Triple* elements;
}CompressedMatrix, *CompressedMatrixPtr;

这里利用的是struct嵌套实现-有名称意义二维数组(numElements * 3), 内嵌的struct便是有类别3个元素 ,分别是行、列、数据。

初始化:

CompressedMatrixPtr initCompressedMatrix(int paraRows, int paraColumns, int paraElements, int** paraData) {
	CompressedMatrixPtr resultPtr = (CompressedMatrixPtr)malloc(sizeof(struct CompressedMatrix));
	resultPtr->columns = paraColumns;
	resultPtr->rows = paraRows;
	resultPtr->numElements = paraElements;
	resultPtr->elements = (TriplePtr)malloc(paraElements * sizeof(struct Triple));
	
	for (int i  = 0; i < paraElements; i++) {
		resultPtr->elements[i].i = paraData[i][0];
		resultPtr->elements[i].j = paraData[i][1];
		resultPtr->elements[i].e = paraData[i][2];
	}//Of for i.
	
	return resultPtr;
} 

普通数组转化成压缩:

int** exchangeCompressed(TwoDArrayPtr paraPtr) {
	int** resultArray;

	resultArray = (int**)malloc(countValuableElement(paraPtr) * sizeof(int*));
	for (int i = 0; i < countValuableElement(paraPtr); i++) {
		resultArray[i] = (int*)malloc(3 * sizeof(int));
	}
	
	int k = 0;
	for (int i = 0; i < paraPtr->rows; i++) {
		for (int j = 0; j < paraPtr->columns; j++) {
			if (paraPtr->elements[i][j] != 0) {
				resultArray[k][0] = i;
				resultArray[k][1] = j;
				resultArray[k][2] = paraPtr->elements[i][j];
				k++;
			}
		}
	}
	return resultArray;	
}

其中的的 countValuableElement()数有效数据的个数:

int countValuableElement(TwoDArrayPtr paraPtr) {
	int cnt = 0;
	for (int i = 0; i < paraPtr->rows; i++) {
		for (int j = 0; j < paraPtr->columns; j++) {
			if (paraPtr->elements[i][j] != 0) {
				cnt++;
			}
		}
	}
	return cnt;
}

压缩转化为普通数组:

TwoDArrayPtr returnCompressed(CompressedMatrixPtr paraPtr) {
	TwoDArrayPtr resultArray = initTwoDArray(paraPtr->rows, paraPtr->columns);
	
	int k = 0;
	for (int i = 0; i < paraPtr->rows; i++) {
		for (int j = 0; j < paraPtr->columns; j++) {
			if (paraPtr->elements[k].i == i && paraPtr->elements[k].j == j) {
				resultArray->elements[i][j] = paraPtr->elements[k].e;
				k++;
			} else {
				resultArray->elements[i][j] = 0;
			}
			
		}
	}
	return resultArray;
}

 压缩数组的转置:

CompressedMatrixPtr transposeCompressedMatrix(CompressedMatrixPtr paraPtr) {
	//Step 1. 建立记录数组
	int *tempColumnCounts = (int*)malloc(paraPtr->columns * sizeof(int));//记录每一列所拥有的数据个数。 
	int *tempOffsets = (int*)malloc(paraPtr->columns * sizeof(int));//记录列交换后新二维数组的位置 
	//初始化
	for (int i = 0; i < paraPtr->columns; i++) {
		tempColumnCounts[i] = 0;//一开始全为 0 
	}
	
	//初始化新数组
	CompressedMatrixPtr resultPtr = (CompressedMatrixPtr)malloc(sizeof(struct CompressedMatrix));
	resultPtr->rows = paraPtr->columns;
	resultPtr->columns = paraPtr->rows;
	resultPtr->numElements = paraPtr->numElements;
	resultPtr->elements = (TriplePtr)malloc(paraPtr->numElements * sizeof(struct Triple));
	
	//Step 2.扫描数组
	for (int i = 0; i < paraPtr->numElements; i++) {
		tempColumnCounts[paraPtr->elements[i].j]++;
	} 
	
	//Step 3.初始化offset 
	tempOffsets[0] = 0;
	for(int i = 1; i < paraPtr->columns; i++) {
		tempOffsets[i] = tempOffsets[i - 1] + tempColumnCounts[i - 1];
	}
	
	//Step 4.填入
	int tempPosition, tempColumn;
	for (int i = 0; i < paraPtr->numElements; i++) {
		tempColumn = paraPtr->elements[i].j;
		tempPosition = tempOffsets[tempColumn];//给转前的列数,转化为其在之后的行的数列 
		//交换
		resultPtr->elements[tempPosition].i = paraPtr->elements[i].j;
		resultPtr->elements[tempPosition].j = paraPtr->elements[i].i;
		resultPtr->elements[tempPosition].e = paraPtr->elements[i].e;
		 
		tempOffsets[tempColumn]++;
	} //Of for i;
	
	return resultPtr; 
}

路思:

主要思路就是需要记录转置之前每列的数据个数-tempColumnCounts,然后记录转置之后之前的列在现在行的位置-tempOffsets(随填入而更新的),然后再俩点保障数据再正确位置,另外直接交换压缩数组的行列即可。

总代码:

#include <stdio.h> 
#include <malloc.h>

typedef int elem;//

/*
 * A trile for row index, colum index, and data.
 */
 
typedef struct Triple {//用与记录 
	int i;
	int j;
	elem e; 
}Triple, *TriplePtr;

/**
 * A triple for row index, colum index, and data.
 */

typedef struct CompressedMatrix {
	int rows, columns, numElements;
	Triple* elements;
}CompressedMatrix, *CompressedMatrixPtr;

//稀疏数组 
typedef struct TwoDArray{
	int rows;
	int columns;
	int** elements;
}TwoDArray, *TwoDArrayPtr;

TwoDArrayPtr initTwoDArray(int paraRows, int paraColumns){
	int i;
	TwoDArrayPtr resultPtr = (TwoDArrayPtr)malloc(sizeof(TwoDArray));
	resultPtr->columns = paraColumns;
	resultPtr->rows = paraRows;
	resultPtr->elements = (int**)malloc(sizeof(int*) * paraRows);
	for (i = 0; i < paraRows; i++) {
	resultPtr->elements[i] = (int*)malloc(sizeof(int) * paraColumns);
	}//Of for(i)
	
	return resultPtr;
}

void printTwoDArray(TwoDArrayPtr paraPtr) {
	for (int i = 0; i < paraPtr->rows; i++) {
		for (int j = 0; j < paraPtr->columns; j++) {
			printf("%d ", paraPtr->elements[i][j]);
		}//Of for i
		printf("\r\n");
	}//Of for j
}



/**
 * Initialize a compressed matrix.
 */
CompressedMatrixPtr initCompressedMatrix(int paraRows, int paraColumns, int paraElements, int** paraData) {
	CompressedMatrixPtr resultPtr = (CompressedMatrixPtr)malloc(sizeof(struct CompressedMatrix));
	resultPtr->columns = paraColumns;
	resultPtr->rows = paraRows;
	resultPtr->numElements = paraElements;
	resultPtr->elements = (TriplePtr)malloc(paraElements * sizeof(struct Triple));
	
	for (int i  = 0; i < paraElements; i++) {
		resultPtr->elements[i].i = paraData[i][0];
		resultPtr->elements[i].j = paraData[i][1];
		resultPtr->elements[i].e = paraData[i][2];
	}//Of for i.
	
	return resultPtr;
} 

/**
 * Print the compressed matrix.
 */
void printCompressedMatrix(CompressedMatrixPtr paraPtr) {
	for (int i = 0; i < paraPtr->numElements; i++) {
		printf("(%d, %d): %d\n", paraPtr->elements[i].i, paraPtr->elements[i].j, paraPtr->elements[i].e);
	}//Of for i
}

/**
 * Transpose a compressed matrix.
 */
 
CompressedMatrixPtr transposeCompressedMatrix(CompressedMatrixPtr paraPtr) {
	//Step 1. 建立记录数组
	int *tempColumnCounts = (int*)malloc(paraPtr->columns * sizeof(int));//记录每一列所拥有的数据个数。 
	int *tempOffsets = (int*)malloc(paraPtr->columns * sizeof(int));//记录列交换后新二维数组的位置 
	//初始化
	for (int i = 0; i < paraPtr->columns; i++) {
		tempColumnCounts[i] = 0;//一开始全为 0 
	}
	
	//初始化新数组
	CompressedMatrixPtr resultPtr = (CompressedMatrixPtr)malloc(sizeof(struct CompressedMatrix));
	resultPtr->rows = paraPtr->columns;
	resultPtr->columns = paraPtr->rows;
	resultPtr->numElements = paraPtr->numElements;
	resultPtr->elements = (TriplePtr)malloc(paraPtr->numElements * sizeof(struct Triple));
	
	//Step 2.扫描数组
	for (int i = 0; i < paraPtr->numElements; i++) {
		tempColumnCounts[paraPtr->elements[i].j]++;
	} 
	
	//Step 3.初始化offset 
	tempOffsets[0] = 0;
	for(int i = 1; i < paraPtr->columns; i++) {
		tempOffsets[i] = tempOffsets[i - 1] + tempColumnCounts[i - 1];
	}
	
	//Step 4.填入
	int tempPosition, tempColumn;
	for (int i = 0; i < paraPtr->numElements; i++) {
		tempColumn = paraPtr->elements[i].j;
		tempPosition = tempOffsets[tempColumn];//给转前的列数,转化为其在之后的行的数列 
		//交换
		resultPtr->elements[tempPosition].i = paraPtr->elements[i].j;
		resultPtr->elements[tempPosition].j = paraPtr->elements[i].i;
		resultPtr->elements[tempPosition].e = paraPtr->elements[i].e;
		 
		tempOffsets[tempColumn]++;
	} //Of for i;
	
	return resultPtr; 
}

/*
 ** test
 */
 
void compressedMatrixTest(){
	printf("--- compressedMatrixTest begins ----\n");
	CompressedMatrixPtr tempPtr1, tempPtr2;
	int tempElements;
	
	//建立二维数组-动态.
	tempElements = 4;
	int** tempMatrix1 = (int**)malloc(tempElements * sizeof(int*));
	for (int i = 0; i < tempElements; i++) {
		tempMatrix1[i] = (int*)malloc(3 * sizeof(int));
	}
	
	//初始化
	int tempMatrix2[4][3] = {{0, 0, 2}, {0, 2, 3}, {2, 0, 5}, {2, 1, 6}};
	//给动态数组赋值 
	for (int i = 0; i < tempElements; i++) {
		for (int j = 0; j < 3; j++) {
			tempMatrix1[i][j] = tempMatrix2[i][j]; 
		}
	}
	tempPtr1 = initCompressedMatrix(2, 3, 4, tempMatrix1); 
	printf("After initialization \n");
	printCompressedMatrix(tempPtr1);
	
	tempPtr2 = transposeCompressedMatrix(tempPtr1);
	printf("After traspose. \n");
	printCompressedMatrix(tempPtr2);
	
	printf("--- compressedMatrixTest ends ----\n");
}

int countValuableElement(TwoDArrayPtr paraPtr) {
	int cnt = 0;
	for (int i = 0; i < paraPtr->rows; i++) {
		for (int j = 0; j < paraPtr->columns; j++) {
			if (paraPtr->elements[i][j] != 0) {
				cnt++;
			}
		}
	}
	return cnt;
}
 
int** exchangeCompressed(TwoDArrayPtr paraPtr) {
	int** resultArray;

	resultArray = (int**)malloc(countValuableElement(paraPtr) * sizeof(int*));
	for (int i = 0; i < countValuableElement(paraPtr); i++) {
		resultArray[i] = (int*)malloc(3 * sizeof(int));
	}
	
	int k = 0;
	for (int i = 0; i < paraPtr->rows; i++) {
		for (int j = 0; j < paraPtr->columns; j++) {
			if (paraPtr->elements[i][j] != 0) {
				resultArray[k][0] = i;
				resultArray[k][1] = j;
				resultArray[k][2] = paraPtr->elements[i][j];
				k++;
			}
		}
	}
	return resultArray;	
}

TwoDArrayPtr returnCompressed(CompressedMatrixPtr paraPtr) {
	TwoDArrayPtr resultArray = initTwoDArray(paraPtr->rows, paraPtr->columns);
	
	int k = 0;
	for (int i = 0; i < paraPtr->rows; i++) {
		for (int j = 0; j < paraPtr->columns; j++) {
			if (paraPtr->elements[k].i == i && paraPtr->elements[k].j == j) {
				resultArray->elements[i][j] = paraPtr->elements[k].e;
				k++;
			} else {
				resultArray->elements[i][j] = 0;
			}
			
		}
	}
	return resultArray;
}

void test() {
	printf("---- test begins ----\n");
	TwoDArrayPtr tempPtr = initTwoDArray(3, 3);
	//稀疏数组初始化
	for (int i = 0; i < 3; i++) {
		for(int j = 0; j < 3; j++) {
			if (i == 0 && j == 0) {
				tempPtr->elements[i][j] = 2;
			} else if (i == 0 && j == 2) {
				tempPtr->elements[i][j] = 3;
			} else if (i == 2 && j == 0) {
				tempPtr->elements[i][j] = 5;
			} else if (i == 2 && j == 1) {
				tempPtr->elements[i][j] = 6;
			} else {
				tempPtr->elements[i][j] = 0;
			}
		}
	}
	
	printf("after init array.\n");
	printTwoDArray(tempPtr);
	
	//压缩
	int** array = exchangeCompressed(tempPtr);
	CompressedMatrixPtr tempCompressedPtr = initCompressedMatrix(tempPtr->rows, tempPtr->columns, countValuableElement(tempPtr), array);
	printf("After exchange.\n");
	printCompressedMatrix(tempCompressedPtr);
	
	//转置 
	CompressedMatrixPtr tempCompressedPtr2 = transposeCompressedMatrix(tempCompressedPtr);
	printf("After transpose.\n");
	printCompressedMatrix(tempCompressedPtr2);
	
	//返回稀疏函数 
	TwoDArrayPtr tempDAPtr =  returnCompressed(tempCompressedPtr2);
	printf("After retrun.\n");
	printTwoDArray(tempDAPtr);
	printf("---- test ends ----\n");
}
int main(void){
	compressedMatrixTest();
	test();
	return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值