JAVA自诞生至今已经有20多年了,在编程界可谓是常青树般地存在,也是目前非常流行的计算机编程语言之一。它的应用领域非常广,比如我们熟知的手机APP,尽管它们运用了不同的JVM以及不同的封装方式,但主要代码还是用JAVA语言编写。当然还有许多其他领域。
在我们接触JAVA初期,会有几块特殊的敲门砖:JAVA关键字、系统自带的直接和Console平台对话的main()方法、循环语句、条件语句……
关于这些JAVA基础在此就不一一累述了。
我们在JAVA学习初期时,会习惯性地将代码统一编写在main()方法中。久而久之我们会发现许多问题:在不同的程序体系中我们经常需要重新编写相同的代码,以至造成了时间的不够支配;如果main()方法中处理的数据比较多,那很容易造成代码的冗余现象,而在编程领域,代码冗余是最为忌讳的。那我们就得考虑能否像main()方法一样自定方法,而在main()方法中我们除了调用相应的方法,仅仅输入相关的输出信息?答案是可以的。
(一)、质数、合数
在此,我们先设计一个自定方法,这个方法用以判断某个数是否为质数,之所以优先选择它,是因为这里面牵涉到了最为基础的条件语句、循环体,并且这个方法的使用范围比较广。在此先申明一下,为了以后能够将其应用到超过int型取值范围以及除法运算的领域中,在此我利用BigDecimal。
/**
* 质数的判断
*
* @param number
* @return
*/
private static boolean primeNumber(BigDecimal number) {
// TODO Auto-generated method stub
for (BigDecimal a = BigDecimal.valueOf(2); a.compareTo(number) < 0; a = a.add(BigDecimal.ONE)) {
if (number.remainder(a).equals(BigDecimal.ZERO))
return false;
}
return true;
}
这个方法是根据质数的含义来设定的。这个方法确定了下来,在以后其他的方法体内只要涉及到质数或者合数,我们都可以利用判断语句调用这个方法。
如果项目要求为质数,我们只需这么写:
if (primeNumber(number)) { }
同样,如果项目要求为合数,我们只需这么写:
if (!primeNumber(number)) { }
而不需要每段代码中都重复编写上述判断体中的整段代码。
我们在main()方法中输出这么一段代码,分别输出100以内的质数、合数:
BigDecimal count = BigDecimal.ZERO;
for (BigDecimal number = BigDecimal.valueOf(2); number.compareTo(BigDecimal.valueOf(100)) <= 0; number = number
.add(BigDecimal.ONE)) {
if (primeNumber(number)) {
System.out.print(number + "\t");
count = count.add(BigDecimal.ONE);
if (count.remainder(BigDecimal.TEN).equals(BigDecimal.ZERO))
System.out.println();
}
}
System.out.println();
System.out.println();
count = BigDecimal.ZERO;
for (BigDecimal number = BigDecimal.valueOf(2); number.compareTo(BigDecimal.valueOf(100)) <= 0; number = number
.add(BigDecimal.ONE)) {
if (!primeNumber(number)) {
System.out.print(number + "\t");
count = count.add(BigDecimal.ONE);
if (count.remainder(BigDecimal.TEN).equals(BigDecimal.ZERO))
System.out.println();
}
}
其运行结果为:
2 3 5 7 11 13 17 19 23 29
31 37 41 43 47 53 59 61 67 71
73 79 83 89 97
4 6 8 9 10 12 14 15 16 18
20 21 22 24 25 26 27 28 30 32
33 34 35 36 38 39 40 42 44 45
46 48 49 50 51 52 54 55 56 57
58 60 62 63 64 65 66 68 69 70
72 74 75 76 77 78 80 81 82 84
85 86 87 88 90 91 92 93 94 95
96 98 99 100
这是100以内的所有质数与合数,当然我们也可以设定“上限”和“下限”,筛选特殊范围内的指数或者合数。
(二)、质数分解
在合数领域,最为需要的算是质数分解了,质数分解为约分和通分、(最大)公约数和(最小)公倍数提供了非常有效的帮助。
质数分解法的首要步骤是提取质因子、质因子的指数。
/**
* 质数分解
*
* @param number
*/
public static void divisorPrime(BigDecimal number) {
// TODO Auto-generated method stub
if (number.compareTo(BigDecimal.valueOf(2)) >= 0) {
for (BigDecimal a = BigDecimal.valueOf(2); a.compareTo(number) <= 0;) {
BigDecimal count = BigDecimal.ZERO;
if (number.remainder(a).equals(BigDecimal.ZERO)) {
while (number.remainder(a).equals(BigDecimal.ZERO)) {
count = count.add(BigDecimal.ONE);
number = number.divide(a);
}
if (count.equals(BigDecimal.ONE))
System.out.print(a);
else if (count.compareTo(BigDecimal.ONE) > 0)
System.out.print(a + " ^ " + count);
if (!number.equals(BigDecimal.ONE))
System.out.print(" * ");
} else
a = a.add(BigDecimal.ONE);
}
} else
System.out.print("null");
}
在这个方法体中,我们利用
number.remainder(BigDecimal.ONE).equals(BigDecimal.ZERO)
这个条件语句来确定number是否为整数,因为数字1能够整除任何整数,也就是说整数被1整除后,余数为0;如果是小数,余数为舍去整数的小数部分,肯定不为0,而为0.几几几。这个条件语句为我们省去了关于精度是否缺失的烦恼和担忧。
当然我们也可以将其单独写成一个方法:
/**
* 判断某个数是否为整数
*
* @param number
* @return
*/
private static boolean intNumber(BigDecimal number) {
// TODO Auto-generated method stub
if (number.remainder(BigDecimal.ONE).equals(BigDecimal.ZERO))
return true;
return false;
}
我们在main()方法中输出这么一段代码:
for (BigDecimal number = BigDecimal.valueOf(2); number.compareTo(BigDecimal.valueOf(100)) <= 0; number = number
.add(BigDecimal.ONE)) {
System.out.print(number + " = ");
divisorPrime(number);
System.out.println();
}
运行结果:
2 = 2
3 = 3
4 = 2 ^ 2
5 = 5
6 = 2 * 3
7 = 7
8 = 2 ^ 3
9 = 3 ^ 2
10 = 2 * 5
11 = 11
12 = 2 ^ 2 * 3
13 = 13
14 = 2 * 7
15 = 3 * 5
16 = 2 ^ 4
17 = 17
18 = 2 * 3 ^ 2
19 = 19
20 = 2 ^ 2 * 5
21 = 3 * 7
22 = 2 * 11
23 = 23
24 = 2 ^ 3 * 3
25 = 5 ^ 2
26 = 2 * 13
27 = 3 ^ 3
28 = 2 ^ 2 * 7
29 = 29
30 = 2 * 3 * 5
31 = 31
32 = 2 ^ 5
33 = 3 * 11
34 = 2 * 17
35 = 5 * 7
36 = 2 ^ 2 * 3 ^ 2
37 = 37
38 = 2 * 19
39 = 3 * 13
40 = 2 ^ 3 * 5
41 = 41
42 = 2 * 3 * 7
43 = 43
44 = 2 ^ 2 * 11
45 = 3 ^ 2 * 5
46 = 2 * 23
47 = 47
48 = 2 ^ 4 * 3
49 = 7 ^ 2
50 = 2 * 5 ^ 2
51 = 3 * 17
52 = 2 ^ 2 * 13
53 = 53
54 = 2 * 3 ^ 3
55 = 5 * 11
56 = 2 ^ 3 * 7
57 = 3 * 19
58 = 2 * 29
59 = 59
60 = 2 ^ 2 * 3 * 5
61 = 61
62 = 2 * 31
63 = 3 ^ 2 * 7
64 = 2 ^ 6
65 = 5 * 13
66 = 2 * 3 * 11
67 = 67
68 = 2 ^ 2 * 17
69 = 3 * 23
70 = 2 * 5 * 7
71 = 71
72 = 2 ^ 3 * 3 ^ 2
73 = 73
74 = 2 * 37
75 = 3 * 5 ^ 2
76 = 2 ^ 2 * 19
77 = 7 * 11
78 = 2 * 3 * 13
79 = 79
80 = 2 ^ 4 * 5
81 = 3 ^ 4
82 = 2 * 41
83 = 83
84 = 2 ^ 2 * 3 * 7
85 = 5 * 17
86 = 2 * 43
87 = 3 * 29
88 = 2 ^ 3 * 11
89 = 89
90 = 2 * 3 ^ 2 * 5
91 = 7 * 13
92 = 2 ^ 2 * 23
93 = 3 * 31
94 = 2 * 47
95 = 5 * 19
96 = 2 ^ 5 * 3
97 = 97
98 = 2 * 7 ^ 2
99 = 3 ^ 2 * 11
100 = 2 ^ 2 * 5 ^ 2
这是对100以内的所有质数、合数分解而得的结果。
(三)、最大公约数、最小公倍数
/**
* 最大公约数
*
* @param number01
* @param number02
*/
private static void maximumCommonDivisor(BigDecimal number01, BigDecimal number02) {
// TODO Auto-generated method stub
System.out.print(number01 + " 和 " + number02 + " 的最大公约数为:");
if (number01.compareTo(BigDecimal.valueOf(2)) >= 0 && number02.compareTo(BigDecimal.valueOf(2)) >= 0
&& intNumber(number01) && intNumber(number02)) {
BigDecimal lowNumber = number01.compareTo(number02) <= 0 ? number01 : number02;
for (BigDecimal number = lowNumber; number.compareTo(BigDecimal.ONE) >= 0; number = number
.subtract(BigDecimal.ONE)) {
if (number01.remainder(number).equals(BigDecimal.ZERO)
&& number02.remainder(number).equals(BigDecimal.ZERO)) {
System.out.println(number);
break;
}
}
}
}
/**
* 最小公倍数
*
* @param number01
* @param number02
*/
private static void minimumCommonMultiple(BigDecimal number01, BigDecimal number02) {
// TODO Auto-generated method stub
System.out.print(number01 + " 和 " + number02 + " 的最小公倍数为:");
if (number01.compareTo(BigDecimal.valueOf(2)) >= 0 && number02.compareTo(BigDecimal.valueOf(2)) >= 0
&& intNumber(number01) && intNumber(number02)) {
BigDecimal highNumber = number01.compareTo(number02) >= 0 ? number01 : number02;
for (BigDecimal number = highNumber;; number = number.add(BigDecimal.ONE)) {
if (number.remainder(number01).equals(BigDecimal.ZERO)
&& number.remainder(number02).equals(BigDecimal.ZERO)) {
System.out.println(number);
break;
}
}
}
}
这个方法体中有两点要注意:一是加入了三目运算符筛选较大值和较小值,因为在运算公约数和公倍数时,位于二者之间的“中间数”都是不符合条件的,因此可以通过这种方法将其排除出去;二是break();语句,加了它只会输出最大公约数或者最小公倍数,如果不加,它将会输出所有的公约数、公倍数,公约数是有限的,公倍数是无限的,因此公倍数将不停地输出下去。
因为我们已经在方法体中加入了System.out.print();System.out.println();语句,因此我们在main()方法中只需直接调用方法就可以了:
maximumCommonDivisor(BigDecimal.valueOf(2), BigDecimal.valueOf(3));
maximumCommonDivisor(BigDecimal.valueOf(5), BigDecimal.valueOf(10));
maximumCommonDivisor(BigDecimal.valueOf(720), BigDecimal.valueOf(360));
maximumCommonDivisor(BigDecimal.valueOf(20), BigDecimal.valueOf(24));
minimumCommonMultiple(BigDecimal.valueOf(2), BigDecimal.valueOf(3));
minimumCommonMultiple(BigDecimal.valueOf(5), BigDecimal.valueOf(10));
minimumCommonMultiple(BigDecimal.valueOf(720), BigDecimal.valueOf(360));
minimumCommonMultiple(BigDecimal.valueOf(20), BigDecimal.valueOf(24));
运行结果:
2 和 3 的最大公约数为:1
5 和 10 的最大公约数为:5
720 和 360 的最大公约数为:360
20 和 24 的最大公约数为:4
2 和 3 的最小公倍数为:6
5 和 10 的最小公倍数为:10
720 和 360 的最小公倍数为:720
20 和 24 的最小公倍数为:120