由接受用户输入计算质数个数程序的优化项打开多线程编程

由接受用户输入计算质数个数的优化项打开多线程编程

命题

设计一个程序,在用户输入整数后,计算小于等于这个数的质数的个数

解决思路

  • 从数学角度分析问题
  • 抽象方法并设计程序
  • 对程序评估并优化方案

从数学角度来分析问题

我们需要知道质数的定义

在大于 1 的自然数中,除了1和它自身之外不再有其他因数,我们就称这个数为质数,又称素数,其中,规定最小的质数是2

将以上分析一下

  • 它要是个大于 1 的自然数
  • 除了1和它本身,没有任何一个自然数数可以将它整除

枚举法(试除法)

在大于等于2小于等于这个数间枚举每个自然数尝试与它本身相除

核心方法步骤(java实现)

设定这个数为 n

for(int i = 2;i<n;i++){
  if(n % i == 0){
    // 一旦成立,那么就说明可以被
    // 除1和它自身以外的其他自然数整除
    // 就不是质数(素数)
    break;// 具体操作还可另设
  }
}
// 如果循环完整结束中间无意外退出,就说明 n 是质数

该核心步骤执行的时间复杂度约为O(n)

抽象方法并设计程序

抽象出方法

  • +countPrimeNumber(int number):void

    计数方法:统计质数的个数

  • +isPrimeNumber(int number):boolean

    测试方法:判断传入的数是否为质数

试除法原理(计算范围为2~n)实现的java程序实例

PrimeNumberApp.java

import java.util.Scanner;

public class PrimeNumberApp {
    public static void main(String[] args) {
        PrimeNumberApp primeNumberApp = new PrimeNumberApp();
        primeNumberApp.excute();
    }

    public void excute(){
        Scanner scan = new Scanner(System.in);

        int number = scan.nextint();
        while (number!= 0){
            PrimeNumberTester primeNumberTester = new PrimeNumberTester();
            primeNumberTester.countPrimeNumber(number);
            System.out.println("请输入");
            number = scan.nextint();
            System.out.println("输入了:"+number);
        }
    }

    public class PrimeNumberTester{
        /**
         *测试输入的整数是否是质数
         * @param number
         * @return
         */
        public boolean isPrimeNumber(int number){
            for(int i=2;i<number;i++){
                if(number % i ==0){
                    return false;
                }
            }
            return true;
        }

        /**
         * 测试小于等于指定整数中质数的个数
         * @param number
         * @return
         */
        public void countPrimeNumber(int number){
            int count = 0;
            for (int i =2;i<=number;i++){
                if(this.isPrimeNumber(i)){
                    count++;
                }
            }
            System.out.println("小于:"+number+"的质数个数:"+count);
        }
    }
}

程序实例解说

程序的 UML 类图

程序的活动说明

在运行程序后输入数字并等待结果,可以发现时间是随输入数的增大而增大的

尤其是当输10位数字后,会发现控制台很长时间没有反应,

对程序评估并优化方案

程序的基本操作分解

  1.  for(int i=2;i<number;i++){
         if(number % i ==0){
             return false;
         }
     }
    

    O(n)

  2.  for (int i =2;i<=number;i++){
         if(this.isPrimeNumber(i)){
             count++;
         }
     }
    

    O(n*n)

PrimeNumberApp 程序的时间复杂度为O(n*n)

对枚举的范围优化(数学方法)

以上的枚举法范围是2至n内的所有自然数,我们可以看出在求证一个数是否是质数(素数)的步骤主要是循环遍历2到这个数之间的所有自然数能否将这个数整除

  1. 比如验证 10 是否是一个质数的验证过程,我们就可以看出

10 = 2x5; 10 = 5x2;

从数学角度我们来说

如若是一个自然数n,我们一定可以将这个整数拆分成两个正整数a,b的形式
n=a*b

如若一个数是素数,那么它只可以拆分成为 n=1*n的形式

posted on 2020-10-10 10:59  CodingAnt_Ricky  阅读(186)  评论(0)    收藏  举报