连续整数检测法原理C语言,最大公约数的三种算法(欧几里得递归算法、连续整数检测算法、公共质因数相乘算法)...

最大公约数的算法在编程中是比较典型的,常见的有三种,按效率高低分别为:欧几里得递归算法、连续整数检测算法、公共质因数相乘算法。如下:

(1)欧几里得递归算法:

第一步:如果n=0;返回m值作为结果,同时过程结束;否则进入第二步。

第二步:m除以n,将余数赋给r。

第三步:将n的值赋给m,将r的值赋给n,返回第一步。

代码描述如下:

public static int gcd1(int m,int n){

if(m < n){

int temp = m;

m = n;

n = temp;

}

if(n == 0)

return m;

else

return gcd1(n,m%n);

}

(2)连续整数检测算法:

第一步:将min{m,n}的最小值赋给t

第二步:m除以t,如果余数为0,进入第三步;否则进入第四步

第三步:n除以t,如果余数为0,返回t的值作为结果;否则进入第四步

第四步:把t的值减1,返回第二步。

代码描述如下:

public static int gcd2(int m,int n){

int t;

if(m < n)

t = m;

else

t = n;

for(t = n;t >= 1; t–){

if(m%t==0 & & n%t==0)

break;

}

return t;

}

这两种算法的代码很简洁,而且效率也很高,所以在任何一种编程语言中都有他们两个的身影,但是很少见到第三种的描述。我记得我们在小学学习最大公约数的时候不是用这两种方法的,而是第三种。比如说求24和18的最大公约数— —

24 = 2 * 2 * 2 * 3

18 = 2 * 3 * 3

所以,最大公约数为:2 * 3 =6,看起来很容易的,可是用代码写出来却很复杂。今天做了一下这个费劲不讨好的算法。先描述一下吧:

(3)公共质因数相乘算法:

第一步:找出m的所有质因数

第二步:找出n的所有质因数

第三步:找出m和n的所有公因数(如果p是一个公因数,而且在m和n的质因数分解式中 分别出现p和q次,那么将p重复min{p,q}次)

第四步:将所有公共质因数相乘,结果返回。

代码描述如下(分三步走):

(1)找出n以内(包括n)的所有质数,结果存在一个List中

public static List< Integer> primeList(int n){

List< Integer> prime = new ArrayList< Integer>();

//将2-n之间的所有自然数放进List.

for(int i = 2;i

prime.add(i);

int end = (int)Math.sqrt(n);

//将非质数从Llist中去掉

for(int i = 2; i

if(prime.indexOf(i) == -1)

continue;

for(int j = prime.indexOf(i)+1; j < prime.size(); j++){

if(prime.get(j)%i == 0)

prime.remove(j);

}

}

return prime;

}

(2)找出正整数n的所有质因数,放进一个List中

public static List< Integer> primeDivisorList(int n){

List< Integer> prime = primeList(n/2);//只需要前n/2个质数

List< Integer> primeDivisor = new ArrayList< Integer>();

int i = 0;

while(true){

if(n == 1)break;

if(n%prime.get(i) == 0){

primeDivisor.add(prime.get(i));

n = n/prime.get(i);

i = 0;//因为一个数可以有多个相同的质因数,所以要再从头寻找

}

else

i++;

}

return primeDivisor;

}

(3)找出公因数相乘,求两个数的最大公约数

public static int gcd3(int m,int n){

int result = 1;

List< Integer> mList = primeDivisorList(m);

List< Integer> nList = primeDivisorList(n);

while(!mList.isEmpty() & & !nList.isEmpty()){

int i;

for(i = 0;i < nList.size();i++){

if(mList.get(0) == nList.get(i)){

//每找到一个公因数,将该数从两个公因数列表中删除

mList.remove(i);

result = result * nList.remove(i);

break;

}

}

if(i == nList.size())

if(!mList.isEmpty())

mList.remove(0)

}

return result;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值