精华内容
下载资源
问答
  • 压缩矩阵

    千次阅读 2020-02-25 10:51:51
    压缩矩阵:指为多个值相同的元素只分配一个存储空间,对零元素不分配存储空间 特殊矩阵:指具有许多相同矩阵元素或零元素,并且这些相同矩阵元素或零元素的分配有一定规律性 1、对称矩阵 对称矩阵:矩阵每个元素都...
    • 压缩矩阵:指为多个值相同的元素只分配一个存储空间,对零元素不分配存储空间
    • 特殊矩阵:指具有许多相同矩阵元素或零元素,并且这些相同矩阵元素或零元素的分配有一定规律性

    1、对称矩阵

    对称矩阵:矩阵每个元素都有aij=aji
    在这里插入图片描述
    压缩方法:将对称矩阵存放到一维数组B[n(n+1)/2]中,第一行先存,依次向下,只存放主对角线和下三角线的元素

    元素aij在数组B中的下标k=1+2+…+(i-1)+j-1 (这里的i,j都是从1开始的)
    在这里插入图片描述

    2、三角矩阵

    三角矩阵:上三角或者下三角都是同一常量
    在这里插入图片描述
    压缩方法:将三角矩阵压缩到一维数组B[n(n+1)/2+1]中,按行优先,数组B最后一个空间存放常量C
    在这里插入图片描述
    元素aij在数组B中的下标k (ij都是从1开始)
    下三角矩阵:
    在这里插入图片描述
    上三角矩阵:
    在这里插入图片描述

    3、三对角矩阵

    三对角矩阵:只有以主对角线为中心的3条对角线为不全为0,其他的都是0

    在这里插入图片描述
    压缩方式:将3条对角线上的元素按行优先存放一维数组B中

    元素aij在数组B中的下标k (ij都是从1开始)
    在这里插入图片描述
    知道k,如何求i,j?
    在这里插入图片描述

    4、稀疏矩阵

    稀疏矩阵:矩阵里0元素非常多
    在这里插入图片描述
    压缩方法:仅存储非零元素,存储非零元素的行值、列值、非零元素值,按行优先

    i、j从0开始
    在这里插入图片描述
    缺点:稀疏矩阵压缩存储后便失去了随机存取特性(前面的k还可以根据i、j来求)

    展开全文
  • 实验6、压缩矩阵的2种转置运算 (1)实验目的 通过该实验,让学生理解矩阵压缩存储的概念、方法等相关知识,掌握用三元组表的方式如何进行矩阵的压缩存储,并在此基础上进行转置操作,理解转置和快速转置两种矩阵...

    实验6、压缩矩阵的2种转置运算

    (1)实验目的
    通过该实验,让学生理解矩阵压缩存储的概念、方法等相关知识,掌握用三元组表的方式如何进行矩阵的压缩存储,并在此基础上进行转置操作,理解转置和快速转置两种矩阵转置算法的思想。
    (2)实验内容
    用三元组表压缩存储矩阵,实现创建矩阵、显示以及教材中介绍的两种转置算法。
    (3)参考界面
    1.创建矩阵
    2.销毁矩阵
    3.输出矩阵
    4.转置矩阵
    5.快速转置矩阵
    具体要求:请认真查看测试用例
    (4)验收/测试用例

    • 创建矩阵:

    注意:检查非零元素个数是否小于等于行数乘列数;检查是否能拦截元素下标重复输入;检查是否能控制输入的非零元素的下标是递增的(即按照行序输入,先输入小的下标,再输入较大的下标)。
    注意:输入的过程中如果有一个输入错了,不要让用户从头再把所有的输入一次,只需把刚才输入错误的,重新输入正确即可。

    1. 输入:4(行数) 4(列数) 25(非零元个数),会提示:输入错误,非零元素个数要小于等于行数乘列数,请从新输入。
    2. 输入:4(行数) 4(列数) 5(非零元个数)
    3. 先输入:(1,1,1) (2,3,2)
    4. 再输入(2,3,6),会提示:输入错误,输入的下标重复,请重新输入!
    5. 再输入(1,1,6),会提示:输入错误,输入的下标重复,请重新输入!
    6. 继续输入(3,1,3) (3,4,5)
    7. 再输入(3,2,9),会提示:输入错误,下标输入时要递增输入,请重新输入!
    8. 再输入(2,3,8),会提示:输入错误,下标输入时要递增输入,请重新输入!
    9. 最后输入(4,2,4)
    • 显示:

    屏幕上输出

             1  0  0  0
             0  0  2  0
             3  0  0  5
             0  4  0  0
    
    • 转置:
      屏幕上输出
             1  0  3  0
             0  0  0  4
             0  2  0  0
             0  0  5  0
    

    效果图
    在这里插入图片描述

    代码

    #include <stdio.h>
    #include <stdlib.h>
    
    #define OK 1
    #define ERROR -1
    #define OVERFLOW -2
    //--------------压缩矩阵的顺序存储表示-------------
    typedef int status;     //status是函数的类型,其值是函数结果状态代码。
    typedef int Elem;       //自定
    
    #define MAXSIZE 100     //非零元个数的最大值为100
    
    typedef struct {
    	/*定义矩阵中一个非零元素的结构
    	    i为行下标,j为列下标,e为该元素的值 
    	*/
    	int i,j;
    	Elem e;	
    }Triple; 
    
    typedef struct {
    	/*定义整个矩阵的结构 
    	     data为压缩矩阵,data[0]未被使用 
    	     mu为行数,nu为列数,tu为非零元个数 
    	*/
    	Triple data[MAXSIZE+1];
    	int mu,nu,tu;
    }TMatrix; 
    
    //---------------基本操作的函数原型说明------------ 
    status CreateTMatrix(TMatrix &M);
           //创建矩阵 
    status DestoryTMatrix(TMatrix &M);       
           //销毁矩阵 
    status PrintTMatrix(TMatrix M);       
           //输出矩阵 
    status TransposeTMatrix(TMatrix M,TMatrix &T);
           //转置矩阵 
    status FastTransposeTMatrix(TMatrix M,TMatrix &T);
           //快速转置矩阵 
    //---------------主函数---------------------------- 
    int main() {
    	//初始化 
    	int i = 0;
    	TMatrix M ;
    	TMatrix T ;
    	
    	int choice;
    	while (1){
    		//菜单
    		printf("\t\t\t 1---创建矩阵\n");
    		printf("\t\t\t 2---销毁矩阵\n");
    		printf("\t\t\t 3---输出矩阵\n");
    		printf("\t\t\t 4---转置矩阵\n");
    		printf("\t\t\t 5---快速转置矩阵\n");	
    		printf("\t\t\t 退出,输入一个负数!");
    		printf("\n");
    		printf("\t\t----------------------------------------------\n");
    		printf("\n");
    		printf("请输入你需要的操作:\n");
    		//退出
    		scanf("%d",&choice);
    		if(choice<=0){
    			printf("已退出\n");
    			return 0;
    		} 
    		switch (choice){
    			case 1:
    				i = CreateTMatrix(M);
    				if(i == 1){
    					printf("创建成功\n");
    				}
    				break;
    			case 2:
    				i = DestoryTMatrix(M);
    				if(i == 1){
    					printf("销毁成功\n");
    				}
    				break;
    			case 3:
    				i = PrintTMatrix(M);				
    			 	break;
    			case 4:
    				printf("转置前\n");
    				i = PrintTMatrix(M);	
    				i = TransposeTMatrix(M,T);
    				printf("转置后\n");
    				i = PrintTMatrix(T);				
    			 	break;
    			case 5:
    				printf("转置前\n");
    				i = PrintTMatrix(M);
    				i = FastTransposeTMatrix(M,T);
    				printf("快速转置后\n");
    				i = PrintTMatrix(T);
    			 	break;
    			default:
    				printf("选择失败!请重新选择!\n");
    				break; 	 	 	 			
    		}
    		system("pause");   //请按任意键结束 
    		system("cls");     //清屏 
    	}
    	return 0;
    }
    //---------------基本操作的算法描述----------------
    status CreateTMatrix(TMatrix &M){
    	//创建矩阵 
    	M.data[0].i = M.data[0].j = 0;//方便比较 
    	int num = 1;
    
    	while(1){
    		//检查非零元素个数是否小于等于行数乘列数;
    		printf("请输入矩阵的行数,列数和非零元个数:");
    		scanf("%d%d%d",&M.mu,&M.nu,&M.tu);
    		if(M.nu*M.mu < M.tu){
    		    printf("输入错误,非零元素个数要小于等于行数乘列数,请从新输入。\n");
    		    continue;
    		}else{
    			break;
    		}
    	}
    	//输入数据 
    	while(num <= M.tu){
    		printf("请输入第%d个元素的行下标,列下标和元素值(按行序输入,且下标递增):",num);
    		scanf("%d%d%d",&M.data[num].i,&M.data[num].j,&M.data[num].e);	
    		if(M.data[num].i < M.data[num-1].i){
    			//行下标递减,报错 
    			printf("该元素行下标输入错误,请重新输入\n");
    		}else if(M.data[num].i == M.data[num-1].i){
    			//行下标相等,则列下标不可小于或等于上一个元素的列下标 
    			if(M.data[num].j <= M.data[num-1].j || M.data[num].j > M.nu){
    				//列下标递减或重复,或者列下标超出列数范围,都报错 
    				printf("该元素列下标输入错误,请重新输入\n"); 
    			}else{
    				//列下标递增,输入成功 
    				num++; 
    			}
    		}else if(M.data[num].i > M.mu){
    			//行下标超出行数范围
    			printf("该元素行下标输入错误,请重新输入\n"); 
    		}else{
    			//行下标递增,则只需控制列下标不超纲即可 
    			if(M.data[num].j >=1 && M.data[num].j <=M.nu){
    				//输入成功 
    				num++;	
    			}else{
    				printf("该元素列下标输入错误,请重新输入\n"); 
    			} 
    		} 
    	}
    	return OK;
    }
    
    status DestoryTMatrix(TMatrix &M){
    	//销毁矩阵 
    	M.mu = 0;
    	M.nu = 0;
    	M.tu = 0;
    	return OK;
    }      
      
    status PrintTMatrix(TMatrix M){
    	//输出矩阵   
    	int num = 1;
    	for(int col = 1;col <= M.mu;col++){
    		for(int rol = 1;rol <= M.nu;rol++){
    			if(col == M.data[num].i && rol == M.data[num].j){
    				//输出数据 
    				printf("%d",M.data[num].e);
    				num++;				
    			}else{
    				printf("0");
    			}
    			printf("\t");
    			if(rol == M.nu){
    				//一列输出后换行 
    				printf("\n");
    			}
    		}
    	} 
    }       
             
    status TransposeTMatrix(TMatrix M,TMatrix &T){
    	//转置矩阵
    	int num = 1;	
    	T.mu = M.nu;
    	T.nu = M.mu;
    	T.tu = M.tu;
    	if(T.tu){
    		for(int col = 1;col <= M.nu; col++){
    			//每行 
    			for(int sum = 1;sum <= M.tu;sum++){
    				//遍历所有的数据 
    				if(M.data[sum].j == col){
    					T.data[num].i = M.data[sum].j;
    					T.data[num].j = M.data[sum].i;
    					T.data[num].e = M.data[sum].e; 
    					num++;
    				}
    			}
    		}
    	}
    	return OK;
    }
           
    status FastTransposeTMatrix(TMatrix M,TMatrix &T){
    	//快速转置矩阵
    	T.mu = M.nu;
    	T.nu = M.mu;
    	T.tu = M.tu;
    	int q = 0;
    	int col = 0;
    	int num[MAXSIZE + 1];
    	int cpot[MAXSIZE + 1];
    	for(int col = 1;col <= M.mu; col++){
    		//清空num 
    		num[col] = 0;
    	}
    	for(int t = 1;t <= M.tu; t++){
    		//求M中每一列含非零元个数
    		 num[M.data[t].j]++;
    	}
    	cpot[1] = 1;
    	for(int col = 2;col <= M.nu; col++){
    		//求第col列中第一个非零元在T.data中的序号 
    		cpot[col] = cpot[col - 1] + num[col - 1];
    	}
    	for(int p = 1;p <= M.tu; p++){
    		col = M.data[p].j;
    		q = cpot[col];
    		T.data[q].i = M.data[p].j;
    		T.data[q].j = M.data[p].i;
    		T.data[q].e = M.data[p].e;
    		cpot[col]++;
    	}
    	return OK;
    }
    
    

    号外
    在检验创建矩阵中的输入时,我发现了一个本实验要求中没有提及的一种更加极端的情况:输入的数据过靠后,导致后面的数据没有位置存储。就是说假设输入一个4行4列4个元素的矩阵时,若第3个数据输入的时候为(4,4,*),则最后一个数据将无法输入(极端情况)。我想到的想法便是在输入后再加一段判断,控制每一个输入的数据都可以使后面的数据有位置输入,当然这种情况的判断还需考虑所输入矩阵的列数,故没有在代码中实现,默认不会出现这种情况。
    有兴趣的可以去实现以下,也不难,奈何博主太懒
    ╮(╯▽╰)╭

    展开全文
  • 压缩矩阵乘法

    2020-06-29 21:38:01
    矩阵是一个二维平面的概念,而压缩矩阵就是要把这个平面进行压缩,即用一维数组来表示二维数组。 那应该怎样来表示二维数组?我们知道二维数组都有一个行列下标i和j,而一维数组只有一个下标k,我们只需要将k用i和j...

    试编写实现矩阵C = A X B 操作的函数。设矩阵A、矩阵B和矩阵C的行列维数均为n,并采用压缩存储结构,矩阵元素均为int型


    题目分析:

    矩阵是一个二维平面的概念,而压缩矩阵就是要把这个平面进行压缩,即用一维数组来表示二维数组。

    那应该怎样来表示二维数组?我们知道二维数组都有一个行列下标i和j,而一维数组只有一个下标k,我们只需要将k用i和j来表示,得到对应的关系式,就可以将矩阵存储到一维数组了

    对应的关系是这样的:

    img


    考点:

    k = i*n+j,k是一维数组的下标,i、j是二维数组的行、列

    1.二维矩阵和一维矩阵的一一对应关系
    2.矩阵的乘法法则以及代码实现


    代码实现:

    #include<stdio.h>
    #include<stdlib.h>
    /*输入数据创建矩阵,返回压缩后的矩阵(一维数组)*/
    int* input(int n)
    {
        int *arr = (int *)malloc(sizeof(int)*(n*n));
        printf("请输入 %d 个数:",n*n);
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
            {
                int number;
                scanf_s("%d", &number);     //从键盘获取数据
                arr[i*n + j] = number;      //将数据存储到一维数组相应位置上
            }
        printf("\n\n");
        return arr;      //返回一维数组
    }
    /*矩阵的乘法,返回一个一维数组,存放着压缩矩阵*/
    int *mul(int A[], int B[], int n)
    {
        int *C = (int *)malloc(sizeof(int)*(n*n));
        for (int i = 0; i < n*n; i++)         //因为矩阵乘法涉及到加和过程,所以得把C数组中全部置0
            C[i] = 0;
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                for (int k = 0; k < n; k++)
                {
                    C[i*n + j] += A[i*n + k] * B[k*n + j];     //矩阵乘法:C[i][j] += A[i][k]*B[k][j]
                }
            }
        }
        return C;         //返回计算好的一维数组
    }
    /*输出矩阵*/
    void output(int *arr, int n)
    {
        for (int i = 0; i < n*n; i++)
        {
            if (i % n == 0)   //换行
                printf("\n");
            printf("%5d", arr[i]);
        }
        printf("\n");
    }
    int main()
    {
        int n;
        printf("请输入矩阵的阶数:");
        scanf_s("%d", &n);
        int *A = (int *)malloc(sizeof(int)*(n*n));
        int *B = (int *)malloc(sizeof(int)*(n*n));
        int *C = (int *)malloc(sizeof(int)*(n*n));
        printf("创建矩阵A:\n\n");
        A = input(n);
        printf("创建矩阵B:\n\n");
        B = input(n);
        C = mul(A, B, n);
        printf("计算结果矩阵C如下:\n\n");
        output(C,n);
        system("pause");
        return 0;
    }
    

    运行结果:


    测试一

    img



    测试二

    img



    测试三

    img



    代码编译器:Visual Studio 2017
    ok,没问题

    展开全文
  • 实验6、压缩矩阵的2种转置运算 (1)实验目的 通过该实验,让学生理解矩阵压缩存储的概念、方法等相关知识,掌握用三元组表的方式如何进行矩阵的压缩存储, 并在此基础上进行转置操作,理解转置和快速转置两种矩阵...

    实验6、压缩矩阵的2种转置运算

    (1)实验目的

    通过该实验,让学生理解矩阵压缩存储的概念、方法等相关知识,掌握用三元组表的方式如何进行矩阵的压缩存储,

    并在此基础上进行转置操作,理解转置和快速转置两种矩阵转置算法的思想。

    (2)实验内容

    用三元组表压缩存储矩阵,实现创建矩阵、显示以及教材中介绍的两种转置算法。

    (3)参考界面

    1. 创建矩阵
    2. 销毁矩阵
    3. 输出矩阵
    4. 转置矩阵
    5. 快速转置矩阵

    具体要求:请认真查看测试用例

    (4)验收/测试用例

    创建矩阵:

    检查非零元素个数是否小于等于行数乘列数;检查是否能拦截元素下标重复输入;

    检查是否能控制输入的非零元素的下标是递增的(即按照行序输入,先输入小的下标,再输入较大的下标)。

    输入的过程中如果有一个输入错了,不要让用户从头再把所有的输入一次,只需把刚才输入错误的,重新输入正确即可

    • 1 输入:4(行数) 4(列数) 25(非零元个数),会提示:输入错误,非零元素个数要小于等于行数乘列数,请从新输入。
    • 2 输入:4(行数) 4(列数) 5(非零元个数)
    • 3 先输入:(1,1,1) (2,3,2)
    • 4 再输入(2,3,6),会提示:输入错误,输入的下标重复,请重新输入!
    • 5 再输入(1,1,6),会提示:输入错误,输入的下标重复,请重新输入!
    • 6 继续输入(3,1,3) (3,4,5)
    • 7 再输入(3,2,9),会提示:输入错误,下标输入时要递增输入,请重新输入!
    • 8 再输入(2,3,8),会提示:输入错误,下标输入时要递增输入,请重新输入!
    • 9 最后输入(4,2,4)

    显示,屏幕上输出

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

    转置,屏幕上输出

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

    重点: 矩阵的转置算法

    难点: 快速转置、输入时按行序非递减输入的控制

    一、设计思想

    1. 矩阵的压缩适合特殊矩阵,或者说特殊矩阵的压缩才有意义,压缩就是只需存储矩阵中的非零元素到一张表,这张表字段需要有:矩阵的总行数、列数和总的元素数,以及存储元素的结构体数组。

    2. 对于结构体数组,只需要包含 该元素的 行标、列标、该元素值。

    3. 需要注意的地方是 :

      3.1. 对于矩阵规格的判断(行数、列数是否小于0)

      3.2. 对于已定矩阵输入元素位置的判断(是否越界。是否坐标重复,是否非递减)

      3.3. 对于压缩矩阵的普通转置,需要以新矩阵的第一行开始存放元素,对应着也就是以此找处于第一列、第二列、。。等的元素

      3.4. 对于快速转置,快速的关键就在于 不存在嵌套循环,也就是一次就可以把第一个非零元元素在data中的序号计算出来,对应的思想不是位置找元素,而是一次把某个元素的位置定下来。

      3.5 设置bool的标记error_flag来 判断 不合法的情况,不合法就提示重新输入,对应I–,合法就提示当前元素输入成功

    4. 对于结构体数组采用的是定长空间,所以销毁不必释放空间,只需将元素等参数置为0即可

    二、源代码

    # include<iostream>
    # include<stdio.h>
    # include<stdlib.h>
    using namespace std;
    
    //压缩矩阵的转置实验 
    
    # define MAXSIZE 10000
    
    typedef  int ElemType;
    
    typedef struct{
    	int  row;
    	int  col;
    	ElemType e;
    }Triple; 
    
    typedef struct{
    	Triple data[MAXSIZE + 1];
    	int hangShu;
    	int lieShu;
    	int eCount;
    }TSMatrix;
    
    //int print_eCount = 1;
    
    // 一、函数声明
    //1. 创建矩阵
    void CreateTsmatrix(TSMatrix &t);
    
    //2. 销毁矩阵
    void DestoryTsmatrix(TSMatrix &t); 
    
    
    //3. 输出矩阵
    void PrintTsmatrix(TSMatrix t); 
    
    //4. 转置矩阵
    void TransposeSMatrix(TSMatrix t,TSMatrix &t_reserve);
    
    //5. 快速转置矩阵 
    void FastTransposeSMatrix(TSMatrix t,TSMatrix &t_reserve);
     
     
    
    int main(){
    	TSMatrix t;
    	TSMatrix t_reserve;
    	TSMatrix t_fast;
    //	t.data = NULL;
    //	t.data.col = 0;
    //	t.data.row = 0;
    //	t.data.e = 0;
    	 
    	t.hangShu = 0;
    	t.lieShu = 0;
    	t.eCount = 0;
    	
    	
    	t_reserve.hangShu = 0;
    	t_reserve.lieShu = 0;
    	t_reserve.eCount = 0;
    	
    	t_fast.hangShu = 0;
    	t_fast.lieShu = 0;
    	t_fast.eCount = 0;
    	
    	
    	bool flag = true;
    	while(flag){
    		
    		cout<<"☆   欢迎使用矩阵操作小程序   ☆" <<endl<<endl;
    		cout<<"Design By 软6-司超龙-1925050351"<<endl;
    		cout<<"==============================="<<endl;
    		cout<<"     1. 创建矩阵"<<endl;
    		cout<<"     2. 销毁矩阵"<<endl;
    		cout<<"     3. 输出矩阵"<<endl;
    		cout<<"     4. 转置矩阵"<<endl;
    		cout<<"     5. 快速转置矩阵"<<endl<<endl;
    		cout<<"请输入指令完成相关操作~"<<endl;
    		cout<<"输入一个负数退出程序!"<<endl<<endl;
    		
    		int n;
    		cin>>n;
    		switch(n){
    			case 1:
    				system("cls"); 
    				
    				//1.1 保证总行数为有效值 
    				while(true){
    					cout<<"请输入矩阵的行数:"<<endl;
    					cin>>t.hangShu;
    					if(t.hangShu <= 0){
    						cout<<"输入有误!请重新输入~"<<endl;
    					}
    					else{
    						break;
    					}
    				}
    				
    				
    				
    				//1.2 保证总列数为有效值 
    				while(true){
    					cout<<"请输入矩阵的列数:"<<endl;
    					cin>>t.lieShu;
    					if(t.lieShu <= 0){
    						cout<<"输入有误!请重新输入~"<<endl;
    					}
    					else{
    						break;
    					}
    				}
    				
    				//2. 检查不合法的矩阵元素个数 
    				static bool flag_num = true;
    				while(flag_num){
    					cout<<"请输入矩阵元素的个数:"<<endl;
    					cin>>t.eCount;
    					if(t.eCount > t.hangShu * t.lieShu || t.eCount <= 0){
    						cout<<"元素个数输入有误! 请重新输入~" <<endl;
    						
    					}
    					else{
    						flag_num = false;
    					}
    					
    				}
    				
    				/*检查1:不合法的矩阵元素个数 
    				do{
    					if(t.eCount > t.hangShu * t.lieShu || t.eCount < 0){
    						cout<<"你输入的矩阵元素个数有误!请重新输入~"<<endl; 
    					}
    					else{
    						cout<<"请输入矩阵元素的个数:"<<endl;
    					} 
    					
    					cin>>t.eCount;
    				}while(t.eCount > t.hangShu * t.lieShu)
    				*/
    				cout<<"请输入矩阵元素的位置及值:(元素下标不能重复,且下标需要递增)"<<endl;
    				for(int i = 1;i<=t.eCount;i++){
    					
    					cin>>t.data[i].row>>t.data[i].col>>t.data[i].e;
    					
    					//3.1.1 对第一个元素位置单独处理 
    					if(i == 1) {
    						if(t.data[i].row > t.hangShu || t.data[i].col > t.lieShu || t.data[i].row <= 0 || t.data[i].col <= 0){
    							
    							cout<<"元素位置不合法!请重新输入第一个元素~"<<endl;
    							i--;
    						}
    						
    						//3.1.2 第一个元素成功输入 
    						else if(i == 1){
    							cout<<"第 " <<i<<" 个元素输入完成!共 "<<t.eCount<<" 个元素"<<endl;
    						} 
    						
    					}
    					
    					//3.1.3 从第二个元素需要处理是否有重复位置的情况 
    					 
    					int j;//作用域需要提升 
    					bool error_flag = false;
    					if(i > 1){
    						
    						for(j = 1;j<i;j++){
    							if(t.data[i].row == t.data[j].row && t.data[i].col == t.data[j].col ){
    								cout<<"元素下标重复!请重新输入当前元素~"<<endl;
    								i--;
    								error_flag = true;
    								break;
    							}
    							else if(t.data[i].row < t.data[j].row && t.data[i].col < t.data[j].col){
    								cout<<"元素下标非递增!请重新输入当前元素~"<<endl;
    								i--;
    								error_flag = true;
    								break;
    							}
    							
    							
    							else if(t.data[i].col < t.data[j].col && t.data[i].row == t.data[j].row){
    								cout<<"元素列下标非递增!请重新输入当前元素~"<<endl;
    								i--;
    								error_flag = true;
    								break;
    							}
    							else if(t.data[i].row < t.data[j].row ){
    								cout<<"元素行下标非递增!请重新输入当前元素~"<<endl;
    								i--;
    								error_flag = true;
    								break;
    							}
    							else if(t.data[i].row > t.hangShu || t.data[i].col > t.lieShu || t.data[i].row <= 0 || t.data[i].col <= 0 ) {
    								cout<<"元素位置不合法!请重新输入当前元素"<<endl;
    								i--; 
    								error_flag = true;
    								break;
    							}
    							
    							
    							
    							
    						}
    						
    					}
    					//3.1.4 除第一个元素的输入成功信息 
    						if(!error_flag && i != 1){
    								cout<<"第 " <<i<<" 个元素输入完成!共 "<<t.eCount<<" 个元素"<<endl;
    								
    							}
    					
    					
    					
    					
    					
    				}
    				cout<<endl;
    				break;
    			case 2:
    				system("cls");
    				
    				DestoryTsmatrix(t); 
    				DestoryTsmatrix(t_reserve);
    				cout<<"矩阵销毁成功!"<<endl;
    				cout<<endl;
    				break;
    			case 3:
    				system("cls");
    				cout<<"矩阵的元素为:"<<endl;
    				//注意局部变量不能定义在switch中,会报错 ,需要加上static关键字 
    				static int print_eCount = 1;
    				
    				for(int i = 0;i<t.hangShu;i++){
    					for(int j = 0;j<t.lieShu;j++){
    						if( (i + 1 == t.data[print_eCount].row) && (j + 1 == t.data[print_eCount].col) ){
    							cout<<t.data[print_eCount].e<<" ";
    							print_eCount++;
    						}
    						else{
    							cout<<"0 ";
    						}
    						
    					}
    					cout<<endl;
    				}
    				cout<<endl;
    				
    				break;
    				
    			case 4:
    				system("cls") ;
    				TransposeSMatrix(t,t_reserve);
    				cout<<"转置矩阵的元素为:"<<endl;
    				PrintTsmatrix(t_reserve);
    				cout<<endl;
    				
    				
    				
    				break;
    				
    			case 5:
    				system("cls");
    				cout<<"快速转置矩阵的元素为:"<<endl; 
    				FastTransposeSMatrix(t,t_fast);
    				PrintTsmatrix(t_fast);
    				cout<<endl;
    				break;
    				
    			default:
    				if(n < 0){
    					system("cls");
    					flag = false;
    					cout<<"退出程序成功 ! 欢迎下次使用~~"<<endl;
    				}
    				else{
    					cout<<"输入的操作指令有误!下次吧~下次吧~"<<endl;
    				}
    				cout<<endl;
    				break;
    				
    		}
    		 
    	}
    	
    } 
    
    //二、函数实现
    
    //因为输出语句不能放在功能函数,为了实现简单,部分功能函数不在单独写出 
    //1. 创建矩阵
    void CreateTsmatrix(TSMatrix &t){} 
    
    //2. 销毁矩阵
    void DestoryTsmatrix(TSMatrix &t){
    	for(int i = 1;i<=t.eCount;i++){
    		t.data[i].e = 0;
    		t.data[i].row = 0;
    		t.data[i].col = 0;
    	}
    	
    	t.hangShu = 0;
    	t.lieShu = 0;
    	t.eCount = 0;
    	
    	
    }
    
    
    //3. 输出矩阵
    void PrintTsmatrix(TSMatrix t){
    
    
    	int print_eCount = 1;
    				
    	for(int i = 0;i<t.hangShu;i++){
    		for(int j = 0;j<t.lieShu;j++){
    			if( (i + 1 == t.data[print_eCount].row) && (j + 1 == t.data[print_eCount].col) ){
    				cout<<t.data[print_eCount].e<<" ";
    				print_eCount++;
    			}
    			else{
    				cout<<"0 ";
    			}
    			
    		}
    		cout<<endl;
    	}
    }
    
    //4. 转置矩阵
    void TransposeSMatrix(TSMatrix t,TSMatrix &t_reserve){
    	t_reserve.eCount = t.eCount;
    	t_reserve.hangShu = t.lieShu;
    	t_reserve.lieShu = t.hangShu;
    	//矩阵中有元素 
    	if(t_reserve.eCount){
    		//遍历矩阵中的每个元素 先找位置 
    		int q = 1;
    		//从旧矩阵的第一列开始 ,现在的第一列,就是转置后的第一行 
    		for(int i = 1;i<=t.lieShu;i++){
    			//遍历找到每个元素 ,找到就行、列坐标互换,没找到就接着找第二列 
    			for(int j = 1;j<=t.eCount;j++){
    				//找到了 
    				if(t.data[j].col == i ){
    					t_reserve.data[q].row = t.data[j].col;
    					t_reserve.data[q].col = t.data[j].row;
    					t_reserve.data[q].e = t.data[j].e;
    					//找下一个元素 
    					q++;
    				} 
    			}
    		}
    	}
    	
    }
    
    //5. 快速转置矩阵
    void FastTransposeSMatrix(TSMatrix t,TSMatrix &t_reserve){
    
    	t_reserve.eCount = t.eCount;
    	t_reserve.hangShu = t.lieShu;
    	t_reserve.lieShu = t.hangShu;
    	
    	//开辟数组num[i]存放 原矩阵中对应第 i 列的非零元的个数,也就是转置之后第 i 行的非零元元素个数 
    	int num[99];
    	//开辟数组copt[col]存放的是 原矩阵col 列,也就是转置矩阵的第col行 第一个非零元在压缩矩阵中的位置 
    	int cpot[99];
    	
    	
    	if(t_reserve.eCount){
    		
    		//求每一列中非零元的个数 
    		//先确定需要使用多少个num[] 
    		for(int i = 1;i<=t.lieShu;i++){
    			num[i] = 0;
    		}
    		//遍历每个数的列坐标,统计列坐标相等元素的个数到num[]中
    		//如num[1] = 1 表示原来的第一列,也就是转置后的第一行 有 1个元素 
    		for(int j = 1;j<=t.eCount;j++){
    			num[t.data[j].col]++;
    		}
    		 
    		 //设置第一行第一个非零元的位置序号为1 
    		cpot[1] = 1;
    		
    		
    		//对于num[i>1] 即某一列 非零元的个数大于1的 需要定 第一个非零元素得位置 
    		for(int m = 2;m<=t.lieShu;m++){
    			
    			cpot[m] = cpot[m - 1] + num[m - 1];
    			//cpot[m] 为 每一行 第一个非零元素的序号值 
    		} 
    		for(int n = 1;n<=t.eCount;n++){
    			//遍历每个元素
    			
    			//p为该元素所在列值 ,以后如果再次出现相同的列值得元素,就cpot[p]++,序号位置++ 
    			//根据列值求在data中的序号 
    			int p = t.data[n].col;
    			
    			//q对应的是序号 
    			int q = cpot[p];
    			t_reserve.data[q].row = t.data[n].col;
    			t_reserve.data[q].col = t.data[n].row;
    			t_reserve.data[q].e = t.data[n].e;
    			
    			cpot[p]++;
    			
    		}
    		
    	}
    	 
    } 
     
     
    

    三、部分实验截图

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    三、实验小结

    1. 练习了特殊矩阵的定长存储方式,熟悉实现了压缩矩阵的普通转置和快速转置算法
    2. 快速转置的算法 之所以快,时间复杂度由普通的O(n^2)转化为O(n),因为避免了循环嵌套,一般的转置算法思想是依次填充位置,每个位置而必须遍历判断每个元素。而升级的转置算法是 计算出 每行第一个非零元素的data下标序号(第一行第一个则为data[1]),当填上每行第一个非零元素的位置后,存放序号的cpot[i]就加一,之后再出现该行的元素依次放入即可
    展开全文
  • 压缩矩阵的2种转置运算 实验6、压缩矩阵的2种转置运算 (1)实验目的 通过该实验,让学生理解矩阵压缩存储的概念、方法等相关知识,掌握用三元组表的方式如何进行矩阵的压缩存储,并在此基础上进行转置操作,理解...
  • 三角矩阵的压缩矩阵

    2019-09-22 14:33:13
    三角矩阵的压缩矩阵 首先三角矩阵的压缩矩阵 对角线上的元素加上对角线以下的元素,是我们要存储的元素,对角线上面的也是我们要存储的元素,不过他们是相同常数,因此我们可以把这些同样的常数,只要存储一个就...
  • 用来测试压缩感知中构造的测量矩阵的RIP
  • 通过该实验,让学生理解矩阵压缩存储的概念、方法等相关知识,掌握用三元组表的方式如何进行矩阵压缩存储,并在此基础上进行转置操作,理解转置和快速转置两种矩阵转置算法的思想。 (2)实验内容 用三元组表...
  • 压缩存储称矩阵存储时只需要存储上三角/下三角的数据,所以最多存储n(n+1)/2个数据(相当于1+2+…+n,即等差数列求和)。 对称矩阵压缩存储的对应关系:下三角存储i>=j, SymmetricMatrix[i][j] ==Array[i*(i+1)/2+j...
  • 主要介绍了C++ 实现稀疏矩阵压缩存储的实例的相关资料,M*N的矩阵矩阵中有效值的个数远小于无效值的个数,且这些数据的分布没有规律,需要的朋友可以参考下
  • 三角矩阵中的重复元素c可共享一个存储空间,其余元素正好有n(n+1) /2个,因此三角矩阵压缩存储到向量sa[0...n(n+1) /2]中(一位数组),其中c存放在向量的最后1个分量重。 上三角矩阵 元素aij保存在向量sa中时的...
  • CSC压缩矩阵

    千次阅读 2017-01-10 14:48:36
    一个简单的矩阵 Array(0, 2, 3, 6) Array(0, 2, 1, 0, 1, 2) Array(1, 2, 3, 4, 5, 6)Array(1, 2, 3, 4, 5, 6)–>表示按照列依次顺序排列非0元素 Array(0, 2, 1, 0, 1, 2)–>表示每一列非零元素所在的行号(从0...
  • 1. 对称矩阵采用一维数组进行存储,例如test[3][3]={ { 1 , 2 , 3 } , { 2 , 1 , 3 } , { 3 , 3 , 1 } }存进 ans [ ] 里面;for(int i=0;i&lt;3;i++)for(int j=0;j&lt;3;j++)ans[ len++ ]=test[ i ] [ j ];解...
  • 实验报告 课程名数据结构 C 语言版 实验名矩阵压缩存储 姓 名 班 级 学 号 时 间2014.11.23 一 实验目的与要求 1. 掌握并实现稀疏矩阵压缩存储的方法 2. 在该存储方法上实现矩阵的操作 二 实验内容 ? 判断一个用...
  • 在信息等价矩阵的基础上利用粗集理论扩展了矩阵算法,设计了相对核和相对约简以及规则获取算法,提出了增量式规则挖掘的信息压缩矩阵算法。实现了在原有规则集的基础上进行规则和规则参数的增量更新,避免了重复遍历...
  • 一种基于压缩矩阵的关联规则挖掘算法
  • 已知对称矩阵,采用压缩存储的方式只存储其下三角元素,给出压缩存储的需要的总空间大小及该元素在原矩阵中的行号、列号。 Input 输入只有一行,分别为矩阵的维数n及压缩存储后的元素序号m。 Output 输出包含两行,...
  • 分布式估计中最优压缩矩阵设计的封闭形式解决方案
  • Java版 压缩矩阵的定义及转置算法
  • 网络游戏-农田无线传感器网络参数间动态耦合压缩矩阵构建方法.zip
  • SpMV_CSR 使用压缩稀疏行格式的稀疏矩阵矢量乘法来编译代码,请使用gcc CSR.c mmio.c -o csr ./csr [filename.mtx]
  • 提出了一种基于压缩矩阵运算的电信告警关联规则挖掘算法。它解决了apriori等算法需多次扫描数据库的问题,通过扫描告警事务库并进行压缩变换得到压缩告警关联矩阵,对关联矩阵进行运算得到告警间的关联规则。仿真...
  • 对于数组的压缩存储,一维数组主要使用哈夫曼压缩,多维数组主要采用矩阵压缩的形式,对特殊矩阵和系数矩阵进行压缩。 哈夫曼压缩 哈夫曼压缩是由哈夫曼树推广而来的,是哈夫曼编码的重要应用。哈夫曼树 ─ 即最优...
  • 矩阵压缩 以及转置后 输出 原始状态的矩阵压缩的三元表形式
  • 稀疏矩阵的压缩矩阵

    2017-06-08 23:46:46
    如果一个矩阵中的大部分元素为零,称为稀疏矩阵。对于稀疏矩阵而言,时间存储的数据项很少,如果在程序中使用传统的二维数组方式来存储,则十分浪费存储空间,且矩阵越大,资源浪费越严重。为提内存空间利用率,可...
  • 其次,结合矩阵补全(MC)技术与CS 技术,提出基于极稀疏块观测矩阵压缩感知数据收集算法,在一个采集周期内进行数据收集,利用 MC 技术恢复丢失数据,减少分组丢失对数据收集的影响;利用CS技术重构全网数据,...
  • 将整个图形的连接存储在邻接矩阵中。 用邻接链表来表示图之间的关系 在图中表示连接的最简单方法是在每个节点的数据结构中存储与其连接的节点的列表。该结构称为邻接列表。 例如,在航空公司图表中 每一个节点连接...
  • 用来测试压缩感知中构造的测量矩阵的RIP
  • 首先引入两个概念: ...特殊矩阵压缩存储——对称矩阵 在对角线的两边,aij==aji,这里出现了不必要的多于存储,所以我们对其进行矩阵压缩。 这里只演示二维数组从0,0开始的 这分别是我们的二维数据中的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 78,338
精华内容 31,335
关键字:

压缩矩阵