数据结构实验四_二维数组基本操作的编程实现(C语言)

一、实验题目

二维数组基本操作的编程实现

二、题目要求

二维数组基本操作的编程实现,掌握数组的建立、读取数据、压缩存储等基本操作的编程实现,存储结构可以在顺序结构或链接结构中任选,也可以全部实现。也鼓励学生利用基本操作进行一些应用的程序设计。

三、运行结果

数据结构实验四_二维数组基本操作的编程实现(C语言)_第1张图片
数据结构实验四_二维数组基本操作的编程实现(C语言)_第2张图片

四、程序基本功能

1、矩阵生成

对于矩阵的生成,我采用了两种方式,第一种为随机生成,第二种为文件导入,其实之前我打算加入第三种人工输入的,我认为文件导入其实就包括了人工输入,所以放弃了这种方法。

(1)随机生成矩阵

函数名:arraycreate1()
描述:随机生成一个1x1—20x20的矩阵,并且非零元大约为总数的20%。
入口参数:无
出口参数:无
说明:函数执行之后,我首先随机生成了随机行row和随机列col,然后确定存储随机矩阵大小的二维数组,接着控制非零元的个数count在总数的20%左右。然后初始化row*col二维数组全为0,通过一个for循环随机生成一个数据,该数据的十位存为行rowc,该数据的个位存为列colc,然后为二维数组array[rowc][colc]随机赋值。部分重要代码如下:

	row=rand()%20+1;
	col=rand()%20+1;
	int data[row*col/5];
	do
	{
		srand(time(NULL)); //避免每次产生相同的随机数
		if(row*col/5==0)   //行数*列数<5
		{
			count=1;
		}
		else
		count=rand()%(row*col/5); //非零数的个数 
	}while(count<(row*col/5-3)); 
	for(i=0;i<row;i++)
	for(j=0;j<col;j++)
	{
		array[i][j]=0;		//数组初始化为0 
	}
	for(i=0;i<count;i++)	//随机为count个数赋值 
	{
		data[i]=rand()%100;
		rowc=data[i]/10;
		colc=data[i]%10;
		do
		{
			array[rowc][colc]=rand()%100;	
		}while(array[rowc][colc]<10);
	}
	printf("随机%dx%d矩阵已生成!\n",row,col);

(2)文件导入矩阵

函数名:arraycreate2()
描述:从文件导入一个1x1—20x20的矩阵。
入口参数:无
出口参数:无
说明:首先在“文件导入矩阵数据.txt”文件中输入符合规格的矩阵。先判断此文件是否存在,不存在即退出,否则开始读取数据,进入while循环,当文件读取结束时结束循环。While循环中读入字符ch,判断字符ch是否是空格或者回车,如果是空格j++,如果是回车i++。用i,j最终的值确定文件中的行列数。再次读取文件,确定行列数之后,用fscanf()函数读取数据,录入所在的行列。最后关闭文件。部分重要代码如下:

	if((fp=fopen("文件导入矩阵数据.txt","r"))==NULL)
	{
		printf("文件打开失败!\n");
		exit(0);
	}
    while (!feof(fp))       
	{ 
		ch=fgetc(fp);
	    if(ch==' ')  
		{
    		j++;
    		continue;
		}
	    if(ch=='\n')
		{
	    	i++;
	     	continue;
		}
	}
	row=i+1;
	col=j/(i+1);
	fp=fopen("文件导入矩阵数据.txt", "r");
	for(i=0;i<row;i++)
	for(j=0;j<col;j++)
	{
		fscanf(fp,"%d",&array[i][j]);
	}
	printf("\n矩阵导入完成!\n");
	fclose(fp);

文件导入矩阵数据.txt

 1 1 1 0 0
 2 2 2 0 0
 3 3 3 0 0
 4 4 4 0 0

(3)矩阵压缩三元组

函数名:arraycompress()
描述:将矩阵中的非零元压缩成三元组。
入口参数:无
出口参数:无
说明:由于行row,列col均是全局变量,所以开始定义一个rowcol大小的结构体数组(struct compress data[rowcol]),通过两个for循环判断当array[i][j]==0时将i赋值给data[count+1].row,将j赋值给data[count+1].col,array[i][j]赋值给data[count+1].number。每添加一组数据count++。然后把行row,列col,count赋值给data[0],即矩阵压缩三元组成功。部分重要代码如下:

	for(i=0;i<row;i++)
	{
		for(j=0;j<col;j++)
		{
			if(array[i][j]!=0)
			{
			data[count+1].row=i;
			data[count+1].col=j;
			data[count+1].number=array[i][j];
			count++;
			}
		}
	}
	data[0].row=row;
	data[0].col=col;
	data[0].number=count;

2、三元组生成

三元组生成有两种方式,随机生成三元组和文件导入三元组.

(1)随机生成三元组

函数名:groupcreate1()
描述: 随机生成一个三元组
入口参数:无
出口参数:无
说明:首先随机生成矩阵的行row,列col,和非零元的个数count,并且非零元的个数限制在总数的20%,将行、非零元的个数存在data[0]中。然后定义一个value[count+1],随机生成count个0- -(row-1)*(col-1)大小的数,为了让三元组中数据是有序的,通过冒泡法将value这个一维数组中我的数据排序,之后将每个数的十位作为该组数据的行,个位数作为列,之中判断该行该列是否重复,通过一个判断重复函数来判断,然后随机为该行该列的非零元随机赋值。部分重要代码如下:

	row=rand()%10+1;
	col=rand()%10+1;
	count=rand()%((row*col+1)/5);
	int value[count+1];
	struct compress data[count+1];
	data[0].row=row;
	data[0].col=col;
	data[0].number=count;
	for(i=0;i<count;i++)
	{	
		value[i]=rand()%((row-1)*(col-1)-9)+1;
	}
	groupsort(count,value); //三元组排序
	for(i=1;i<=count;i++)
	{
		do
		{
			data[i].row=value[i-1]/10;
			data[i].col=value[i-1]%10;
		}while(testrepeat(i,data));	//判断是否重复
		data[i].number=rand()%100;
	}
	printf("随机三元组已生成!\n");

(2)文件生成三元组

函数名:groupcreate2()
描述: 通过文件导入一个三元组
入口参数:无
出口参数:无
说明:文件导入还存在Bug
数据结构实验四_二维数组基本操作的编程实现(C语言)_第3张图片

(3)三元组解压为矩阵

函数名:groupcreate2()
描述: 把三元组解压为矩阵
入口参数:无
出口参数:无
说明:因为我是把这个函数插入在生成三元组中,所以矩阵的行列数已经知道,首先直接通过两个for循环对矩阵初始化为0,然后再通过两个for循环把三元组中的数据赋值给矩阵中所在的位置。部分重要代码如下:

	for(i=0;i<row;i++)
	for(j=0;j<col;j++)  //矩阵初始化为0
	{
		array[i][j]=0;
	}
	for(i=1;i<=count;i++)
	{
		do
		{
			data[i].row=value[i-1]/10;
			data[i].col=value[i-1]%10;
		}while(testrepeat(i,data));	
		data[i].number=rand()%100;
		array[data[i].row][data[i].col]=data[i].number; //赋值
	}
	printf("随机三元组已生成!\n");
	for(i=0;i<=count;i++)
	{
		printf(" %d %d %d\n",data[i].row,data[i].col,data[i].number);
		fprintf(fp," %d %d %d\n",data[i].row,data[i].col,data[i].number);
	}
	printf("\n三元组解压矩阵成功!\n");

五、源码

#include
#include
#include
#include
#define max 30
void showmenu();//菜单显示
void processmenu();//菜单控制
void arraycreate(); //矩阵生成
void arraycreate1();//随机生成矩阵
void arraycreate2();//文件导入矩阵
void groupcreate(); //三元组生成
void groupcreate1();//随机生成三元组
void groupcreate2();//文件导入三元组
void arraycompress(); //矩阵压缩
void showarray();  //显示矩阵
int testrepeat(int k,struct compress *p); //判断三元组是否重复
int groupsort(int k,int *p);   //三元组排序
int array[max][max];//矩阵
int row=0,col=0; //矩阵行,列
struct compress {
	int row; //行
	int col; //列
	int number; //数据
};
int main() {
	system("color f0");//背景白色
	while(1) {
		showmenu();
		processmenu();
		system("pause");
		system("cls");
	}
}
void showmenu() {
	puts("~~~~~~~~~~~~~~~~~~~~~~~~");
	puts("\t  二维数组基本操作的编程实现");
	puts("\t\t操作软件:dev c++");
	puts("~~~~~~~~~~~~~~~~~~~~~~~~");
	puts("~~~\t\t1、矩阵输入\t\t~~~~");
	puts("~~~\t\t2、三元组输入\t\t~~~~");
	puts("~~~\t\t0、退出程序\t\t~~~~");
	puts("~~~~~~~~~~~~~~~~~~~~~~~~");
	puts("");
	printf("请输入您的选择:");
}
void processmenu() {
	int menuchoice;//菜单选择
	scanf("%d",&menuchoice);
	switch(menuchoice) {
		case 1:
			arraycreate();//矩阵生成
			break;
		case 2:
			groupcreate(); //三元组生成
			break;
		case 0:
			puts("\n~~~~~~~~~~~~~~~~~~~~~~~~");
			puts("\t\t欢迎下次再用!");
			puts("~~~~~~~~~~~~~~~~~~~~~~~~\n");
			exit(0);
		default :
			printf("输入错误!请重新输入...\n");
	}
}
void arraycreate() {	//矩阵生成
	int choose;
	printf("  1、随机生成\n");
	printf("  2、文件导入\n");
	printf("请选择输入方式:");
	scanf("%d",&choose);
	switch(choose) {
		case 1:
			arraycreate1(); //随机生成矩阵
			break;
		case 2:
			arraycreate2(); //文件导入矩阵
			break;
		default :
			printf("输入错误!\n");
	}
	showarray(); //显示矩阵
	arraycompress(); //压缩矩阵为三元组
}
void arraycreate1() { //随机生成矩阵
	int i,j;
	int count;
	int rowc,colc;
	row=rand()%20+1;
	col=rand()%20+1;
	int data[row*col/5];
	do {
		srand(time(NULL));
		if(row*col/5==0) {
			count=1;
		} else
			count=rand()%(row*col/5); //非零数的个数
	} while(count<(row*col/5-3));
	for(i=0; i<row; i++)
		for(j=0; j<col; j++) {
			array[i][j]=0;		//数组初始化为0
		}
	for(i=0; i<count; i++) {	//随机为count个数赋值
		data[i]=rand()%100;
		rowc=data[i]/10;
		colc=data[i]%10;
		do {
			array[rowc][colc]=rand()%100;
		} while(array[rowc][colc]<10);
	}
	printf("随机%dx%d矩阵已生成!\n",row,col);
}
void arraycreate2() { //文件导入矩阵
	FILE *fp;
	char ch;
	int i=0,j=0;
	if((fp=fopen("文件导入矩阵数据.txt","r"))==NULL) {
		printf("文件打开失败!\n");
		exit(0);
	}
	while (!feof(fp)) {
		ch=fgetc(fp);
		if(ch==' ') {
			j++;
			continue;
		}
		if(ch=='\n') {
			i++;
			continue;
		}
	}
	row=i+1;
	col=j/(i+1);
	fp=fopen("文件导入矩阵数据.txt", "r");
	for(i=0; i<row; i++)
		for(j=0; j<col; j++) {
			fscanf(fp,"%d",&array[i][j]);
		}
	printf("\n矩阵导入完成!\n");
	fclose(fp);
}
void showarray() { //显示矩阵
	FILE *fp;
	if((fp=fopen("矩阵显示后数据.txt","w"))==NULL) {
		printf("文件打开失败!\n");
		exit(0);
	}
	int i,j;
	for(i=0; i<row; i++) {
		for(j=0; j<col; j++) {
			printf("[%d]",array[i][j]);
			fprintf(fp," %d",array[i][j]);
		}
		if(i==row-1)
			break;
		else {
			printf("\n");
			fprintf(fp,"\n");
		}
	}
	printf("\n");
	fclose(fp);
}
void arraycompress() { //矩阵压缩
	int i,j;
	int count=0;
	struct compress data[row*col];
	FILE *fp;
	if((fp=fopen("矩阵压缩后三元组数据.txt","w"))==NULL) {
		printf("文件打开失败!\n");
		exit(0);
	}
	for(i=0; i<row; i++) {
		for(j=0; j<col; j++) {
			if(array[i][j]!=0) {
				data[count+1].row=i;
				data[count+1].col=j;
				data[count+1].number=array[i][j];
				count++;
			}
		}
	}
	data[0].row=row;
	data[0].col=col;
	data[0].number=count;
	printf("\n矩阵压缩三元组成功!\n");
	printf("r c v\n");
	for(i=0; i<=count; i++) {
		printf("%d %d %d \n",data[i].row,data[i].col,data[i].number);
		fprintf(fp,"%d %d %d \n",data[i].row,data[i].col,data[i].number);
	}
	fclose(fp);
}
void groupcreate() { //三元组生成
	int choose;
	printf("  1、随机生成\n");
	printf("  2、文件导入\n");
	printf("请选择输入方式:");
	scanf("%d",&choose);
	switch(choose) {
		case 1:
			groupcreate1(); //随机生成三元组
			break;
		case 2:
			groupcreate2(); //文件导入三元组
			break;
		default :
			printf("输入错误!\n");
	}
}
void groupcreate1() { //随机生成三元组
	FILE *fp;
	if((fp=fopen("随机生成三元组数据.txt","w"))==NULL) {
		printf("文件读取失败!\n");
		exit(0);
	}
	int i,j;
	int count;
	srand(time(NULL));
	row=rand()%10+1;
	col=rand()%10+1;
	count=rand()%((row*col+1)/5);
	int value[count+1];
	struct compress data[count+1];
	data[0].row=row;
	data[0].col=col;
	data[0].number=count;

	for(i=0; i<count; i++) {
		value[i]=rand()%((row-1)*(col-1)-9)+1;
	}

	groupsort(count,value); //三元组排序
	for(i=0; i<row; i++)
		for(j=0; j<col; j++) {
			array[i][j]=0;
		}
	for(i=1; i<=count; i++) {
		do {
			data[i].row=value[i-1]/10;
			data[i].col=value[i-1]%10;
		} while(testrepeat(i,data));

		data[i].number=rand()%100;
		array[data[i].row][data[i].col]=data[i].number;
	}
	printf("随机三元组已生成!\n");
	for(i=0; i<=count; i++) {
		printf(" %d %d %d\n",data[i].row,data[i].col,data[i].number);
		fprintf(fp," %d %d %d\n",data[i].row,data[i].col,data[i].number);
	}
	printf("\n三元组解压矩阵成功!\n");
	fclose(fp);
	showarray();
}
void groupcreate2() { //文件导入三元组
	FILE *fp;
	if((fp=fopen("文件导入三元组数据.txt","r"))==NULL) {
		printf("文件读取失败!\n");
		exit(0);
	}
	int ch;
	int i,j;
	int rowc=0;
	while(!feof(fp)) {
		ch=fgetc(fp);
		if(ch==' ') {
			j++;
			continue;
		}
		if(ch=='\n') {
			i++;
			continue;
		}
	}
	rowc=i+1;
	struct compress data[rowc];
	fp=fopen("文件导入三元组数据.txt","r");
	for(i=0; i<rowc; i++) {
		fscanf(fp,"%d",&data[i].row);
		fscanf(fp,"%d",&data[i].col);
		fscanf(fp,"%d",&data[i].number);
		array[data[i].row][data[i].col]=data[i].number;
	}

	printf("文件三元组已生成!\n");

	for(i=0; i<rowc; i++) {
		printf(" %d %d %d\n",data[i].row,data[i].col,data[i].number);
		fprintf(fp," %d %d %d\n",data[i].row,data[i].col,data[i].number);
	}
	printf("\n三元组解压矩阵成功!\n");
	fclose(fp);
	showarray();
}
int testrepeat(int k,struct compress *p) { //判断三元组是否重复
	for(int i=0; i<k; i++)
		if(p[k].row==p[i].row&&p[k].col==p[i].col)
			return 1;
	return 0;
}
int groupsort(int k,int *p) { //三元组排序
	int min;
	for(int i=0; i<k; i++) {
		for(int j=i+1; j<k; j++) {
			if(p[j]<p[i]) {
				min=p[j];
				p[j]=p[i];
				p[i]=min;
			}
		}
	}
}

你可能感兴趣的:(数据结构)