目录
一、介绍
当一个数组中大部分的元素为0或相同时,可以使用稀疏数组来保存这个数组。
二、具体操作
1.记录数据几行几列,有多少个有效数据。
2.将有效元素的行、列、值记录在一个数组中,达到压缩的效果。如下图:
原始数组 稀疏数组
0 0 0 22 0 0 15 6 7 8
0 11 0 0 0 17 0 0 3 22
0 0 0 -6 0 0 0 =》 0 6 15
0 0 0 0 0 39 0 1 1 11
91 0 0 0 0 0 0 1 5 17
0 0 28 0 0 0 0 2 3 -6
3 5 39
4 0 91
5 2 28
很简单就是将一维数组或二维数组压缩成一个二维数组,这个二维数组记录了原始数组有多少行、多少列,有多少个有效值。当然这是稀疏数组简单定义,在具体实现可以根据业务灵活变换。如你想让无效数组变成1为非0。
三、实现
1.压缩关键代码:
首先遍历原始数组,得到有效数据的个数sum,然后根据sum定义出稀疏数组sparse,稀疏数组第一行记录和原始数组行数、列数、以及有效值个数。然后遍历原始数组,使用稀疏数组记录其有效值。
int sum = 0;
for (int i=0;i<7;i++)
{
for(int j=0;j<7;j++)
{
if (arr[i][j] != 0)
{
sum++;
}
}
}
int sparse[sum+1][3];
sparse[0][0] = 7;
sparse[0][1] = 7;
sparse[0][2] = sum;
int count=1;
for (int i=0;i<7;i++)
{
for(int j=0;j<7;j++)
{
if (arr[i][j] != 0)
{
sparse[count][0]=i;
sparse[count][1]=j;
sparse[count++][2]=arr[i][j];
}
}
}
2.解压关键代码:
再稀疏数组的第一行拿到原始数组的行、列、以及有效值的个数,然后定义出原始数据,然后将原始数组全部元素先初始化为0,然后根据稀疏数组,还原原始数组相应位置的值。
int row,col,size;
row = sparse[0][0];
col = sparse[0][1];
size = sparse[0][2];
int arr[row][col];
initArr(&arr[0][0],row,col);
for (int i=1;i<row0;i++)
{
arr[arr[i][0]][arr[i][1]] = arr[i][2];
}
3.将稀疏数组从内存写入到文件:
首先我们写入将稀疏数组大小写入到文件开始位置,然后将稀疏数组其他数据按sizeof(int)大小一次写入文件。
void writeToFile(int (*sparse)[3],int rows)
{
FILE *fp = NULL;
fp = fopen("./file","ab+");
if (fp == NULL)
{
puts("open file failed");
exit(-1);
}
int size = rows*3;
//printf("size=%d\n",size);
fwrite(&size,sizeof(int),1,fp);
fwrite(&sparse[0],sizeof(int),size,fp);
fclose(fp);
}
4.从文件中将稀疏数组读到内存:
在读取文件时,我们先读int大小的数据,这就是size。然后根据size我们在堆上分配内存。最后将数据读到刚刚分配的内存中。数据读出来之后一切就好说了。
int* readFromFile(int *row)
{
FILE *fp = NULL;
fp = fopen("./file","rb+");
if (fp == NULL)
{
puts("open file failed");
exit(-1);
}
int size;
fread(&size,sizeof(int),1,fp);
//printf("size = %d\n",size);
int *arr = (int*)malloc(size*sizeof(int));
if (arr == NULL)
{
puts("malloc failed");
exit(-1);
}
fread(arr,sizeof(int),size,fp);
*row = size / 3;
fclose(fp);
return arr;
}
四、全体代码
直接gcc main.c && ./a.out
#include<stdio.h>
#include <stdlib.h>
#include <string.h>
void printArr(int *arr,int row,int col);
void initArr(int *arr,int row,int col);
void writeToFile(int (*sparse)[3],int rows);
int* readFromFile(int *row);
void archiver();
void extract();
int arr[7][7]={
{0,1,0,0,0,0,0},
{0,2,0,0,0,0,0},
{0,0,4,0,0,0,0},
{0,0,0,5,0,0,0},
{0,0,0,0,1,0,0},
{0,0,0,0,0,0,19},
{0,0,0,0,0,0,0},
};
void archiver(){
puts("原始数组:");
printArr(arr[0],7,7);
int sum = 0;
for (int i=0;i<7;i++)
{
for(int j=0;j<7;j++)
{
if (arr[i][j] != 0)
{
sum++;
}
}
}
int sparse[sum+1][3];
sparse[0][0] = 7;
sparse[0][1] = 7;
sparse[0][2] = sum;
int count=1;
for (int i=0;i<7;i++)
{
for(int j=0;j<7;j++)
{
if (arr[i][j] != 0)
{
sparse[count][0]=i;
sparse[count][1]=j;
sparse[count++][2]=arr[i][j];
}
}
}
puts("稀疏数组如下:");
printArr(sparse[0],sum+1,3);
writeToFile(sparse,sum+1);
}
void extract(){
int row0;
int *p = readFromFile(&row0);
int sparse[row0][3];
puts("在文件中读到的稀疏数组:");
printArr(p,row0,3);
memcpy(&sparse[0],p,sizeof(int)*row0*3);
free(p);
int row,col,size;
row = sparse[0][0];
col = sparse[0][1];
size = sparse[0][2];
int arr[row][col];
initArr(&arr[0][0],row,col);
for (int i=1;i<row0;i++)
{
arr[sparse[i][0]][sparse[i][1]] = sparse[i][2];
}
puts("还原的数组如下:");
printArr(arr[0],row,col);
}
int main(){
archiver();
extract();
return 0;
}
void printArr(int *arr,int row,int col)
{
for (int i=0;i<row;i++)
{
for(int j=0;j<col;j++)
{
printf("%d ",*(arr + i*col +j));
}
printf("\n");
}
}
void initArr(int *arr,int row,int col)
{
for (int i=0;i<row;i++)
{
for(int j=0;j<col;j++)
{
*(arr + i*col +j) = 0;
}
}
}
void writeToFile(int (*sparse)[3],int rows)
{
FILE *fp = NULL;
fp = fopen("./file","ab+");
if (fp == NULL)
{
puts("open file failed");
exit(-1);
}
int size = rows*3;
//printf("size=%d\n",size);
fwrite(&size,sizeof(int),1,fp);
fwrite(&sparse[0],sizeof(int),size,fp);
fclose(fp);
}
int* readFromFile(int *row)
{
FILE *fp = NULL;
fp = fopen("./file","rb+");
if (fp == NULL)
{
puts("open file failed");
exit(-1);
}
int size;
fread(&size,sizeof(int),1,fp);
//printf("size = %d\n",size);
int *arr = (int*)malloc(size*sizeof(int));
if (arr == NULL)
{
puts("malloc failed");
exit(-1);
}
fread(arr,sizeof(int),size,fp);
*row = size / 3;
fclose(fp);
return arr;
}