JAVA基础 第一篇:素数、合数、质数分解、最大公约数、最小公倍数

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

 

你可能感兴趣的:(JAVA基础 第一篇:素数、合数、质数分解、最大公约数、最小公倍数)