上篇文章我们对线性表和数组做个一些简单的了解。这篇我们通过代码来演示数组的使用。
数学中的矩阵(matrix)用来描述二维数组的最好方式。那么本章主要来通过代码来讨论矩阵的相加,相乘以及稀疏矩阵,转置矩阵,上三角与小三角矩阵。
矩阵相加
package arrays;
public class matrixAdd {
/*
* 两个矩阵相加
*
*/
private static void MatrixAdd(int[][] arrayA, int[][] arrayB, int[][] arrayC, int x, int y) {
// TODO Auto-generated method stub
int row,col;
if(x<=0||y<=0){
System.out.println("矩阵维数必须大于0");
return;
}
for(row=1;row<=x;row++){
for(col=1;col<=y;col++){
arrayC[(row-1)][(col-1)]=arrayA[(row-1)][(col-1)]+arrayB
[(row-1)][col-1];
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int i;
int j;
final int ROWS=3;
final int COLS=3;
//定义两个数组,即矩阵
int[][] A={{1,3,5},{7,9,11},{13,15,17}};
int[][] B={{9,8,7},{6,5,4},{3,2,1}};
int[][] C=new int[ROWS][COLS];
System.out.println("[矩阵A的各个元素]");//打印矩阵A的内容
for(i=0;i<3;i++){
for(j=0;j<3;j++){
System.out.print(A[i][j]+" \t");
}
System.out.println();
}
System.out.println("[矩阵B的各个元素]");//打印矩阵B的内容
for(i=0;i<3;i++){
for(j=0;j<3;j++){
System.out.print(B[i][j]+"\t");
}
System.out.println();
}
MatrixAdd(A,B,C,3,3);
System.out.println("[矩阵A和B相加的结果]");//打印矩阵C的内容
for(i=0;i<3;i++){
for(j=0;j<3;j++){
System.out.print(C[i][j]+" \t");
}
System.out.println();
}
}
}
矩阵相乘
package arrays;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class matrixMultiply {
private static void MatrixMultiply(int[][] arrA, int[][] arrB, int[][] arrC, int m,
int n, int p) {
if(m<=0||n<=0||p<=0){
System.out.println("输入错误:n,m,p必须大于0");
return;
}
for(int i=0;i<m;i++){
for(int j=0;j<p;j++){
int temp=0;
for(int k=0;k<n;k++){
temp=temp+arrA[i][k]*arrB[k][j];
arrC[i][j]=temp;
}
}
}
}
public static void main(String[] args) throws IOException {
int m,n,p;
int i,j;;
String temp;//用来接收矩阵输入的值
BufferedReader keyin=new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入矩阵A的维数(m,n)");
System.out.println("请先输入矩阵A的m值");
m=Integer.parseInt(keyin.readLine());
System.out.println("接下来输入矩阵A的n值");
n=Integer.parseInt(keyin.readLine());
int A[][]=new int[m][n];
System.out.println("请输入矩阵A的各个元素");
for(i=0;i<m;i++){
for(j=0;j<n;j++){
System.out.println("a"+i+j+"=");
temp=keyin.readLine();
A[i][j]=Integer.parseInt(temp);
}
}
System.out.println("请输入矩阵B的维数(n,p)");
System.out.println("请先输入矩阵B的n值");
n=Integer.parseInt(keyin.readLine());
System.out.println("接下来输入矩阵B的p值");
p=Integer.parseInt(keyin.readLine());
int B[][]=new int[n][p];
System.out.println("请输入矩阵B的各个元素");
for(i=0;i<n;i++){
for(j=0;j<p;j++){
System.out.println("b"+i+j+"=");
temp=keyin.readLine();
B[i][j]=Integer.parseInt(temp);
}
}
int[][] C=new int[m][p];
MatrixMultiply(A,B,C,m,n,p);
System.out.println("A和B相乘结果为");
for(i=0;i<m;i++){
for(j=0;j<p;j++){
System.out.print(C[i][j]+"\t");
}
System.out.println();
}
}
}
转置矩阵
假设A为m*n矩阵。则A的转置矩阵为n*m
package arrays;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class matrixZZ {
public static void main(String[] args) throws IOException {
int m,n;
int row,col;;
String temp;//用来接收矩阵输入的值
BufferedReader keyin=new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入m*n矩阵的维数(m,n)");
System.out.println("请先输入矩阵维度的m:");
m=Integer.parseInt(keyin.readLine());
System.out.println("接下来输入矩阵维度的n:");
n=Integer.parseInt(keyin.readLine());
int A[][]=new int[m][n];
int B[][]=new int[n][m];
System.out.println("请输入矩阵的内容");
for(row=1;row<=m;row++){
for(col=1;col<=n;col++){
System.out.println("a"+row+col+"=");
temp=keyin.readLine();
A[row-1][col-1]=Integer.parseInt(temp);
}
}
System.out.println("输入的矩阵为:");
for(row=1;row<=m;row++){
for(col=1;col<=n;col++){
System.out.print(A[row-1][col-1]+"\t");
}
System.out.println();
}
//进行转置的动作
for(row=1;row<=n;row++){
for(col=1;col<=m;col++){
B[(row-1)][(col-1)]=A[(col-1)][(row-1)];
}
}
System.out.println("转置矩阵为:");
for(row=1;row<=n;row++){
for(col=1;col<=m;col++){
System.out.print(B[row-1][col-1]+"\t");
}
System.out.println();
}
}
}
稀疏矩阵
package arrays;
import java.io.IOException;
public class SparseMatrix {
/*
* 稀疏矩阵:一个矩阵中大部分元素都为0,即可称为“稀疏矩阵”。如果直接使用传统的二维数组来存储,会造成
* 内存空间大量浪费,改进的方法为三项式(3-tuple)。例如:
* 25 0 0 32 0 -25 1 2 3
* 0 33 77 0 0 0 0 6 6 6
* 0 0 0 55 0 0 1 1 1 25
* 0 0 0 0 0 0 压缩后为:2 1 4 32
* 101 0 0 0 0 0 3 1 6 -25
* 0 0 0 38 0 0 4 2 2 33
* 5 2 3 77
* A(0,1)=表示此矩阵的行数 6 3 4 55
* A(0,1)=表示此矩阵的列数 7 5 1 101
* A(0,3)=表示此矩阵的非零项目的总数。 8 6 3 38
* 利于此三项式数据结构来压缩稀疏矩阵的方法。可以减少内存的不必要的浪费。
*/
public static void main(String[] args) throws IOException {
final int ROWS=8;//定义行数
final int COLS=9;//定义列数
final int NOTZERO=8;//定义稀疏矩阵中不为0的数
int i,j,rw,cl,nz;
int temp=1;
int[][] Sparse=new int[ROWS][COLS];//声明稀疏矩阵
int[][] Compress=new int[NOTZERO+1][3];//声明压缩矩阵
//将稀疏矩阵的元素全设为0
for(i=0;i<ROWS;i++){
for(j=0;j<COLS;j++){
Sparse[i][j]=0;
}
}
nz=NOTZERO;
for( i=1;i<nz+1;i++){
rw=(int) (Math.random()*100);
rw=rw%ROWS;
cl=(int)(Math.random()*100);
cl=cl%COLS;
if(Sparse[rw][cl]!=0){
nz++;//避免同一元素设定两次数值而造成压缩矩阵中有0
}
Sparse[rw][cl]=i;//随机产生稀疏矩阵中非零的元素值
}
System.out.println("打印矩阵中的元素");
for(i=0;i<ROWS;i++){
for(j=0;j<COLS;j++){
System.out.print(Sparse[i][j]+"");
}
System.out.println();
}
//开始压缩稀疏矩阵
Compress[0][0]=ROWS;
Compress[0][1]=COLS;
Compress[0][2]=NOTZERO;
for(i=0;i<ROWS;i++){
for(j=0;j<COLS;j++){
if(Sparse[i][j]!=0){
Compress[temp][0]=i;
Compress[temp][1]=j;
Compress[temp][2]=Sparse[i][j];
temp++;
}
}
}
System.out.println("系数矩阵压缩后的内容为:");
for(i=0;i<NOTZERO+1;i++){
for(j=0;j<3;j++){
System.out.print(Compress[i][j]+" ");
}
System.out.println();
}
}
}
运行结果:
打印矩阵中的元素
000800000
000000000
000000000
002006000
000000000
100400000
000970500
000000000
系数矩阵压缩后的内容为:
8 9 8
0 3 8
3 2 2
3 5 6
5 0 1
5 3 4
6 3 9
6 4 7
6 6 5
上三角矩阵
package arrays;
public class UpperTrangularMatrix {
/*
* 上三角矩阵:就是一种对角线以下皆为0的n*n矩阵,其中又分为右上三角矩阵和左上三角矩阵。由于上三角
* 矩阵仍有许多的为0,所以我们可以把三角矩阵的二维模式存储在一维数组中。共有n*(n+1)/2项
* 也可分为“以行为主”和“以列为主”。下面以左上三角矩阵为例:
* 求A[i][j]在数组中所对应的k值,n*n矩阵。
* 以行为主:k=n*(i-1)-i*(i-1)/2+j;
* 以列为主:k=j*(j-1)/2+i;
* 假如有一个5*5的右上三角矩阵A,以列为主对应到一维数组B,请问a23所对应B(k)的k值多少?
* k=j*(j-1)/2+i=3*(3-1)/2+2=5 a23=B(5)
* 左上三角矩阵:
* 求A[i][j]在数组中所对应的k值,n*n矩阵。
* 以行为主:k=n*(i-1)-(i-2)*(i-1)/2+j;
* 以列为主:k=n*(j-1)-(j-1)*(j-2)/2+i;
*/
public static void main(String[] args) {
int[][] array={{7,8,12,21,9},
{0,5,14,17,6},
{0,0,7,23,24},
{0,0,0,32,19},
{0,0,0,0,8}};
showArray(array);
result(array);
}
private static void showArray(int[][] array) {
System.out.println("上三角矩阵");
for(int i=0;i<array.length;i++){
for(int j=0;j<array.length;j++){
System.out.print(array[i][j]+" ");
}
System.out.println();
}
}
private static void result(int[][] array) {
int[] arr;
int arrSize;
int index=0;
arrSize=array.length;
arr=new int[arrSize*(arrSize+1)/2];
for(int i=0;i<arrSize;i++){
for(int j=0;j<arrSize;j++){
if(array[i][j]!=0){
arr[index++]=array[i][j];
}
}
}
System.out.println("以行为主一维数组表示为:");
System.out.print("[");
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
System.out.println("]");
}
}
运行结果:
上三角矩阵
7 8 12 21 9
0 5 14 17 6
0 0 7 23 24
0 0 0 32 19
0 0 0 0 8
以行为主一维数组表示为:
[7 8 12 21 9 5 14 17 6 7 23 24 32 19 8 ]
下三角矩阵
/*
* 下三角矩阵:就是一种对角线以上皆为0的n*n矩阵,其中又分为右下三角矩阵和左下三角矩阵。和上三角
* 矩阵处理方式类似
* 也可分为“以行为主”和“以列为主”。下面以左下三角矩阵为例:
* 求A[i][j]在数组中所对应的k值,n*n矩阵。
* 以行为主:k=i*(i-1)/2+j;
* 以列为主:k=n*(j-1)+i-j*(j-1)/2;
* 假如有一个6*6的右上三角矩阵A,以列为主对应到一维数组B,请问a32所对应B(k)的k值多少?
* k=n*(j-1)+i-j*(j-1)/2=6*(2-1)+3-2*(2-1)/2=8 a23=B(8)
* 右下三角矩阵:
* 求A[i][j]在数组中所对应的k值,n*n矩阵。
* 以行为主:k=i*(i+1)/2+j-n;
* 以列为主:k=j*(j+1)/2+i-n;
*/
public static void main(String[] args) {
int[][] array={{76,0,0,0,0},
{54,51,0,0,0},
{23,8,26,0,0},
{43,35,28,18,0},
{12,9,14,35,46}};
showArray(array);
result(array);
}
数组与多项式
多项式是数学中相当重要的表现方式,通常如果用计算机来处理多项式的相关运算,可以将多项式以数组或链表的形式来存储,本节主要讨论多项式以数组结构方式表示相关应用。
package arrays;
public class PolyAdd {
/*
* 多项式在数组中的表示方式(n次多项式。例如P(x)=2*x^5+3*x^4+5*x^2+4*x+1为5次多项式。)
* 1.使用一个n+2长度的一维数组存放,数组的第一个位置存储最大指数n,其他位置按照指数n递减,
* 一次存储对应关系。
* A{5,2,3,0,5,4,1}
* 2.只存储多项式中非零项目,如果有m个非零项,则使用长度为2m+1的数组来存储,数组第一个
* 元素为非零项的个数
* A{5,2,5,3,4,5,2,4,1,1,0}
*/
public static void main(String[] args) {
int[] PolyA={4,3,7,0,6,2};
int[] PolyB={4,1,5,2,0,9};
System.out.print("多项式A=> ");
printPoly(PolyA);
System.out.print("多项式B=> ");
printPoly(PolyB);
PolySum(PolyA,PolyB);
}
private static void PolySum(int[] polyA, int[] polyB) {
int[] result=new int[polyA[0]+2];
result[0]=polyA[0];
for(int i=1;i<result.length;i++){
result[i]=polyA[i]+polyB[i];
}
System.out.print("A加B的和为=>");
printPoly(result);
}
private static void printPoly(int[] poly) {
int MaxExp;
MaxExp=poly[0];
//循环次数
for(int i=1;i<=poly[0]+1;i++){
MaxExp--;
if(poly[i]!=0){//如果该式为零就跳过
if((MaxExp+1)!=0){
System.out.print(poly[i]+"x^"+(MaxExp+1));
}else{
System.out.println(poly[i]);
}
if(MaxExp>=0){
System.out.print("+");
}
}
}
System.out.println();
}
}
运行结果
多项式A=> 3x^4+7x^3+6x^1+2
多项式B=> 1x^4+5x^3+2x^2+9
A加B的和为=>4x^4+12x^3+2x^2+6x^1+11