给定一个大于2的偶数,将其分解为两个质数的和

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的时候,退出循环,返回求出的两个质数

扫描二维码关注公众号,回复: 1677065 查看本文章

注意,上面算法步骤中,之所以考虑到取半数进行处理,是因为待处理的数据和逻辑存在对称效应,所以,为了提高处理性能,避免无效的计算开销,采取取半执行。

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开销,长期坚持节约或者资源用到刀刃上的习惯,软件质量一般不会差。

猜你喜欢

转载自www.cnblogs.com/shihuc/p/9208464.html