1 问题描述

Compute the Greatest Common Divisor of Two Integers using Sieve of Eratosthenes.

翻译:使用埃拉托色尼筛选法计算两个整数的最大公约数。(PS:最大公约数也称最大公因数,指两个或多个整数共有约数中最大的一个)

2 解决方案

2.1 埃拉托色尼筛选法原理简介

引用自百度百科:

埃拉托色尼筛选法(the Sieve of Eratosthenes)简称埃氏筛法,是古希腊数学家埃拉托色尼(Eratosthenes 274B.C.~194B.C.)提出的一种筛选法。 是针对自然数列中的自然数而实施的,用于求一定范围内的质数,它的容斥原理之完备性条件是p=H~。

具体求取质数的思想:

(1)先把1删除(现今数学界1既不是质数也不是合数)

(2)读取队列中当前最小的数2,然后把2的倍数删去

(3)读取队列中当前最小的数3,然后把3的倍数删去

(4)读取队列中当前最小的数5,然后把5的倍数删去

(5)如上所述直到需求的范围内所有的数均删除或读取

下面看一下执行上述步骤求不大于100的所有质数的一个示意图:

2.2 具体编码

本文求取两个数的最大公约数,采用质因数分解法:把每个数分别分解质因数,再把各数中的全部公有质因数提取出来连乘,所得的积就是这几个数的最大公约数。

例如:求24和60的最大公约数,先分解质因数,得24=2×2×2×3,60=2×2×3×5,24与60的全部公有的质因数是2、2、3,它们的积是2×2×3=12,所以,(24,60)=12。

此处,第一步,先使用埃拉托色尼筛选法求取不大于数A的所有质数,然后从这些质数中选取A的所有质因数;第二步,依照第一步思想求取数B的所有质因数;第三步,求取数A和数B公共质因数;第四步,输出数A和数B的最大公约数。

具体代码如下:

package com.liuzhen.ex1;

import java.util.Scanner;

public class SieveOfEratosthenes {
//返回一维数组,数组中的元素为不大于n的所有质数
public static int[] getPrime(int n){
int[] result1 = new int[n]; //定义一个一维数组,并从第2个元素依次初始化为相应的自然数
for(int i = 2;i < n+1;i++){
result1[i-1] = i;
}
for(int i = 2;i < n;i++){
for(int j = i+1;j < n+1;j++){
if(j % i == 0) //如果j能够整除i,使result[j-1]等于0
result1[j-1] = 0;
}
}
int[] result2 = getNoneZero(result1); //除去result数组中所有0元素
return result2; //数组中非零元素即为不大于n的所有质数
} //返回一维数组,该数组的元素为参数数组中所有不为0的元素值
public static int[] getNoneZero(int[] A){
int len = 0;
for(int i = 0;i < A.length;i++){
if(A[i] != 0)
len = len+1;
}
int[] result = new int[len];
int k = 0;
for(int i = 0;i < A.length;i++){
if(A[i] != 0){
result[k] = A[i];
k++;
}
}
return result;
} //求取一个数n的所有质因数(eg:24=2×2×2×3,则result[] = {2,2,2,3})
public static int[] getNprime(int n){
int[] primes = getPrime(n);
int[] result; //最终返回结果集
int len = 0; //返回结果集数组长度,初始化为0
for(int i = 0;i < primes.length;i++){
int temp = n;
while(temp % primes[i] == 0){
temp = temp/primes[i];
len++;
}
}
result = new int[len];
int k = 0;
for(int i = 0;i < primes.length;i++){
int temp = n;
while(temp % primes[i] == 0){
temp = temp/primes[i];
result[k] = primes[i];
k++;
}
}
return result;
} //返回两个一维数组中所有共同元素
public static int[] getCommonPrime(int[] A , int[] B){
int[] result;
int lenA = A.length;
int lenB = B.length;
if(lenA < lenB){
result = new int[lenA];
for(int i = 0;i < lenA;i++){
int temp = A[i];
for(int j = 0;j < lenB;j++){
if(temp == B[j]){
result[i] = A[i];
B[j] = 0;
break;
}
}
}
}
else{
result = new int[lenB];
for(int i = 0;i < lenB;i++){
int temp = B[i];
for(int j = 0;j < lenA;j++){
if(temp == A[j]){
result[i] = B[i];
A[j] = 0;
break;
}
}
}
}
int[] result1 = getNoneZero(result);
return result1;
} //求取数A和B的最大公约数
public static void getMaxCommonDivisor(int A,int B){
int[] primesA = getNprime(A); //数A所有质因子
int[] primesB = getNprime(B); //数B所有质因子
int[] resultPrime = getCommonPrime(primesA,primesB); //数A和数B的公共质因数
int maxCommonDivisor = 1;
System.out.println(A+"和"+B+"的公共质因数为:");
for(int i = 0;i < resultPrime.length;i++){
maxCommonDivisor *= resultPrime[i];
System.out.print(resultPrime[i]+"\t");
}
System.out.println();
System.out.print(A+"和"+B+"的最大公约数为:"+maxCommonDivisor);
} public static void main(String[] args){
System.out.println("请输入数字A和数字B的值:");
Scanner in = new Scanner(System.in);
int a = in.nextInt();
int b = in.nextInt();
getMaxCommonDivisor(a,b);
}
}

运行结果:

请输入数字A和数字B的值:
60
100和60的公共质因数为:
2 5
100和60的最大公约数为:20 请输入数字A和数字B的值:
48
60和48的公共质因数为:
2 3
60和48的最大公约数为:12 请输入数字A和数字B的值:
54
120和54的公共质因数为:
3
120和54的最大公约数为:6

Java实现埃拉托色尼筛选法的更多相关文章

  1. 算法笔记_012:埃拉托色尼筛选法(Java)

    1 问题描述 Compute the Greatest Common Divisor of Two Integers using Sieve of Eratosthenes. 翻译:使用埃拉托色尼筛选 ...

  2. 使用埃拉托色尼筛选法(the Sieve of Eratosthenes)在一定范围内求素数及反素数(Emirp)

    Programming 1.3 In this problem, you'll be asked to find all the prime numbers from 1 to 1000. Prime ...

  3. LeetCode Count Primes 求素数个数(埃拉托色尼筛选法)

    题意:给一个数n,返回小于n的素数个数. 思路:设数字 k =from 2 to sqrt(n),那么对于每个k,从k2开始,在[2,n)范围内只要是k的倍数的都删掉(也就是说[k,k2)是不用理的, ...

  4. java筛选法求素数

    这本身没什么,代码一堆 发来纪念下而已 本来刚学习java,编写输出100以内的素数 对于我这个有代码运行性能洁癖的人(但是本身又不懂算法)来说,不能忍 于是看了些资料 参考: http://blog ...

  5. 素数筛选法(prime seive)

    素数筛选法比较有名的,较常用的是Sieve of Eratosthenes,为古希腊数学家埃拉托色尼(Eratosthenes 274B.C.-194B.C.)提出的一种筛选法.详细步骤及图示讲解,还 ...

  6. Eratosthenes筛选法构造1-n 素数表

    筛选法:对于不超过n的每个非负整数p,删除2p,3p,4p...当处理完所有数之后,还没没删除的就是素数. 代码中进行了相应的优化. 本代码功能,输入一个数,输出从1-该数之间的素数.功能待完善,可将 ...

  7. ACM/ICPC 之 数论-素数筛选法 与 "打表"思路(POJ 1595)

    何为"打表"呢,说得简单点就是: 有时候与其重复运行同样的算法得出答案,还不如直接用算法把这组数据所有可能的答案都枚举出来存到一个足够大的容器中去-例如数组(打表),然后再输入数据 ...

  8. HDU1215(筛选法)

    题意:求n的所有因子和: 思路:类似于筛选法求素数的思想,只有第一次的时候了解过它的思想,然后就只是用来求素数,思想的运用反而少: 筛选法求素数: int prime() { memset(vis, ...

  9. POJ 3978 Primes(素数筛选法)

    题目 简单的计算A,B之间有多少个素数 只是测试数据有是负的 //AC //A和B之间有多少个素数 //数据可能有负的!!! #include<string.h> #include< ...

随机推荐

  1. C# 数据操作系列 - 5. EF Core 入门

    0.前言 上一章简单介绍了一下ORM框架,并手写了一个类似ORM的工具类.这一章将介绍一个在C#世界里大名鼎鼎的ORM框架--Entity Framework的Core版. Entity Framew ...

  2. 错误 在应用程序级别之外使用注册为 allowDefinition='MachineToApplic

    错误 在应用程序级别之外使用注册为 allowDefinition='MachineToApplication' 的节是错误的.如果在 IIS 中没有将虚拟目录配置为应用程序,则可能导致此错误. 如果 ...

  3. TP5 order排序

    order方法属于模型的连贯操作方法之一,用于对操作的结果排序. ->order('sort desc,id desc') 用法如下: Db::table('think_user')->w ...

  4. pod install update没有反应

    出去是镜像的问题,我用的是外网,所以应该不是镜像的问题, 换用这个: pod install --verbose --no-repo-update pod update --verbose --no- ...

  5. android 数据库是否该关闭

    关于android多线程数据读写请看博客: android 多线程数据库读写 常常纠结于获取了SQLiteDatabase每次操作完是否要关闭的问题,每次关闭又怕影响性能,这里记录下SQLiteOpe ...

  6. 【Linux学习】【第一节】【vi命令】

    在linux下操作文件,通常会用到vi命令,现对其常用命令进行总结. 基本上vi/vim共分为三种模式,分别是命令模式.输入模式和底线命令模式,三者之间的关系如图所示. 一.移动光标的方法 (1)上下 ...

  7. Vue element-ui date-picker 结束时间大于开始时间且开始时间小于此刻(转)

    转载自:https://blog.csdn.net/wintersweetGirl/article/details/82461412 <el-form ref="form" ...

  8. webpack使用babel

    几个月没用webpack都忘了好多了. webpack构建前端,使用时除了entry/output,就是plugins和module.loaders,还有本地测试的devServer. npm ins ...

  9. 曹工谈Spring Boot:Spring boot中怎么进行外部化配置,一不留神摔一跤;一路debug,原来是我太年轻了

    spring boot中怎么进行外部化配置,一不留神摔一跤:一路debug,原来是我太年轻了 背景 我们公司这边,目前都是spring boot项目,没有引入spring cloud config,也 ...

  10. Django之AJAX简单使用

    AJAX简介: AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”.即使用Javascript语言与服务器进行异步交互,传输 ...