1. 问题描述
给定一个大于2的偶数,请用算法实现,将其分解为两个质数的和。
提示:质数是指除了能被1和它自身整除以外,不能被其他任何数整除的整数。
2. 算法分析
从这个问题的描述来看,其实这个算法不是太难,主要是提示信息很明确,基本算是基于提示信息,就很容易将核心的代码写出来,然后套用这个核心的代码,即可将待处理的数分为两个数之和,只有当两个数都是质数的时候,才符合问题答案的要求,即可返回结果。按部就班的将人类语言翻译成机器代码即可解决本问题
1). 判断一个数是否为质数。
主要的逻辑就是将这个数n,循环的进行和【2,n/2】的每一个数进行求余数,只要有一个余数不为0,即得知n不是质数。(充分利用问题的提示信息,翻译成机器语言)
2). 将待处理的偶数x,进行分解,分解为a,x-a两部分(a >=2)
3). 在[a, x/2]之间循环调用步骤1)中的函数,判断步骤2)中的a和x-a是否同时为质数
4). 只有步骤3)返回值为true的时候,退出循环,返回求出的两个质数
注意,上面算法步骤中,之所以考虑到取半数进行处理,是因为待处理的数据和逻辑存在对称效应,所以,为了提高处理性能,避免无效的计算开销,采取取半执行。
3. 代码实现
package even2prime; import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; /** * @author shihuc * @date 2018年6月21日 上午10:35:15 * * 给定一个大于2的偶数,将其分解成两个质数的和。所谓质数,就是指除了1和它自身之外,没有能够被整除的数。 * * 注意: 1即不是质数也不是合数,2是最小的质数。 */ public class Solution { /** * @author shihuc * @param args */ public static void main(String[] args) { Scanner scan = null; try { scan = new Scanner(new File("./src/even2prime/input.txt")); int count = scan.nextInt(); for(int i = 0; i < count; i++){ int even = scan.nextInt(); int prims[] = divEven2Prime(even); System.out.println("No." + i + ": even=" + even + ", prime1=" + prims[0] + ", prime2=" + prims[1]); } } catch (FileNotFoundException e) { e.printStackTrace(); } finally { if (scan != null){ scan.close(); } } } /** * 将目标数据分解为两个质数的具体实现逻辑 * * @author shihuc * @param src * @return */ private static int[] divEven2Prime(int src){ int prime2[] = new int[2]; int middle = src / 2; for(int ele=2; ele <= middle; ele++){ if(isPrime(ele) && isPrime(src - ele)){ prime2[0] = ele; prime2[1] = src - ele; break; } } return prime2; } /** * 判断当前数据是否是一个质数,核心思想是,将待判断的数和[2,src/2]之间的每一个数进行求余,余数为0,则说明该src数不是质数。 * * @author shihuc * @param src * @return */ private static boolean isPrime(int src) { int src2 = 0; if(src == 2){ return true; }else if(src > 2){ src2 = src/2; } boolean flag = true; int next = 2; do{ //核心通过求余数是否为0,判断能否被整除, 另外,为了提升性能,只需要求目标数的一半即可。 if(src % next == 0){ flag = false; break; } next++; }while(next <= src2); return flag; } }
4. 测试数据
7 4 18 100 200 300 4000 10000
5. 运行结果
No.0: even=4, prime1=2, prime2=2 No.1: even=18, prime1=5, prime2=13 No.2: even=100, prime1=3, prime2=97 No.3: even=200, prime1=3, prime2=197 No.4: even=300, prime1=7, prime2=293 No.5: even=4000, prime1=11, prime2=3989 No.6: even=10000, prime1=59, prime2=9941
总结:
1. 对于这种流程性的算法问题,重点抓住问题中的核心提示信息,将其用编程语言描述出来,即可完成问题的处理。
2. 算法问题,需要考虑性能,分析数据和问题逻辑,尽量避免不必要的CPU开销,长期坚持节约或者资源用到刀刃上的习惯,软件质量一般不会差。