zoukankan      html  css  js  c++  java
  • 给定一个大于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的时候,退出循环,返回求出的两个质数

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

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

  • 相关阅读:
    c++ 异常处理 assert | try
    c++ 容器类
    protobuf 向前兼容向后兼容
    命名空间和模块化编程,头文件
    对象3:继承
    动态内存 this指针
    对象2 构造,析构
    对象 1 作用域解析符 ::
    hibernate-criteria查询
    oracle报错:ORA-28000: the account is locked
  • 原文地址:https://www.cnblogs.com/shihuc/p/9208464.html
Copyright © 2011-2022 走看看