2021年07月12日 数组习题

1、在一个数组中找出最大和最小值,并输出它们的位置;

FindMaxAndMinInArray.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class FindMaxAndMinInArray {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int[] a = new int[10];
System.out.print("输入10个数:");
for (int i = 0; i < a.length; i++) {
a[i] = scanner.nextInt();
}
int maxIndex = 0, minIndex = 0;
for (int i = 1; i < a.length; i++) {
// 如果找到一个更大的数
if (a[i] > a[maxIndex]) {
maxIndex = i;
}
// 如果找到一个更小的数
if (a[i] < a[minIndex]) {
minIndex = i;
}
}
// 输出最大最小值
System.out.println("最大值:a[" + maxIndex + "]=" + a[maxIndex] + ",最小值:a[" + minIndex + "]=" + a[minIndex]);
}
}

2、冒泡法对一个数组排序;

冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢”浮”到数列的顶端。
https://www.runoob.com/w3cnote/bubble-sort.html

https://baike.baidu.com/item/%E5%86%92%E6%B3%A1%E6%8E%92%E5%BA%8F#4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
* 冒泡排序,默认升序排列。
* 如果数组已经有序,则不再排序。
*
* @param array
*/
private static void bubbleSortBetter(int[] array) {
// 添加一个判断是否交换的标记
boolean haveSwap = false;
for (int i = 0, temp; i < array.length - 1; i++) {
haveSwap = false;
for (int j = 0; j < array.length - 1 - i; j++) {
// 如果前一个数比后一个数大
if (array[j] > array[j + 1]) {
temp = array[j];
// 小的数放前面
array[j] = array[j + 1];
// 大的数放后面
array[j + 1] = temp;
// 经过交换
haveSwap = true;
}
}
// 如果一轮比较之后,没有交换,则说明已经有序,不需要再排序了
if (!haveSwap) {
break;
}
}
}

3、 选择法对数数组排序;

https://zh.wikipedia.org/wiki/%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95
https://www.runoob.com/w3cnote/selection-sort.html
选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是:
第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。
选择排序是不稳定的排序方法。

  • 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
  • 再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
  • 重复第二步,直到所有元素均排序完毕。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
* 选择排序,升序排序
* 每次选择一个最小的值放到没有排序的序列的前方。
* @param a 待排序的数组。
*/
public static void selectionSort(int[] a) {
// n个元素,需要比较n-1次(2个元素,比较1次,3个元素,比较两次)
for (int i = 0, temp; i < a.length - 1; i++) {
// 默认最小值
int min = i;
// 遍历没有排序的元素
for (int j = i + 1; j < a.length; j++) {
// 如果找到更小的值
if (a[j] < a[min]) {
// 记录下这个更小的值
min = j;
}
}
// 如果找到了更小的值
if (min > i) {
temp = a[min];
a[min] = a[i];
a[i] = temp;
}
}
}

4、把一个十进制数转换成十六进制的数;

https://zh.wikihow.com/%E6%8A%8A%E5%8D%81%E8%BF%9B%E5%88%B6%E6%95%B0%E8%BD%AC%E6%8D%A2%E4%B8%BA%E5%8D%81%E5%85%AD%E8%BF%9B%E5%88%B6%E6%95%B0

和十进制转2进制的做法一样,除以16,取余数,然后逆序排列即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
public class DecimalToHexadecimal {

public static void main(String[] args) {
// 被除数,十进制数
int dividend = 16 + 15;
// 除16取余
int[] remainders = decimalToHexadecimal(dividend);
// 逆序打印余数
System.out.println("(" + dividend + ")10 = (" + printHexadecimal(remainders) + ")16");
}

/**
* 十进制转十六进制
* 除16取余,逆序排列
*
* @param remainders 保存每个余数的数组
* @param remainderCounter 到底有多少个余数
* @return
*/

private static int[] decimalToHexadecimal(int dividend) {
// 创建一个临时的数组用来,保存余数
int[] remainderTemps = new int[20];
int remainderCounter = 0;
// 十进制数(被除数)
// int dividend = 16 + 15;
// 定义商
int quotient;
do {
// 求商
quotient = dividend / 16;
// 求余数
remainderTemps[remainderCounter++] = dividend % 16;
// 商作为下次的被除数
dividend = quotient;
} while (dividend > 0);
// 创建一个刚好能保存所有余数的数组
int[] remainders = new int[remainderCounter];
// 从临时保存的余数数组中拷贝到
for (int i = 0; i < remainders.length; i++) {
remainders[i] = remainderTemps[i];
}
// 返回保存余数的数组
return remainders;
}

/**
* 打印16进制数
*
* @param remainders 保存余数的数组。
*/
private static String printHexadecimal(int[] remainders) {
StringBuffer sb = new StringBuffer(remainders.length);
// 十进制转十六进制口诀:除16取余,逆序排列
// 逆序打印
for (int i = remainders.length - 1; i >= 0; i--) {
if (remainders[i] < 10) {
// System.out.print(remainders[i]);
sb.append(remainders[i]);
} else {
// System.out.print((char) ('A' + remainders[i] - 10));
sb.append((char) ('A' + remainders[i] - 10));
}
}
return sb.toString();
}
}

5、实现一个数组的逆序存储

ReverseStoredInTheArray.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* 逆序存储到数组中
*
*/
public class ReverseStoredInTheArray {

public static void main(String[] args) {
int[] a=new int[10];
Scanner scanner=new Scanner(System.in);
for (int i = 0; i < a.length; i++) {
a[a.length-1-i]=scanner.nextInt();
}
for (int i = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
}
}

6、在一个有序的数组插入一个数,也保证有序;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
public class OrderedArrayIsStillOrderedAfterInsertion {

public static void main(String[] args) {
// 保存有序序列的数组
int[] a = new int[20];
// 有序序列
int[] b = { 1, 5, 9, 18, 24 };
// 把有序序列保存到数组中
for (int i = 0; i < b.length; i++) {
a[i] = b[i];
}
System.out.println("有序序列:");
printArray(a);

int toBeInsert;
// Scanner scanner = new Scanner(System.in);
// System.out.println("输入一个整数:");
// toBeInsert=scanner.nextInt();

// 插入有序序列的最前面
// toBeInsert = 0;
// 插入有序序列的中间
// toBeInsert = 8;
// toBeInsert = 23;
// 插入有序序列的最后面
toBeInsert = 25;
System.out.println("要插入的元素:" + toBeInsert);
// 找出要出插入的位置
int insetIndex = findInsertIndex(a, b.length - 1, toBeInsert);
System.out.println("插入后的位置:" + insetIndex);
// 为要插入的元素腾出空间
makeRoomForInsertion(a, b.length, insetIndex);
System.out.println("为待插入元素腾出空间:");
printArray(a);
// 插入要插入的元素
a[insetIndex] = toBeInsert;
System.out.println("插入后的效果:");
printArray(a);
}

/**
* 查找要插入的元素在有序数组中将要插入的位置。
*
* @param a 有序数组
* @param orderedSequenceEndIndex 有序数组中最后的元素的下标。
* @param toBeInserted 要插入的元素
* @return
*/
private static int findInsertIndex(int[] a, int orderedSequenceEndIndex, int toBeInserted) {
int insetIndex = 0;
int i = 0;
for (; i <= orderedSequenceEndIndex; i++) {
// 如果输入的比扫描到的数小
if (toBeInserted < a[i]) {
// 则应该在这里插入输入的数
insetIndex = i;
break;
}
}
if (insetIndex == 0) {
insetIndex = i;
return insetIndex;
}
return insetIndex;
}

/**
* 为要插入的元素腾出空间
*
* @param a 保存有序序列的数组
* @param lastIndexOfNew 插入元素之后形成的新的有序序列的最后一个元素的下标
* @param insetIndex 要插入的下标
*/
private static void makeRoomForInsertion(int[] a, int lastIndexOfNew, int insetIndex) {
// 如果要插入的位置,在原来有序序列的最后面
if (insetIndex == lastIndexOfNew) {
// 那么不需要平移元素
return;
}
// 从后向前扫描
for (int i = lastIndexOfNew + 1, temp; i > insetIndex; i--) {
// 所有的元素往后移动一格
temp = a[i];
a[i] = a[i - 1];
}
}

/**
* 打印数组
*
* @param a 待打印数组
*/
private static void printArray(int[] a) {
for (int i = 0; i < a.length; i++) {
System.out.print(a[i]);
if (i < a.length - 1)
System.out.print(",");
}
System.out.println();
}
}

7、在一个有序的数组中,利用折半法进行查找;

https://baike.baidu.com/item/%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE
https://zh.wikipedia.org/wiki/%E4%BA%8C%E5%88%86%E6%90%9C%E5%B0%8B%E6%BC%94%E7%AE%97%E6%B3%95

二分查找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
* 二分查找。
*
* @param a 有序数组
* @param toFind 要查找的整数
* @return 如果在数组中查找到该元素,则返回该元素的索引,
* 否则返回-1表示在数组找不到这个元素。
*/
private static int binarySearch(int[] a, int toFind) {
// 查找序列的开始位置
int start = 0;
// 查找序列的结束位置
int end = a.length - 1;
int middle;
while (start <= end) {
middle = (start + end) / 2;
// 如果待查找的等于中间值,则说明查找到了,输出该元素的位置
if (a[middle] == toFind) {
// System.out.println(toFind + "位于:" + middle + "位置");
// break;
// 返回待查找元素的下标
return middle;
}
// 如果待查元素比中间位置的值大,应该到后面的序列去查找
else if (toFind > a[middle]) {
// 修改待查找的序列的起始位置为中间值的后一个位置
start = middle + 1;
}
// 如果待查元素比中间值小,应该到前面去查找
else {
// 修改待查找的序列的结束位置为中间位置的前面一个位置
end = middle - 1;
}
}
// 返回一个负数作为下标,表示没有查找到该元素
return -1;
}

测试

1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {
int[] a = { 1, 2, 7, 8, 9, 10, 23, 45, 67, 89, 98, 123, 134 };
int toFind = 9;

int index = 0;
if ((index = binarySearch(a, toFind)) >= 0) {
System.out.println("数组中 存在" + toFind + "这个元素,a[" + index + "]=" + a[index]);
} else {
System.out.println("数组中 不存在" + toFind + "这个元素");
}
}

运行结果

1
数组中  存在9这个元素,a[4]=9

8、矩阵的倒置;

水平镜像矩阵

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* 水平镜像矩阵,上面的行保存到下面,下面的行保存到上面。
*
* @param a 保存矩阵的二维数组
*/
private static void mirrorHorizontalMatrix(int[][] a) {
int temp;
for (int i = 0; i <= (a.length - 1) / 2; i++) {
for (int j = 0; j < a[i].length; j++) {
temp = a[i][j];
a[i][j] = a[a.length - 1 - i][j];
a[a.length - 1 - i][j] = temp;
}
}
}

垂直镜像矩阵

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* 对矩阵做垂直镜像操作
*
* @param a 保存矩阵的二维数组。
*/
private static void mirrorVertical(int[][] a) {
int temp;
for (int i = 0; i < a.length; i++) {
for (int j = 0; j <= (a[0].length - 1) / 2; j++) {
temp = a[i][j];
a[i][j] = a[i][a[i].length - 1 - j];
a[i][a[i].length - 1 - j] = temp;
}
}
}

测试

1
2
3
4
5
6
7
8
9
10
11
int[][] a = { 
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 } };
printMatrix(a);
// 水平镜像矩阵
mirrorHorizontalMatrix(a);
printMatrix(a);
// 垂直镜像矩阵
mirrorVertical(a);
printMatrix(a);

运行结果

1
2
3
4
5
6
7
8
9
10
11
|01,02,03|
|04,05,06|
|07,08,09|

|07,08,09|
|04,05,06|
|01,02,03|

|09,08,07|
|06,05,04|
|03,02,01|

9、矩阵相加

https://baike.baidu.com/item/%E7%9F%A9%E9%98%B5%E5%8A%A0%E6%B3%95

通常的矩阵加法被定义在两个相同大小的矩阵。两个m×n矩阵A和B的和,标记为A+B,一样是个m×n矩阵,其内的各元素为其相对应元素相加后的值。例如:

$$
\left[\begin{array}{ll}
1 & 3 \\
1 & 0 \\
1 & 2
\end{array}\right]+\left[\begin{array}{ll}
0 & 0 \\
7 & 5 \\
2 & 1
\end{array}\right]=\left[\begin{array}{ll}
1+0 & 3+0 \\
1+7 & 0+5 \\
1+2 & 2+1
\end{array}\right]=\left[\begin{array}{ll}
1 & 3 \\
8 & 5 \\
3 & 3
\end{array}\right]
$$

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/**
* 判断一个二维数组是否是矩阵。
*
* @param A 保存矩阵的二维数组。
* @return 如果是矩阵的话,则返回true,否是返回false。
*/
public static boolean isMatrix(int[][] A) {
for (int i = 1; i < A.length; i++) {
// 如果其他行的长度与第一行的长度不一样
if (A[i].length != A[0].length) {
// 说明不是矩阵
// System.out.println("不是矩阵");
return false;
}
}
return true;
}

/**
* 判断两个矩阵是否是相同类型的矩阵
*
* @param A 保存矩阵的二维数组
* @param B 另一个保存矩阵的二维数组
* @return 如果这两个矩阵是相同类型的矩阵,则返回true;否则返回false.
*/
public static boolean isSameMatrix(int[][] A, int[][] B) {
// 如果两个二维数组,其中有一个不是矩阵,那没什么好说的
if (!isMatrix(A) || !isMatrix(B)) {
return false;
}
// 如果两个都是矩阵的话,比较行数和第一行的列数即可
return A.length == B.length && A[0].length == B[0].length;
}

/**
* 矩阵加法。
*
* @param A 保存矩阵的二维数组
* @param B 保存矩阵的二维数组
* @return 保存矩阵相加之后的矩阵的二维数组。
*/
public static int[][] matrixAdd(int[][] A, int[][] B) {
int[][] C = new int[A.length][A[0].length];
for (int i = 0; i < A.length; i++) {
for (int j = 0; j < A[i].length; j++) {
C[i][j] = A[i][j] + B[i][j];
}
}
return C;
}

测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static void main(String[] args) {
int[][] A = { { 1, 3 }, { 1, 0 }, { 1, 2 } };
// int[][] A = { { 1, 3, 2 }, { 1, 0, 2 }, { 1, 2, 2 } };
int[][] B = { { 0, 0 }, { 7, 5 }, { 2, 1 } };
MatrixTools.printMatrix(A);
System.out.println(" + ");
MatrixTools.printMatrix(B);

// 只有都是同类型的矩阵才可以相加
if (isSameMatrix(A, B)) {
// System.out.println("相同类型的数组");
int[][] C = MatrixTools.matrixAdd(A, B);
System.out.println(" = ");
MatrixTools.printMatrix(C);
} else {
System.out.println("不是相同类型的矩阵,无法相加");
}
}

运行结果:

1
2
3
4
5
6
7
8
9
10
11
|1 3|
|1 0|
|1 2|
+
|0 0|
|7 5|
|2 1|
=
|1 3|
|8 5|
|3 3|

10、矩阵相乘; M*N N*K

设$A$为$m \times p$的矩阵,$B$为$p \times n$的矩阵,那么称$m \times n$的矩阵$C$位$A$与$B$的乘积,记作$C=AB$,其中矩阵$C$中的第$i$行和第$j$列的元素可以表示为:
$$
(A B)_{i j}=\sum_{k=1}^{p} a_{i k} b_{k j}=a_{i 1} b_{1 j}+a_{i 2} b_{2 j}+\cdots+a_{i p} b_{p j}
$$

如下所示:

$$
A =\left[\begin{array}{lll}
a_{1,1} & a_{1,2} & a_{1,3} \\
a_{2,1} & a_{2,2} & a_{2,3}
\end{array}\right] \\
$$

$$
B =\left[\begin{array}{ll}
b_{1,1} & b_{1,2} \\
b_{2,1} & b_{2,2} \\
b_{3,1} & b_{3,2}
\end{array}\right] \\
$$

$$
C =A B=\left[\begin{array}{ll}
a_{1,1} b_{1,1}+a_{1,2} b_{2,1}+a_{1,3} b_{3,1}, & a_{1,1} b_{1,2}+a_{1,2} b_{2,2}+a_{1,3} b_{3,2} \\
a_{2,1} b_{1,1}+a_{2,2} b_{2,1}+a_{2,3} b_{3,1}, & a_{2,1} b_{1,2}+a_{2,2} b_{2,2}+a_{2,3} b_{3,2}
\end{array}\right]
$$

文字描述

1、当矩阵A的列数(column)等于矩阵B的行数(row)时,A与B可以相乘。

2、矩阵C的行数等于矩阵A的行数,C的列数等于B的列数。

3、乘积C的第m行第n列的元素等于矩阵A的第m行的元素矩阵B的第n列对应元素乘积

示例

$$
C=A B=\left(\begin{array}{lll}
5 & 2 & 4 \\
3 & 8 & 2 \\
6 & 0 & 4 \\
0 & 1 & 6
\end{array}\right)\left(\begin{array}{ll}
2 & 4 \\
1 & 3 \\
3 & 2
\end{array}\right)=\left(\begin{array}{cc}
24 & 34 \\
20 & 40 \\
24 & 32 \\
19 & 15
\end{array}\right)
$$

$$
\left[\begin{array}{lll}
1 & 2 & 3 \\
4 & 5 & 6
\end{array}\right] \times\left[\begin{array}{cc}
7 & 8 \\
9 & 10 \\
11 & 12
\end{array}\right]=\left[\begin{array}{cc}
58 & 64 \\
139 & 154
\end{array}\right]
$$

交换顺序 结果不一样

$$
\begin{aligned}
&{\left[\begin{array}{ll}
1 & 2 \\
3 & 4
\end{array}\right] \times\left[\begin{array}{ll}
2 & 0 \\
1 & 2
\end{array}\right]=\left[\begin{array}{ll}
4 & 4 \\
10 & 8
\end{array}\right]}
\end{aligned}
$$
$$
\begin{aligned}
&{\left[\begin{array}{ll}
2 & 0 \\
1 & 2
\end{array}\right] \times\left[\begin{array}{ll}
1 & 2 \\
3 & 4
\end{array}\right]=\left[\begin{array}{ll}
2 & 4 \\
7 & 10
\end{array}\right]}
\end{aligned}
$$

参考资料

https://baike.baidu.com/item/%E7%9F%A9%E9%98%B5%E4%B9%98%E6%B3%95

https://www.shuxuele.com/algebra/matrix-multiplying.html

矩阵乘法java代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/**
* 返回矩阵A和矩阵B的乘法,C=AB的结果
*
* @param A 保存矩阵的二维数组
* @param B 保存另一个矩阵的二维数组
* @return 保存矩阵A乘以矩阵B的结果AB
*/
public static int[][] matrixMultiplication(int[][] A, int[][] B) {
// 矩阵C的行数等于矩阵A的行数,C的列数等于B的列数
int[][] C = new int[A.length][B[0].length];
// 缓存
int sumIJ = 0;
for (int i = 0; i < C.length; i++) {
for (int j = 0; j < C[i].length; j++) {
for (int k = 0; k < B.length; k++) {
// 乘积C的第m行和第n列的元素,
// 等于矩阵A的第m行元素与矩阵B的第n列元素对应的元素的乘积的和
sumIJ = sumIJ + A[i][k] * B[k][j];
}
C[i][j] = sumIJ;
// 计算下一个元素之前先清零,去除上一次的计算结果
sumIJ = 0;
}
}
return C;
}

/**
* 判断矩阵是否可以相乘。
* 当A的列数,等于矩阵B的行数,是A和B可以相乘。
*
* @param A 保存矩阵的二维数组
* @param B 保存另一矩阵的二维数组
* @return 如果可以相乘,则返回true,不可用相乘,则返回false。
*/
public static boolean canBeMultiplied(int[][] A, int[][] B) {
// 首先要都是矩阵
// 当A的列数,等于矩阵B的行数,是A和B可以相乘
return MatrixTools.isMatrix(A) && MatrixTools.isMatrix(B) && A[0].length == B.length;
}

打印矩阵乘法运算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private static void printmatrixMul(int[][] A, int[][] B) {
MatrixTools.printMatrix(A);
System.out.println(" *");
MatrixTools.printMatrix(B);
System.out.println(" =");
// 当A的列数,等于矩阵B的行数,是A和B可以相乘
if (MatrixTools.canBeMultiplied(A, B)) {
// System.out.println("可以相乘");
int[][] C = MatrixTools.matrixMultiplication(A, B);
MatrixTools.printMatrixMoreBeautiful(C);
} else {
System.out.println("不可相乘");
}
}

其他方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* 判断一个二维数组是否是矩阵。
*
* @param A 保存矩阵的二维数组。
* @return 如果是矩阵的话,则返回true,否是返回false。
*/
public static boolean isMatrix(int[][] A) {
for (int i = 1; i < A.length; i++) {
// 如果其他行的长度与第一行的长度不一样
if (A[i].length != A[0].length) {
// 说明不是矩阵
// System.out.println("不是矩阵");
return false;
}
}
return true;
}

矩阵打印相关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/**
* 打印矩阵
*
* @param a 保存矩阵的二维数组?
*/
public static void printMatrix(int[][] a) {
for (int i = 0; i < a.length; i++) {
System.out.print("|");
for (int j = 0; j < a[i].length; j++) {
if (j > 0) {
// System.out.print(",");
System.out.print(" ");
}
System.out.print(a[i][j]);
}
System.out.println("|");
}
}

/**
* 更美观的打印矩阵.
* 如果矩阵中的最大值为3位数,则打印的每个矩阵元素都占三个位,不足的以0补齐。
*
* @param a 保存矩阵的二维数组。
*/
public static void printMatrixMoreBeautiful(int[][] a) {
int max = findMax(a);
// System.out.println("max=" + max);
int bits = 0;
do {
max = max / 10;
bits++;
} while (max > 0);
// System.out.println("bits="+bits);
printMatrixFormatted(a, bits);
}

/**
* 查找矩阵中的最大值(查找二维数组中的最大值)
*
* @param a 保存矩阵的二维数组。
* @return 矩阵的最大元素。
*/
private static int findMax(int[][] a) {
int max = Integer.MIN_VALUE;
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
if (a[i][j] > max) {
max = a[i][j];
}
}
}
return max;
}

/**
* 打印格式化的矩阵,默认打印两位数,如果一个数小于10,则在前面补0。以占满两个位置。
*
* @param a 保存矩阵的二维数组?
*/
public static void printMatrixFormatted(int[][] a, int numLen) {
for (int i = 0; i < a.length; i++) {
System.out.print("|");
for (int j = 0; j < a[i].length; j++) {
if (j > 0) {
// System.out.print(",");
System.out.print(" ");
}
// 格式化输出,%02d,其中
// d表示数据类型为整数,
// 2表示这个数占据两位,
// 0表示不足的在前面补上0
System.out.printf("%0" + numLen + "d", a[i][j]);
}
System.out.println("|");
}
System.out.println();
}

测试1

$$
C=A B=\left(\begin{array}{lll}
5 & 2 & 4 \\
3 & 8 & 2 \\
6 & 0 & 4 \\
0 & 1 & 6
\end{array}\right)\left(\begin{array}{ll}
2 & 4 \\
1 & 3 \\
3 & 2
\end{array}\right)=\left(\begin{array}{cc}
24 & 34 \\
20 & 40 \\
24 & 32 \\
19 & 15
\end{array}\right)
$$

1
2
3
int[][] A = { { 5, 2, 4 }, { 3, 8, 2 }, { 6, 0, 4 }, { 0, 1, 6 } };
int[][] B = { { 2, 4 }, { 1, 3 }, { 3, 2 } };
printmatrixMul(A, B);

运行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
|5 2 4|
|3 8 2|
|6 0 4|
|0 1 6|
*
|2 4|
|1 3|
|3 2|
=
|24 34|
|20 40|
|24 32|
|19 15|

测试2

$$
\left[\begin{array}{lll}
1 & 2 & 3 \\
4 & 5 & 6
\end{array}\right] \times\left[\begin{array}{cc}
7 & 8 \\
9 & 10 \\
11 & 12
\end{array}\right]=\left[\begin{array}{cc}
58 & 64 \\
139 & 154
\end{array}\right]
$$

1
2
3
int[][] A = { { 1, 2, 3 }, { 4, 5, 6 } };
int[][] B = { { 7, 8 }, { 9, 10 }, { 11, 12 } };
printmatrixMul(A, B);

运行结果

1
2
3
4
5
6
7
8
9
|1 2 3|
|4 5 6|
*
|7 8|
|9 10|
|11 12|
=
|058 064|
|139 154|

测试3

$$
\begin{aligned}
&{\left[\begin{array}{ll}
1 & 2 \\
3 & 4
\end{array}\right] \times\left[\begin{array}{ll}
2 & 0 \\
1 & 2
\end{array}\right]=\left[\begin{array}{ll}
4 & 4 \\
10 & 8
\end{array}\right]}
\end{aligned}
$$

$$
\begin{aligned}
&{\left[\begin{array}{ll}
2 & 0 \\
1 & 2
\end{array}\right] \times\left[\begin{array}{ll}
1 & 2 \\
3 & 4
\end{array}\right]=\left[\begin{array}{ll}
2 & 4 \\
7 & 10
\end{array}\right]}
\end{aligned}
$$

1
2
3
4
5
6
int[][] A = { { 1, 2 }, { 3, 4 } };
int[][] B = { { 2, 0 }, { 1, 2 } };
System.out.println("AB=");
printmatrixMul(A, B);
System.out.println("BA=");
printmatrixMul(B, A);

运行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
AB=
|1 2|
|3 4|
*
|2 0|
|1 2|
=
|04 04|
|10 08|
BA=
|2 0|
|1 2|
*
|1 2|
|3 4|
=
|02 04|
|07 10|

11、打印杨辉三角前20行;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
public static void main(String[] args) {
int length = 20;
int[][] yh = yangHui(length);
printYangHui(yh);
// printHangHui1(length);
}

private static int[][] yangHui(int length) {
// 变长的二维数组
int[][] yh = new int[length][];
for (int i = 0; i < yh.length; i++) {
// 创建第2维的数组
yh[i] = new int[i + 1];
}
//
for (int i = 0; i < length; i++) {
for (int j = 0; j < yh[i].length; j++) {
// 第1列和最后一列的值为1
if (j == 0 || i == j) {
yh[i][j] = 1;
} else {
// 当前元素,等于正上方的元素 与 正上方的前一个元素的和
yh[i][j] = yh[i - 1][j] + yh[i - 1][j - 1];
}
}
}
return yh;
}

/**
* 打印杨辉三角形
*
* @param yh 保存杨辉三角形的变长二维数组.
*/
private static void printYangHui(int[][] yh) {
// 杨辉三角形最大值,最后一行的中间位置的值
int max = yh[yh.length - 1][yh.length / 2];
// 格式化打印,每个数的长度都与最大的数的长度一样
printYangHuiFormatted(yh, countBits(max));
}

/**
* 格式化打印杨辉三角形
*
* @param a 保存杨辉三角形的二维数组
* @param maxNumLength 杨辉三角形中最大的数字有多少个数字字符。
*/
public static void printYangHuiFormatted(int[][] a, int maxNumLength) {
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
// 打印分隔符
if (j > 0) {
System.out.print(" ");
}
// 打印空白符,使得小的的数的宽度和最大的数的宽度一样
for (int k = 0; k < maxNumLength - countBits(a[i][j]); k++) {
System.out.print(" ");
}
// 打印元素
System.out.print(a[i][j]);
}
System.out.println();
}
System.out.println();
}

/**
* 计算一个整数有几位数。
*
* @param num 整数
* @return 该整数有多少个整数。
*/
public static int countBits(int num) {
int bits = 0;
do {
num = num / 10;
bits++;
} while (num > 0);
return bits;
}

运行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
1 11 55 165 330 462 462 330 165 55 11 1
1 12 66 220 495 792 924 792 495 220 66 12 1
1 13 78 286 715 1287 1716 1716 1287 715 286 78 13 1
1 14 91 364 1001 2002 3003 3432 3003 2002 1001 364 91 14 1
1 15 105 455 1365 3003 5005 6435 6435 5005 3003 1365 455 105 15 1
1 16 120 560 1820 4368 8008 11440 12870 11440 8008 4368 1820 560 120 16 1
1 17 136 680 2380 6188 12376 19448 24310 24310 19448 12376 6188 2380 680 136 17 1
1 18 153 816 3060 8568 18564 31824 43758 48620 43758 31824 18564 8568 3060 816 153 18 1
1 19 171 969 3876 11628 27132 50388 75582 92378 92378 75582 50388 27132 11628 3876 969 171 19 1

13、找出两个数组的交集

数组1的元素有: 21,3,33,89,16;

数组2的元素有: 33,78,15,16,48,57

则结果为:33,16

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
public class HW_13_Intersection {
public static void main(String[] args) {
int[] A = { 21, 3, 33, 89, 16 };
int[] B = { 33, 78, 15, 16, 48, 57 };
int[] C1 = intersection(A, B);
ArrayTools.printArray(C1);
ArrayTools.printArray(intersection2(A, B));
}

/**
* 求数组的交集
*
* @param A 数组A
* @param B 数组B
* @return 数组A和数组B的交集
*/
private static int[] intersection(int[] A, int[] B) {
int[] C;
if (A.length < B.length) {
C = new int[A.length];
} else {
C = new int[B.length];
}
int count = 0;
for (int i = 0; i < A.length; i++) {
for (int j = 0; j < B.length; j++) {
if (A[i] == B[j]) {
// System.out.println(A[i]);
C[count++] = A[i];
}
}
}
int[] D = new int[count];
for (int i = 0; i < count; i++) {
D[i] = C[i];
}
return D;
}

/**
* 求两个数组的交集,求两个数组共有的元素.
*
* @param A 数组A
* @param B 数组B
* @return 数组A和数字B的交集
*/
private static int[] intersection2(int[] A, int[] B) {
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < A.length; i++) {
for (int j = 0; j < B.length; j++) {
if (A[i] == B[j]) {
list.add(A[i]);
}
}
}
return list.stream().mapToInt(Integer::valueOf).toArray();
}
}

运行结果

1
2
{33,16}
{33,16}