两个一前一后被被调用的方法 也应该一前一后的写在一起。

设想一下如下的情况:

  • 主方法中,先调用了方法A,然后调用方法B.
  • 或者方法A中调用了方法B

这种情况下,我们在阅读程序时,也是先阅读方法A,然后再阅读方法B。
所以我希望这两个方法按调用的顺序写在一起,这样我阅读的时候,就不需要上下翻动页面去查找方法。
直接往下阅读即可看到,下一个被调用的方法。

eclipse中拖动方法的位置

在Outline中长按方法,并拖动其他方法的前面或后面即可:
图片
图片

Preference中搜索Formatter

Preference然后搜索Fromatter,进入Formatter,然后edit。
图片

然后搜索Comments

图片

函数

main(){

}

推动软件发展的动力

  • 软件的复用
  • 尽量接近自然语言

C语言可重用的粒度为函数

Java面向对象可重用的粒度为对象

函数的作用

封装一段功能,方便软件复用

函数的定义

1
2
3
返回类型 函数名(形参列表){
函数体;
}

变量不要使用单独的字母,特别是l和o,这两个字母和数字1和0容易分不清。

形参列表

如下返回值的写法否有语法错误

1
return a,b;

逗号表达式

1
表达式1,表达式2

先执行表达式1,再执行表达式2;

定义函数

1
2
3
4
5
int max(int a,int b)
{
if(a>b) return a;
return b;
}

更简单的写法

1
2
3
4
int max(int a,int b)
{
return a>b?a:b;
}

函数和普通数据类型都在栈空间,只有对象在堆空间。

调用

1
2
3
4
5
main()
{
int m=5,n=6;
int c=max(m,n);
}

编程题 写一个判断素数和闰年的函数

编程题 写一个日历

输入年月日,判断这个日期是年中的第几天。
判断星期几。
1990年1月1日,星期一

判断输入的日期到,1990年1月1日有多少天,然后在%7,即可得到星期。

传值 传地址 交换地址,交换地址的空间里面的内容

1
2
3
4
5
6
7
8
9
10
11
void swap(int a,int b){
int temp=b;
b=a;
a=temp
}
main(){
int a=5,b=6;
swap(a,b);
print a;
print b;
}

问,打印的a和b的值。

不会交换

1
2
3
4
5
6
7
8
9
10
11
void swap(int *a,int *b){
int *temp=b;
b=a;
a=temp
}
main(){
int a=5,b=6;
swap(&a,&b);
print a;
print b;
}

是否有交换?

不会交换,只交换地址而已,没有交换地址里面的数据。

1
2
3
4
5
6
7
8
9
10
11
void swap(int *a,int *b){
int temp=*b;
*b=*a;
*a=temp
}
main(){
int a=5,b=6;
swap(&a,&b);
print a;
print b;
}

是否有交换

有,交换了地址对应的空间里面的值

递归函数

double f(int n){
if(n==0||n==1) return 1;
return f(n-1)*n;
}

编程题 递归斐波那契第n项的值

String类

scanner.next(),以空格或回车作为结束符
scanner.nextLine(),以回车符作为结束符。

指针

内存以字节编址,32位系统,内存地址编址有32个bit表示。

int m=20;
变量m占据4个字节。

C语言中

1
2
3
4
// 定义一个指针变量
int *p;
// 把变量m的地址放到指针遍历p中
p=&m;

指针变量p只会记录数据的首地址,因为地址的长度都是一样的,所以指针的大小都是一样的。

1
2
int a;
a=*p+10

*p表示到指针变量p取值,int占用4个字节,所以*p连续取出4个字节。

1
p++

等价于

1
p=p+1*sizeof(int)

把int类型的m的地址赋值给char类型的指针是否可以?

1
2
char *t;
t=&m;

可以,但取值的时候会出错。

强制类型转换

1
2
char *t;
t=(char*)&m;

强制吧m的地址赋值给char变量t。

1
2
int m=30
char k='A';

k赋值给m是否有问题?

1
m=k;

没问题。
m赋值给k有没有问题?

1
k=m;

有问题。

二维数组

C语言写法

1
int a[3][4];

内存条没有二维的,所以,二维数组得转换为一维的来存储。

行序优先存储

Java二维数组写法1

1
2
3
4
//还没有分配空间。
int a[][];
// 分配连续的空间
a=new int[3][4];

后续使用
a[0][1]

另一种二维数组的写法

1
2
3
4
int[][] a=new[3][];
a[0]=new int[2];
a[1]=new int[3];
a[2]=new int[4];

此时分配的空间就不连续了。

问:java中二维数组数组的空间是不是都是连续的
答,不一定。

a.length表示的是行的数目
a[0].length表示第一行的列数

初始化

静态初始化

1
int a[][]={{1,2,3},{4,5},{7}};

静态初始化只能在声明是使用,不能先声明再初始化。
也就是如下写法是错误的:

1
2
int a[][];
a[][]={{1,2,3},{4,5},{7}};

编程题 从键盘接收10个数,存储为2*5的矩阵,并打印出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class InputMatrix {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int[][] array=new int[2][5];
System.out.println("请输入10个数");
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
array[i][j]=scanner.nextInt();
}
}

for (int i = 0; i < array.length; i++) {
System.out.print("|");
for (int j = 0; j < array[i].length; j++) {
System.out.printf("%2s",array[i][j]);
if(j<array[i].length-1) {
System.out.print(",");
}
}
System.out.print("|");
System.out.println();
}
}
}

编程题 找鞍点

二维数组中的一个元素,该元素在当前行中是最大的,但是在该元素所在的列是最小的。
例如,在如下的二维数组中:

1
2
3
1 2 3
4 5 6
7 8 9

3就是鞍点。
查找二维数组的鞍点

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
public class SaddlePoint {
public static void main(String[] args) {
int[][] a = { { 1, 3, 2 }, { 4, 5, 6 }, { 7, 8, 9 } };
int maxInRow, minInCol;
for (int i = 0; i < a.length; i++) {
maxInRow = 0;
for (int j = 1; j < a[i].length; j++) {
// 如果在该行中有更大的值
if (a[i][j] > a[i][maxInRow]) {
// 则记下更大的值得下标
maxInRow = j;
}
}
// 遍历当前行最大的元素所在的列。
int k;
for (k = 0; k < a.length; k++) {
// 如果该列中有更小的值
if (a[k][maxInRow] < a[i][maxInRow]) {
// 当前行中最大的值在其所在的列中不是最小的
break;
}
}
// 如果找到最后,没有找到更小的值,则说明a[i][maxInRow]是该列中最小的,此时k等于列的长度
if (k == a.length) {
System.out.print("鞍点:a[" + i + "][" + maxInRow + "]=" + a[i][maxInRow]);
}
}
}
}

编程题 输出杨辉三角

1
2
3
4
5
6
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
......

编译

  编译javac                        java解释给JVM   

Java———->中间码(字节码).class——————->平台1 的JVM 来执行
|
|———————->平台2 的JVM 来执行

C语言
简化的main方法

1
2
3
4
5
6
int main(){

}
void main(){

}

完整的main

1
2
3
int main(int argsnum,char[][] args){

}

环境变量

做什么用,

例如你在命令行cmd中输入一个copy,cmd如何知道copy命令的可执行文件在字在哪里呢?
先在当前目录下查找copy的执行性文件
如果没有找到则到系统文件中取查找可执行性文件
如果系统中也没有该命令,则到系统中的PATH环境变量中记录的地址中取查找该命令的可执行性文件
如果PATH中的记录的地址也没有找到,则报错,说明找不到该可执行性文件。

Chrome手动安装IDM插件IDM Integration Module

输入IDM在Chrome商店的网址进行安装

在Chrome商店中输入IDM Integration Module无法直接搜索到该插件,可以输入如下的地址进行访问:

1
https://chrome.google.com/webstore/detail/idm-integration-module/ngpampappnmepgilojfohadhhmbhlaek

拖动IDM安装目录下的 IDMGCExt.crx 文件到Chrome中进行安装

进入Chrome扩展程序界面,或者输入如下地址进入:

1
chrome://extensions/

然后,进入IDM的安装路径,找到IDMGCExt.crx文件,把它拖动到Chrome扩展程序界面中进行安装

1
C:\Program Files (x86)\Internet Download Manager\IDMGCExt.crx

取消IDM更新提示

打开注册表,进入路径:

1
计算机\HKEY_CURRENT_USER\SOFTWARE\DownloadManager

找到名称为

1
LstCheck

的数据项,然后双击它,这个数据项保存的是更新提示的日期,最后一个数是当前年,把最后一个数的年份修改为99。
也就是2099年才显示更新提示。

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}

1、输入一个3位的整型数,输入其百位、十位及个位数;

SplitInteger.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* 输入一个3位的整型数,输入其百位、十位及个位数;
*/
public class SplitInteger {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int hundredDigit, tenDigit, singleDigits;
int input = scanner.nextInt();
// 除以100,取出百位数
hundredDigit = input / 100;
// 减去百位数,剩下十位数和个位数,再除以10,取出十位数。
tenDigit = (input - hundredDigit * 100) / 10;
// 求余10,取出个位数
singleDigits = input % 10;
System.out.println(input + "的百位数:" + hundredDigit + ",十位数:" + tenDigit + ",个位数:" + singleDigits);
}
}

2、判断一个数是否是素数?

质数又称素数。一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数;

参考资料

https://oi-wiki.org/math/prime/
https://blog.csdn.net/adamjy/article/details/23514531

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* 判断一个数是否是质数
*
* @param n 一个整数
* @return 如果n是质数,则返回true,否则返回false
*/
public static boolean isPrime(int n) {
// 2和3都是质数
if (n <= 3) {
// 质数都要大于1
return n > 1;
}
int sqrt = (int) Math.sqrt(n);
for (int i = 2; i <= sqrt; i++) {
// 如果n能被小于等于sqrt(n)的整数整除的话,不符合质数的定义,则说明不是质数
if (n % i == 0) {
return false;
}
}
return true;
}

3、百分制转成等级制( 利用 if 和 swtich 两种语句格式写)

利用if

ConvertPercentileScoresToGradedScoresByIf.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
/**
* 百分制转成等级制-利用 if
*/
public class ConvertPercentileScoresToGradedScoresByIf {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int scores = scanner.nextInt();
if (scores > 100) {
System.out.println("成绩必须小于100");
} else if (scores >= 90) {
System.out.println("A");
} else if (scores >= 80) {
System.out.println("B");
} else if (scores >= 70) {
System.out.println("C");
} else if (scores >= 60) {
System.out.println("D");
} else if (scores >= 0) {
System.out.println("E");
} else {
System.out.println("成绩必须大于0");
}
}
}

利用switch

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
/**
* 百分制转成等级制-利用switch
*/
public class ConvertPercentileScoresToGradedScoresBySwitch {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int scores = scanner.nextInt();
if (scores >= 0 && scores <= 100) {
switch (scores / 10) {
case 10:
case 9:
System.out.println("A");
break;
case 8:
System.out.println("B");
break;
case 7:
System.out.println("C");
break;
case 6:
System.out.println("D");
break;
default:
System.out.println("E");
}
} else {
System.out.println("请输入[1,100]区间内的数");
}
}
}

5、企业发放的奖金根据利润提成。

企业发放的奖金根据利润提成。利润(I)

  • 低于或等于10万元时,奖金可提10%;

  • 利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可可提 成7.5%;

  • 20万到40万之间时,高于20万元的部分,可提成5%;

  • 40万到60万之间时高于 40万元的部,可提成3%;

  • 60万到100万之间时,高于60万元的部分,可提成1.5%,

  • 高于 100万元时,超过100万元的部分按1%提成,

从键盘输入当月利润I,求应发放奖金总数?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static void main(String[] args) {
// Scanner scanner = new Scanner(System.in);
int lirun;
// lirun = scanner.nextInt();
lirun = 600;
double jiangjin = 0;
if (lirun <= 10) {
jiangjin += lirun * 0.1;
} else if (lirun < 20) {
jiangjin += 0.1 + (lirun - 10) * 0.075;
} else if (lirun < 40) {
jiangjin += 0.1 + (lirun - 10) * 0.075 + (lirun - 20) * 0.05;
} else if (lirun < 60) {
jiangjin += 0.1 + (lirun - 10) * 0.075 + (lirun - 20) * 0.05 + (lirun - 40) * 0.03;
} else if (lirun < 100) {
jiangjin += 0.1 + (lirun - 10) * 0.075 + (lirun - 20) * 0.05 + (lirun - 40) * 0.03 + (lirun - 60) * 0.015;
} else {
jiangjin += 0.1 + (lirun - 10) * 0.075 + (lirun - 20) * 0.05 + (lirun - 40) * 0.03 + (lirun - 60) * 0.015
+ (lirun - 100) * 0.01;
}
System.out.println(jiangjin);
}

7、判断101-200之间有多少个素数,并输出所有素数。

与第2题重复了,见第二题

8、计算s=1+2+…+100。

Sum1to100.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* 计算s=1+2+…+100。
*/
public class Sum1to100 {
public static void main(String[] args) {
int sum=0;
for(int i=1;i<=100;i++)
{
sum+=i;
}
System.out.println(sum);
}
}

9、打印出所有的“水仙花数”

所谓“水仙花数”是指一个三位数,其各位数字立方和等于该数 本身。例如:153是一个“水仙花数”,因为153=1的三次方+5的三次方+3的三次方。

NarcissisticNumber.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* 求100到999的水仙花数
* 例如: 153 = 1*1*1 + 5*5*5 + 3*3*3.
*/
public class NarcissisticNumber {
public static void main(String[] args) {
int hundreds, tens, ones;
System.out.print("水仙花数:");
for (int i = 100; i < 999; i++) {
// 除以100得到百位数
hundreds = (i / 100);
// 求余100得到十位数和个位数,再除以10得到十位数
tens = i % 100 / 10;
// 求余10得到十位数
ones = i % 10;
if (i == (hundreds * hundreds * hundreds + tens * tens * tens + ones * ones * ones)) {
System.out.print(i+" ");
}
}
}
}

10 找出1000以内的所有完数

一个数如果恰好等于它的因子之和,这个数就称为“完数”。例如6=1+2+3.编程找出1000以内的所有完数

如果一个数恰好等于它的真因子之和,则称该数为“完全数”。第一个完全数是6,第二个完全数是28,第三个完全数是496,后面的完全数还有8128、33550336等等。截至2018年,相关研究者已经找到51个完全数。

性质

所有的完全数都是三角形数。例如:6=1+2+3;28=1+2+3+…+6+7;496=1+2+3+…+30+31;8128=1+2+3…+126+127。

三角形数

第n个三角形数的公式是n(n+1)/2或者(2n+1)^(2)-1/8。

PerfectNumber.java

PerfectNumber.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class PerfectNumber {
public static void main(String[] args) {
for (int i = 2,sumOfFactors=0; i < 1000; i++) {
// 因子的和
sumOfFactors=0;
for(int j=1;j<i;j++) {
// 如果j是i的因子
if(i%j==0) {
// 因子累加
sumOfFactors+=j;
}
}
// 如果一个数恰好等于它的因子之和,那么就是完数
if(i==sumOfFactors) {
System.out.println("完数:"+i);
}
}
}
}

参考资料

https://baike.baidu.com/item/%E4%B8%89%E8%A7%92%E5%BD%A2%E6%95%B0
http://c.biancheng.net/cpp/html/3324.html

11、求s=a+aa+aaa+aaaa+aa…a的值

其中a是一个数字。例如2+22+222+2222+22222
(此时 共有5个数相加),几个数相加有键盘控制。

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
/**
* 11、求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222 (此时
* 共有5个数相加),几个数相加有键盘控制。
*/
public class Sum_a_aa_aaa {
public static void main(String[] args) {
int sum=0;
int a;
int times;
Scanner scanner = new Scanner(System.in);
System.out.println("输入a:");
a = scanner.nextInt();
System.out.println("输入个数:");
times = scanner.nextInt();

System.out.print("sum=");
for (int i = 0; i <=times; i++) {
int temp = a;
for (int j = 1; j < i; j++) {
temp = temp * 10 + a;
}
System.out.print(temp);
if(i<times) {
System.out.print("+");
}
sum=sum+temp;
}
System.out.println("\n ="+sum);
}
}

12、有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13…求出这个数列的前20项之和。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public static void main(String[] args) {
double fenmu = 1;
double fenzi = 2;
double sum = 0.0;
double temp;
for (int i = 0; i < 20; i++) {
if (i > 0)
System.out.print(" + ");
System.out.print((int)fenzi + "/" + (int)fenmu);
// 求和
sum += fenzi / fenmu;
// 记下分母的值
temp = fenmu;
// 前一个的分子作为下次计算的分母
fenmu = fenzi;
// 前一个分子的值加上前一个分母的值作为下次计算的分子
fenzi = fenzi + temp;
if((i+1)%5==0) {
System.out.println();
}
}
System.out.println("=" + sum);
}

运行结果:

1
2
3
4
5
2/1 + 3/2 + 5/3 + 8/5 + 13/8
+ 21/13 + 34/21 + 55/34 + 89/55 + 144/89
+ 233/144 + 377/233 + 610/377 + 987/610 + 1597/987
+ 2584/1597 + 4181/2584 + 6765/4181 + 10946/6765 + 17711/10946
=32.66026079864164

13、一个5位数,判断它是不是回文数。

14、输入一个数,判断它是不是回文数。

设n是一任意自然数。若将n的各位数字==反向排列==所得自然数n1与n相等,则称n为一回文数。例如,若n=1234321,则称n为一回文数;但若n=1234567,则n不是回文数。
注意:
1.偶数个的数字也有回文数124421

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
/**
* 判断一个整数是不是回文数.
*
* @param n 整数
* @return 如果是回文数的话,就返回true,否则返回false.
*/
private static boolean isPalindromeNumberPerfect(int n) {
// 如果把这个整数倒序之后还是和这个数相等的话,那么它就是回文数。
return n == reverseInt(n);
}

/**
* 反转一个整数,例如12345,反转后变成54321
*
* @param m 一个整数
* @return 反转后的整数
*/
private static int reverseInt(int m) {
// 保存反转之后的数值
int inversion = 0;
// 余数
int remainder;
do {
remainder = m % 10;
m = m / 10;
// 根据10的余数,计算出反转的数值
inversion = inversion * 10 + remainder;
} while (m > 0);
// System.out.println(inversion);
// 返回反转后的数值
return inversion;
}

测试:输出10到10000内的所有回文数

1
2
3
4
5
6
7
8
9
boolean isNotFirst = false;
for (int i = 10; i < 10000; i++) {
if (isPalindromeNumberPerfect(i)) {
if (isNotFirst)
System.out.print(",");
System.out.print(i);
isNotFirst = true;
}
}

运行结果:

1
11,22,33,44,55,66,77,88,99,101,111,121,131,141,151,161,171,181,191,202,212,222,232,242,252,262,272,282,292,303,313,323,333,343,353,363,373,383,393,404,414,424,434,444,454,464,474,484,494,505,515,525,535,545,555,565,575,585,595,606,616,626,636,646,656,666,676,686,696,707,717,727,737,747,757,767,777,787,797,808,818,828,838,848,858,868,878,888,898,909,919,929,939,949,959,969,979,989,999,1001,1111,1221,1331,1441,1551,1661,1771,1881,1991,2002,2112,2222,2332,2442,2552,2662,2772,2882,2992,3003,3113,3223,3333,3443,3553,3663,3773,3883,3993,4004,4114,4224,4334,4444,4554,4664,4774,4884,4994,5005,5115,5225,5335,5445,5555,5665,5775,5885,5995,6006,6116,6226,6336,6446,6556,6666,6776,6886,6996,7007,7117,7227,7337,7447,7557,7667,7777,7887,7997,8008,8118,8228,8338,8448,8558,8668,8778,8888,8998,9009,9119,9229,9339,9449,9559,9669,9779,9889,9999

15、输入2个正整数m,n,求其最大公约数和最小公倍数。

参考资料

辗转相除法 求最大公约数

https://zhuanlan.zhihu.com/p/31824895

辗转相除法, 又名欧几里得算法(Euclidean algorithm),目的是求出两个正整数的最大公约数。它是已知最古老的算法, 其可追溯至公元前300年前。

这条算法基于一个定理:两个正整数a和b(a>b),它们的最大公约数等于a除以b的余数c和b之间的最大公约数。比如10和25,25除以10商2余5,那么10和25的最大公约数,等同于10和5的最大公约数。

有了这条定理,求出最大公约数就简单了。我们可以使用递归的方法来把问题逐步简化。

首先,我们先计算出a除以b的余数c,把问题转化成求出b和c的最大公约数;然后计算出b除以c的余数d,把问题转化成求出c和d的最大公约数;再然后计算出c除以d的余数e,把问题转化成求出d和e的最大公约数……

以此类推,逐渐把两个较大整数之间的运算简化成两个较小整数之间的运算,直到两个数可以整除,或者其中一个数减小到1为止

求最小公倍数

两个正整数A、B,他们的最大公约数和最小公倍数的乘积就等于这两个数的乘积(A*B)。

最小公倍数=(A*B)/最大公约数
最小公倍数=两整数的乘积÷最大公约数

程序 辗转相除法求最大公约数

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
public class GreatestCommonDivisor {
public static void main(String[] args) {
int a, b;
a = 1;
b = 2;
int gcd = getGCD(a, b);
System.out.println(a + "和" + b + "的最大公约数为:" + gcd + ",最小公倍数为:" + (a * b) / gcd);
}

/**
* 辗转相除法求最大公约数入口
*
* @param a
* @param b
* @return
*/
private static int getGCD(int a, int b) {
if (a > b) {
return gcd(a, b);
} else {
return gcd(b, a);
}
}

/**
* 辗转相除法求最大公约数
*
* @param bigNumber 两个数中大的数
* @param smallNumber 两个数之中小的数
* @return 最大公约数的值
*/
private static int gcd(int bigNumber, int smallNumber) {
int remainder = bigNumber % smallNumber;
if (remainder == 0) {
return smallNumber;
} else {
return gcd(smallNumber, remainder);
}
}
}

https://baike.baidu.com/item/%E6%9C%80%E5%A4%A7%E5%85%AC%E7%BA%A6%E6%95%B0

16、请编程序打印出以下数列:1、1、2、3、5、8、13、…的前40项。每行输出4个数。(斐波那契数列)

https://zh.wikipedia.org/wiki/%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E6%95%B0

数学上,斐波那契数是以递归的方法来定义:

$$
\begin{cases}
F_{0}=0 \\
F_{1}=1 \\
F_{n}=F_{n-1}+F_{n-2} (n \ge 2)
\end{cases}
$$

https://baike.baidu.com/item/%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E6%95%B0%E5%88%97

斐波那契数列由0和1开始,之后的斐波那契数就是由之前的两数相加而得出。首几个斐波那契数是:

1
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377 ,610, 987

特别指出:0不是第一项,而是第零项。

求斐波那契数列第n项 递归实现

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* 求第n项斐波那契数列的值,递归实现
*
* @param n 第几项斐波那契数列的值,n从1开始。
* @return 第n项斐波那契数列的值
*/
public static int fibonacciRecursive(int n) {
if (n <= 2) {
return 1;
}
return fibonacciRecursive(n - 1) + fibonacciRecursive(n - 2);
}

求斐波那契数列第n项 循环实现

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
/**
* 求斐波那契数列的第n项
*
* @param n 要求斐波那契数列的第几项,n从1开始。
* @return 斐波那契数列的第n项
*/
private static long fibonacciLoop(int n) {
if (n <= 1)
return 1;
long first = 1;
long second = 1;
// System.out.print(first + "," + second + ",");
long temp;
for (int i = 2; i < n; i++) {
// 缓存第1项的值
temp = first;
// 第1项的值等于原来第2项的值
first = second;
// 第2项等于原来第2项的值加上原来第1项的值
second = second + temp;
// if (i > 2)
// System.out.print(",");
// System.out.print(second);
}
return second;
}

缓存已经计算过得斐波那契数列的项

下次遇到已经计算过斐波那契数列项的直接返回,没有计算过得才计算。

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
/**
* 斐波那契前n项的缓存数组,已经计算过得第n项保存在这里,
* 第n项保存在fibBuff[n-]里面
*/
static long[] fibBuff = new long[93];
/**
* 给斐波那契数列的第1项和第2项赋值。
*/
static {
fibBuff[1] = 1;
fibBuff[0] = 1;
}

/**
* 求斐波那契数列的第n项
*
* @param n 要求斐波那契的第几项,n最小为1,不要传入0
* @return 斐波那契数列第n项的值
*/
public static long fibBuffRec(int n) {
// 第1项和第2项斐波那契数列的值都是1,直接返回预定的值。
if (n <= 2 && n > 0) {
return fibBuff[n - 1];
}
// 如果数组中没有保存过斐波那契数列的第n项
if (fibBuff[n - 1] == 0) {
// 先计算出斐波那契数列的第n项
fibBuff[n - 1] = fibBuffRec(n - 1) + fibBuffRec(n - 2);
}
// 返回斐波那契数列的第n项
return fibBuff[n - 1];
}

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 打印前40项斐波那契数列
for (int i = 1; i <= 40; i++) {
if (i > 1)
System.out.print(",");
System.out.print(fibonacciLoop(i));
}
System.out.println();
for (int i = 1; i <= 40; i++) {
if (i > 1)
System.out.print(",");
System.out.print(fibonacciRecursive(i));
}
System.out.println();

System.out.println(fibBuffRec(40));
for (int i = 0; i < fibBuff.length; i++) {
if (i > 0)
System.out.print(",");
System.out.print(fibBuff[i]);
}

运行结果

1
2
3
4
1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025,121393,196418,317811,514229,832040,1346269,2178309,3524578,5702887,9227465,14930352,24157817,39088169,63245986,102334155
1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025,121393,196418,317811,514229,832040,1346269,2178309,3524578,5702887,9227465,14930352,24157817,39088169,63245986,102334155
102334155
1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025,121393,196418,317811,514229,832040,1346269,2178309,3524578,5702887,9227465,14930352,24157817,39088169,63245986,102334155,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

17、输入x值,按照公式计算cos(x)的值,直到最后一项小于10^(-6)为止。

$$
\cos (x)=1-\frac{x^{2}}{2!}+\frac{x^{4}}{4!}-\frac{x^{6}}{6!}+…
$$

特殊cos值

$$
\cos 30^{\circ}=\cos \dfrac{\pi}{6}=\dfrac{\sqrt{3}}{2} \approx 0.8660254038
$$

$$
\cos 45^{\circ}=\cos \dfrac{\pi}{4}=\dfrac{\sqrt{2}}{2} \approx 0.7071067812
$$

$$
\cos 60^{\circ}=\cos \dfrac{\pi}{3}=\dfrac{1}{2}=0.5
$$

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private static double cos(double x) {
double cos = 1.0;
int sign = -1;
// 通项公式分母的求阶乘的初始值
int n = 2;
double fenzi = 1.0;
double fenmu = 1.0;
// 当通项还大于10的-6次方,则继续计算
while (fenzi / fenmu >= 1e-6) {
// 计算乘方
fenzi = fenzi * x * x;
// 计算阶乘
fenmu = fenmu * n * (n - 1);
cos = cos + sign * fenzi / fenmu;
// 分母继承的最大数加2
n = n + 2;
// 改变符号
sign = -sign;
}
return cos;
}

测试

1
2
3
System.out.println(cos(Math.PI / 6));
System.out.println(cos(Math.PI / 4));
System.out.println(cos(Math.PI / 3));

运行结果:

1
2
3
0.8660254042103523
0.7071067810719247
0.4999999963909432

18 、输入2个正整数m,n,求其最大公约数和最小公倍数。

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
/**
* 辗转相除法求最大公约数入口
*
* @param a 整数a
* @param b 整数b
* @return 整数a和整数b的最大公约数.
*/
private static int getGCD(int a, int b) {
if (a > b) {
return gcd(a, b);
} else {
return gcd(b, a);
}
}

/**
* 辗转相除法求最大公约数
*
* @param big 两个数中大的数
* @param small 两个数之中小的数
* @return 最大公约数的值
*/
private static int gcd(int big, int small) {
// 求余数
int remainder = big % small;
// 如果余数为0,说明small就是最大公约数
if (remainder == 0) {
return small;
} else {
// 等价于求小的数和余数的最大公约数
return gcd(small, remainder);
}
}

/**
* 求最小公倍数
*
* @param a 整数
* @param b 另一个整数
* @param gcd a和b的最大公约数
* @return a和b的最小公倍数
*/
private static int lcm(int a, int b, int gcd) {
// 两个数的乘积除以最大公约数就是最小公倍数
return (a * b) / gcd;
}

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int a, b, gcd;
a = 5;
b = 10;
gcd = getGCD(a, b);
System.out.println(a + "和" + b + "的最大公约数为:" + gcd + ",最小公倍数为:" + lcm(a, b, gcd));

a = 5;
b = 6;
gcd = getGCD(a, b);
System.out.println(a + "和" + b + "的最大公约数为:" + gcd + ",最小公倍数为:" + lcm(a, b, gcd));

a = 2;
b = 1;
gcd = getGCD(a, b);
System.out.println(a + "和" + b + "的最大公约数为:" + gcd + ",最小公倍数为:" + lcm(a, b, gcd));

运行结果

1
2
3
5和10的最大公约数为:5,最小公倍数为:10
5和6的最大公约数为:1,最小公倍数为:30
2和1的最大公约数为:1,最小公倍数为:2

19、编写一个程序,求如下值:

$$
1-\dfrac{1}{2}+\dfrac{1}{3}-\dfrac{1}{4}+\cdots+\dfrac{1}{99}-\dfrac{1}{100}
$$

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class HW_19_Sum {
public static void main(String[] args) {
System.out.println(sumXX(1));
System.out.println(sumXX(2));
System.out.println(sumXX(3));
System.out.println(sumXX(4));
System.out.println(sumXX(100));
}
private static double sumXX(int times) {
double sum = 1.0;
double sign = -1;
for (int i = 2; i <= times; i++) {
sum = (sum + sign / i);
sign = -sign;
}
return sum;
}
}

运行结果:

1
2
3
4
5
1.0
0.5
0.8333333333333333
0.5833333333333333
0.688172179310195

20、编写一个程序,求e的值。

$$
e \approx 1+\dfrac{1}{1 !}+\dfrac{1}{2 !}+\cdots+\dfrac{1}{n !}
$$

1
2
3
4
5
6
7
8
9
10
11
12
13
14
double e = 1;
// 阶乘的最大一项
int n = 1;
int jieCheng = 1;
while (Math.abs(1.0 / jieCheng) >= 1e-6) {
// 求阶乘
jieCheng = jieCheng * n;
// 求各项的和
e = e + 1.0 / jieCheng;
// 阶乘的最大一项加一
n++;
}
System.out.println(e);
System.out.println(Math.E);

运行结果:

1
2
2.7182818011463845
2.718281828459045

bit,Byte

1Byte=8bit

32位系统和64位系统的区别

32位的电脑的内存只能使用2^32Byte的内存,也就是32位的电脑最多使用4GB的内存条。

32位处理器一次只能处理32位,也就是4个字节的数据;而64位处理器一次就能处理64位,即8个字节的数据。 如果将总长128位的指令分别按16位、32位、64位为单位进行编辑的话:32位的处理器需要4个指令,而64位处理器则只要两个指令。 显然,在工作频率相同的情况下,64位处理器的处理速度比32位的更快。

内存以字节编址

指针的大小都是一样的

编码 原码 反码 补码

第一位表示符号, 其余位表示值.

比如如果是8位二进制:

1
2
[+1]原 = 0000 0001
[-1]原 = 1000 0001

反码

  • 正数的反码是其本身
  • 负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.

补码

补码的表示方法是:

  • 正数的补码就是其本身
  • 负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

补码的补码就是原码

[+17]补码+[-5]补码=
[+17]补码+[-25]补码=

计算机数值范围8位机器:
-128~+127

-0(指代位-128)
8位机器:
+127+1=-128

32位机器的数值范围

-2^(31)~2^(31)-1

32位机器上最小数-2等于多少。

自己写个框架,然后实现,面试好吹牛。

计算机如何表示浮点数

数据类型

int
float
double
char

ASCII码

A-Z
a-z
0-9

声明变量
int m
变量命名规则:

C语言变量名命名规则

  • 只能取字母,数字,下划线
    • 不能以数字开头
  • 大小写敏感

Java语言

  • 只能取字母,数字,下划线,美元符号$

int m=60;
m=62

m=?
答:62

一次定义多个变量

1
int a,b,c;

算数运算符号

加+,减-,乘*,除/,求余数%

输入命令行

Scanner scanner=new Scanner(System.in);

m=scanner.nextInt();

输出

System.out.println();
System.out.println(“Hello”+m);

eclipse使用示例

打开
创建工程
创建包
创建主类

编程题,输入一个三位数,颠倒顺序

颠倒整数顺序

Upside down integer order

eclipse自动补全
eclipse字体调整

逻辑和条件

条件运算符
与&&、或||,非!

如下代码中:
10<=a<=30
c语言中是没有问题的
java语言中是不可以的
(10<=a)<=30
(boolean)<=int
不同类型无法比较,所以错误

条件式:

1
2
3
if(条件式){
多条语句;
}
1
2
3
4
5
6
if(){

}
else{

}

错误写法

1
2
3
if(xxxx);{
xxxx
}

编程题,闰年判断闰年

  • 能被4整数不能被100整除
  • 能被400整除

编程题 整数百分数,转等级

百分制分数转换为等级制分数

Percentage score conversion to a grade score

编程题switch 整数百分数,转等级

编程题 输入年月日 判断它是该年的第几日 判断是否为闰年

循环结构

1
2
3
for(表达式1;条件式;表达式2){
语句块;
}

错误写法:

1
2
3
for(表达式1;条件式;表达式2);{
语句块;
}

编程题

求阶乘
n!=n*(n-1)…32*1

s=1
s=s2
2=s
3

Factorial.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* 求阶乘
* @author 18190
*
*/
public class Factorial {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.print("输入n:");
int n=scanner.nextInt();
int accumulate=1;
for(int i=1;i<=n;i++) {
accumulate=accumulate*i;
}
System.out.println(n+"的阶乘为:"+accumulate);
}
}
1
2
输入n:2
2的阶乘为:2
1
2
输入n:3
3的阶乘为:6
1
2
输入n:35
35的阶乘为:0

求水仙花数(100~999)

所谓的水仙花数是指:一个 n 位数 ( n≥3 ),它的每个位上的数字的 n 次幂之和等于它本身。例如153,370,371,407等都是水仙花数,就拿153来说,153 = 111 + 555 + 333.

输出所有的“水仙花数”,所谓的“水仙花数”是指一个三位数其各位数字的立方和等于该数本身,例如153是“水仙花数”,因为:153 = 1^3 + 5^3 + 3^3。

Narcissistic number
153=1^3+5^3+4^3

i++和++i的区别

while循环

判断一个数是否为素数

什么时候用for,什么时候有while

循环次数已知的就用for循环,
遍历次数为未知的就用while循环。

单行注释
块注释

编程题

计算根号a

编程题

pi/4=1-1/3+1/5-1/7+1/9-…+1/n
pi/4=

-1/3+1/5-1/7+1/9-…+1/n
-3=21+1
5=2
2+1
-7=2*3+1

(-1)^(i%2)/(2*i+1)

当算到1/n<10^(-6)=1e-6

丑数

把只包含质因数2,3,5的数称作丑数

1是第一个丑数。

UglyNumber.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* 把只包含质因数2,3,5的数称作丑数
*/
public class UglyNumber {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("输入一个数:");
int n = scanner.nextInt();
int temp = n;
while (n % 2 == 0)
n = n / 2;
while (n % 3 == 0)
n = n / 3;
while (n % 5 == 0)
n = n / 5;
if (n == 1)
System.out.println(temp + "是丑数");
else {
System.out.println(temp + "不是丑数");
}
}
}

素数

问号表达式

1
(条件表达式1)?值1:值2

for循环中的变量尽量在循环体内定义。
拆分整数

数组

a[下标]

定义数组

1
2
int a[]
int[] a;

内存划分

栈空间

栈空间占用的内存,生命周期结束则回收。

堆空间

堆空间的内存由垃圾回收机制回收。

new运算符

堆空间 的内存由new运算符来申请。

new申请的空间,对于数值类型的数据,都赋值为0

内存图

圆圈表示栈空间,方块表示堆空间。

浅拷贝

1
2
int[] a=new int[10];
int[] b=a;

数组长度

1
a.lenth

编程题 在数组中查找最大值最小值

从键盘中输入10个数,并找出最大最小值。

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[minIndex]);
}
}

动态初始化

1
2
3
4
5
int[] a=new int[10];
a[0]=1;
...
a[9]=10;

静态初始化

1
int a[]={1,2,3,4,5,6};

编程题 逆序存储到数组

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]+" ");
}
}
}

编程题 逆序存储静态数组,首位交换

AxisymmetricStaticArray.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class AxisymmetricStaticArray {
public static void main(String[] args) {
int[] a = { 1, 2, 3, 4, 5, 6, 7, 8, 9,10 };
// 轴对称数组
for (int i = 0, temp = 0; i < a.length / 2; i++) {
// 保存前面的数
temp = a[i];
// 交换后面的数到前面
a[i] = a[a.length - 1 - i];
a[a.length - 1 - i] = temp;
}
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
}
}

编程题 十进制转为二进制,顺序输出

十进制整数转换为二进制整数十进制整数转换为二进制整数采用”除2取余,逆序排列“法。
具体做法是:
用2整除十进制整数,可以得到一个商和余数;
再用2去除商,又会得到一个商和余数,
如此进行,直到商为小于1时为止,然后把先得到的余数作为二进制数的低位有效位,后得到的余数作为二进制数的高位有效位,依次排列起来。

789=1100010101(B)

算式 余数 顺序
789/2=394 余1 第10位
394/2=197 余0 第9位
197/2=98 余1 第8位
98/2=49 余0 第7位
49/2=24 余1 第6位
24/2=12 余0 第5位
12/2=6 余0 第4位
6/2=3 余0 第3位
3/2=1 余1 第2位
1/2=0 余1 第1位
ConvertDecimalToBinary.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
/**
* 十进制转为二进制
*/
// 11/2 =5----1
// 5 / 2=2----1
// 2 / 2=1----0
// 1 / 2=0----1
public class ConvertDecimalToBinary {
public static void main(String[] args) {
// 被除数
int dividend = 11;
System.out.print("(" + dividend + ")10=");
// 定义保存余数的数组
int[] remainders = new int[20];
// 定义商
int quotient;
// 余数的计数器
int remainderCounter = 0;
do {
// 求商
quotient = dividend / 2;
// 求余数
remainders[remainderCounter] = dividend % 2;
// 本次的商作为下次的被除数
// 除数和被除数的区分方法是:在除法算式中,除号后面的数叫做除数,除号前面的数叫做被除数。
dividend = quotient;
remainderCounter++;
} while (dividend > 0);
System.out.print("(");
for (int i = remainderCounter - 1; i >= 0; i--) {
System.out.print(remainders[i]);
}
System.out.print(")2");
}
}

下载nvm for windows

进入如下地址下载:
https://github.com/coreybutler/nvm-windows/releases
或者:

1
https://github.com/coreybutler/nvm-windows/releases/download/1.1.7/nvm-setup.zip

安装到C盘

nodejs注意要安装到C盘,如果安装到其他盘,可能会造成无法切换nodejs版本。
图片

修改setting.txt 添加下载node和npm的淘宝镜像

安装完后打开setting.txt添加以下内容,切换node和npm的下载镜像:

1
2
node_mirror: https://npm.taobao.org/mirrors/node/
npm_mirror: https://npm.taobao.org/mirrors/npm/

安装后npm -v无显示的情况

如果不使用淘宝镜像的话,安装的时候,可能只安装上node.exe,安装不上npm.exe。

使用nvm

查看可安装版本

1
nvm list available

运行效果:

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
PS C:\\Users\\haha> nvm list available
| CURRENT | LTS | OLD STABLE | OLD UNSTABLE |
|--------------|--------------|--------------|--------------|
| 16.4.2 | 14.17.3 | 0.12.18 | 0.11.16 |
| 16.4.1 | 14.17.2 | 0.12.17 | 0.11.15 |
| 16.4.0 | 14.17.1 | 0.12.16 | 0.11.14 |
| 16.3.0 | 14.17.0 | 0.12.15 | 0.11.13 |
| 16.2.0 | 14.16.1 | 0.12.14 | 0.11.12 |
| 16.1.0 | 14.16.0 | 0.12.13 | 0.11.11 |
| 16.0.0 | 14.15.5 | 0.12.12 | 0.11.10 |
| 15.14.0 | 14.15.4 | 0.12.11 | 0.11.9 |
| 15.13.0 | 14.15.3 | 0.12.10 | 0.11.8 |
| 15.12.0 | 14.15.2 | 0.12.9 | 0.11.7 |
| 15.11.0 | 14.15.1 | 0.12.8 | 0.11.6 |
| 15.10.0 | 14.15.0 | 0.12.7 | 0.11.5 |
| 15.9.0 | 12.22.3 | 0.12.6 | 0.11.4 |
| 15.8.0 | 12.22.2 | 0.12.5 | 0.11.3 |
| 15.7.0 | 12.22.1 | 0.12.4 | 0.11.2 |
| 15.6.0 | 12.22.0 | 0.12.3 | 0.11.1 |
| 15.5.1 | 12.21.0 | 0.12.2 | 0.11.0 |
| 15.5.0 | 12.20.2 | 0.12.1 | 0.9.12 |
| 15.4.0 | 12.20.1 | 0.12.0 | 0.9.11 |
| 15.3.0 | 12.20.0 | 0.10.48 | 0.9.10 |
This is a partial list. For a complete list, visit https://nodejs.org/download/release
PS C:\\Users\\haha>

参看可切换的版本

1
2
3
4
PS C:\\Users\\haha> nvm list
12.22.3
* 10.24.1 (Currently using 64-bit executable)
PS C:\\Users\\haha>

使用特定版本

1
nvm use 12.22.3

此时会跳出两个窗口,都点确认,就可以切换了。

设置npm的下载的淘宝镜像

1
2
npm config set registry https://registry.npm.taobao.org --global 
npm config set disturl https://npm.taobao.org/dist --global

设置npm的全局安装路径

1
2
npm config set prefix "G:\dev2\nvm\nodejs\node_global"
npm config set cache "G:\dev2\nvm\nodejs\node_cache"

参考资料

https://segmentfault.com/a/1190000020807954

Xshell通过用户名和密码连接远程Linux服务器

具体操作步骤如下图所示:

文件 新建

图片

连接

主要是设置名称和主机:协议的话一般都是SSH,端口号一般也是22。
图片

用户身份验证

方法,这里选择Password,然后在上面的输入框中分别输入用户名和密码。最后点击确定即可:
图片

接受并保存主机秘密

第一次连接的时候会弹出如下警告窗口,点击接受并保存按钮即可。
图片

连接成功效果

图片