数组之三种矩阵

Posted 鹏达君

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数组之三种矩阵相关的知识,希望对你有一定的参考价值。

文字描述

 

矩阵的压缩:对于某些特殊的矩阵来说,非零元素较少,大部分元素为0,采用某种算法,将非零元素存储在一位数组里以达到节省存储空间的目的的过程,称为矩阵的压缩

 

矩阵的还原:将压缩后的数组还原成原始矩阵的过程

 

 

 

1、对角矩阵

 

①矩阵介绍

 

所谓对角矩阵:

 

矩阵中的所有非零元素都集中在以主对角线为中心的带状区域中,

 

即除了主对角线上和直接在主对角线上下若干条对角线上的元素外,其余元素均为零。

 

这样的矩阵称为半带宽为d的带状矩阵,带宽是2*d+1,d为直接在对角线上下方不为0的对角线数

 

② 矩阵压缩原理

 

对于n阶2d+1对角矩阵,只需要存放对角线区域内 n*(2*d+1)-d*(d+1)个非零元素

 

为了简便运算,认为每一行都有2*d+1个元素,若少于2*d+1个元素,则添零补齐。

 

因为非零元素都在主对角线元素的左右两侧,

 

那么只要在矩阵的每一行的主对角线元素的两侧分别  “凑够”  d个元素即可,

 

如果该元素  “不在"  矩阵内部,则补零,如果“在”矩阵内部,则存储到一维数组中即可

 

 

2、对称矩阵

 

① 矩阵介绍

 

 对称矩阵  array[ i ][ j ]=array[ j ][ i ]  所以对于相同的元素只保存一个

 

②矩阵压缩的原理

 

压缩成一个一维数组后 array [ i ]  [ j]  =array [ j ]  [ i  ]

 

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

 

对于一个n阶的矩阵而言,压缩后一维空间的数目为  n*(n+1)/2;

 

 

3、三角矩阵

 

① 矩阵介绍

 

所谓三角矩阵:

整个矩阵只有主对角线及主对角线以上(或以下)为非零元素。

 

下三角形矩阵:主对角线及主对角线以下为非零元素

 

上三角形矩阵:主对角线及主对角线以上为非零元素

 

很显然对于一个n阶的矩阵而言,压缩后一维空间的数目为n*(n+1)/2;(等差数列求和)

 

(以下以下三角为例进行分析)

 

② 矩阵压缩的原理

 

根据该矩阵的性质,很容易得出结论

 

很显然第一行一个元素,第二行两个元素,依次类推。。。

 

代码实现

1、对角矩阵

import org.Stone6762.Utils.ArrayUtils; 

/** 
* @Stone6762 
*/ 
public class DiagonalArray { 

/** 
* @Title: compress n阶2d+1对角矩阵的压缩 
* @Description: TODO(n阶2d+1对角矩阵的压缩) 
* @param oriArray 
* 原始矩阵 
* @param d 
* 半带宽 
* @return 
*/ 
public static double[] compress(double[][] oriArray, int d) { 
int n = oriArray.length; 
double compressedArray[] = new double[n * (2 * d + 1)]; 
int col = 0; 
for (int i = 0, k = 0; i < n; i++) { 
for (int j = -d; j <= d; j++, k++) { 
col = i + j;//计算对应的列值 
if (col >=0 && col < n) {//在矩阵内部的就赋值,不在矩阵内部的就直接补零 
compressedArray[k] = oriArray[i][col]; 



return compressedArray; 


/** 
* @Title: recover n阶2d+1对角矩阵的还原 
* @Description: TODO() 
* @param compressedArray 
* 压缩后的矩阵 
* @param d 
* 半带宽 
* @return 
*/ 
public static double[][] recover(double[] compressedArray, int d) { 
int sum = compressedArray.length; 
int n = sum / (2 * d + 1); 
double[][] oriArray = new double[n][n]; 
int col = 0; 
for (int i = 0, k = 0; i < n; i++) { 
for (int j = -d; j <= d; j++, k++) { 
col = i + j; 
if (col >= 0 && col < n) { 
oriArray[i][col] = compressedArray[k]; 



return oriArray; 


public static void main(String[] args) { 
double[][] arr = { 
{ 1, 2, 0, 0, 0 }, 
{ 3, 4, 5, 0, 0 }, 
{ 0, 6, 7, 8, 0 }, 
{ 0, 0,9,10,11 }, 
{ 0, 0, 0,12, 13 } 

}; 

double[] tar = compress(arr,1); 
// [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 0.0] 

ArrayUtils.printOneArray(tar); 

ArrayUtils.printMulArray(recover(tar,1)); 



}

2、对称矩阵

import org.Stone6762.Utils.ArrayUtils; 

/** 
* @Stone6762 
*/ 
public class SymmetricalArray { 

/** 
* @Title: compressSymmetricalArray 对称矩阵的压缩 
* @Description: TODO(n阶方阵 对称矩阵(a[i][j]=a[j][i])的压缩 此处采用的的是行优先顺序储存的方式) 
* @param <T> 
* @param oriArray 
* @return 
*/ 
public static double[] compress(double[][] oriArray) { 
int n = oriArray.length; 
double compressedArray[] = new double[n * (n + 1) / 2]; 
for (int i = 0; i < oriArray.length; i++) { 
for (int j = 0; j <= i; j++) { 
compressedArray[i * (i + 1) / 2 + j] = oriArray[i][j]; 


return compressedArray; 


/** 
* @Title: recoverSymmetricalArray 
* @Description: TODO( 将压缩后的对称矩阵进行还原) 
* @param compressedArray 
* @return 
*/ 
public static double[][] recover(double[] compressedArray) { 
int length = compressedArray.length; 
int n = (int) Math.sqrt(2 * length); 
double[][] oriArray = new double[n][n]; 
for (int i = 0, k = 0; i < oriArray.length; i++) { 
for (int j = 0; j <= i; j++, k++) { 
oriArray[j][i] = oriArray[i][j] = compressedArray[k]; 


return oriArray; 


public static void main(String[] args) { 
double[][] arr = { 
{ 1, 2, 3 }, 
{ 2, 4, 6 }, 
{ 3, 6, 5 } }; 

double[] tar = compress(arr); 
// [1.0, 2.0, 4.0, 3.0, 6.0, 5.0] 

ArrayUtils.printOneArray(tar); 

ArrayUtils.printMulArray(recover(tar)); 



}

3、三角矩阵

import org.Stone6762.Utils.ArrayUtils; 

/** 
* @Stone6762 
*/ 
public class TriangleArray { 

/** 
* @Title: compress 
* @Description: TODO(以下三角形为例压缩) 
* @param oriArray 
* @return 
*/ 
public static double[] compress(double[][] oriArray) { 
int n = oriArray.length; 
double compressedArray[] = new double[n * (n + 1) / 2]; 
for (int i = 0; i < oriArray.length; i++) { 
for (int j = 0; j <= i; j++) { 
compressedArray[i * (i + 1) / 2 + j] = oriArray[i][j]; 


return compressedArray; 


/** 
* @Title: recover 
* @Description: TODO(以下三角形为例解压) 
* @param compressedArray 
* @return 
*/ 
public static double[][] recover(double[] compressedArray) { 
int length = compressedArray.length; 
int n = (int) Math.sqrt(2 * length); 
double[][] oriArray = new double[n][n]; 
for (int i = 0, k = 0; i < oriArray.length; i++) { 
for (int j = 0; j <= i; j++, k++) { 
oriArray[i][j] = compressedArray[k]; 


return oriArray; 


public static void main(String[] args) { 
double[][] arr = { 
{ 1, 0, 0 }, 
{ 2, 4, 0 }, 
{ 3, 6, 5 } }; 
double[] tar = compress(arr); 
// [1.0, 2.0, 4.0, 3.0, 6.0, 5.0] 

ArrayUtils.printOneArray(tar); 

ArrayUtils.printMulArray(recover(tar)); 



}

 

提醒:各种矩阵实现源码下载:

http://www.cnblogs.com/tanlon/p/4155687.html

 

以上是关于数组之三种矩阵的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript基础篇分享之三

向量、矩阵和数组数据类型有啥区别?

[剑指Offer]5.二维数组中的查找

matlab学习笔记

学习笔记之三(数组中的一些方法)

乐字节Java反射之三:方法数组类加载器和类的生命周期