一、Stein算法过程及其简单证明

1.一般步骤:

s1:当两数均为偶数时将其同时除以2至至少一数为奇数为止,记录除掉的所有公因数2的乘积k;

s2:如果仍有一数为偶数,连续除以2直至该数为奇数为止;

s3:用更相减损法(辗转相减法),即GCD(a,b)=GCD(a-b,b),或辗转相除法求出两奇数的最大公约数d;

s4:原来两数的最大公约数即为d*k;

2.简单证明:

s1:即为求出两数为2的幂次方的最大公因数k;

s2:当化简后两数一奇一偶时,显然奇数是不含偶数因子的,那么另一化简后偶数的所有偶数因子都不可能为原来两数的最大公因数的因子;

s3:求出原来两数不为2的幂次方的最大公因数d;

s4:最大公因数即为2的幂次方的最大公因数k乘以不为2的幂次方的最大公因数d;

3.Stein算法的优点:

欧几里得算法在处理较小数字时优势是明显的,但对于大整数时,高精度的整除和取余运算就显得非常复杂,所以Stein算法的优点就在于只需要进行移位(位运算)和减法操作,处理高精度GCD问题时相对简便;

4.相关位运算符的简单介绍:

(1)按位与(&):

a&x为对数a的二进制形式的取位操作,即去a二进制形式的第x位。这里有一个重要应用就是a&1可以用于判断数a的奇偶性,即a末位为0即为偶数,末位为1即为奇数。

(2)异或运算(^):

具体介绍参考之前的随笔:http://www.cnblogs.com/COLIN-LIGHTNING/p/8298554.html;

应用为交换两数:a=b,b=a,a^=b即完成了两数交换。

(3)按位左移(<<):

a<<=x即为使a乘以2的x次幂,原理是让a的二进制形式左移x位;应用为对与2的幂次方相乘使运算更快更方便;

(4)按位右移(>>):

a>>=x即为使a除以2的x次幂,原理是让a的二进制形式右移x位;应用为对与2的幂次方相除使运算更快更方便;

5.一般代码:

(1)递归形式:

int stein(int a,int b){
if(a<b) a^=b,b^=a,a^=b; //交换,使a为较大数;
if(b==0)return a; //当相减为零,即两数相等时,gcd=a;
if((!(a&1))&&(!(b&1))) return stein(a>>1,b>>1)<<1; //s1,注意最后的左移,在递归返回过程中将2因子乘上;
else if((a&1)&&(!(b&1)))return stein(a,b>>1); //s2;
else if((!(a&1))&&(b&1))return stein(a>>1,b);
else return stein(a-b,b); //s3;
}

(2)迭代形式:

int stein(int a,int b){
int k=1;
while((!(a&1))&&(!(b&1))){ //s1;
k<<=1; //用k记录全部公因子2的乘积 ;
a>>=1;
b>>=1;
}
while(!(a&1))a>>=1; //s2;
while(!(b&1))b>>=1;
if(a<b) a^=b,b^=a,a^=b; //交换,使a为较大数;
while(a!=b){ //s3;
a-=b;
if(a<b) a^=b,b^=a,a^=b;
}
return k*a;
}

浅谈Stein算法求最大公约数(GCD)的原理及简单应用的更多相关文章

  1. 浅谈欧几里得算法求最大公约数(GCD)的原理及简单应用

    一.欧几里得算法及其证明 1.定义: 欧几里得算法又称辗转相除法,用于求两数的最大公约数,计算公式为GCD(a,b)=GCD(b,a%b): 2.证明: 设x为两整数a,b(a>=b)的最大公约 ...

  2. Stein算法求最大公约数

    首先引进一个符号:gcd是greatest common divisor(最大公约数)的缩写,gcd( x,y ) 表示x和y的最大公约数.然后有一个事实需要了解:一个奇数的所有约数都是奇数.这个很容 ...

  3. 浅谈分词算法(3)基于字的分词方法(HMM)

    目录 前言 目录 隐马尔可夫模型(Hidden Markov Model,HMM) HMM分词 两个假设 Viterbi算法 代码实现 实现效果 完整代码 参考文献 前言 在浅谈分词算法(1)分词中的 ...

  4. 浅谈分词算法基于字的分词方法(HMM)

    前言 在浅谈分词算法(1)分词中的基本问题我们讨论过基于词典的分词和基于字的分词两大类,在浅谈分词算法(2)基于词典的分词方法文中我们利用n-gram实现了基于词典的分词方法.在(1)中,我们也讨论了 ...

  5. 浅谈分词算法(5)基于字的分词方法(bi-LSTM)

    目录 前言 目录 循环神经网络 基于LSTM的分词 Embedding 数据预处理 模型 如何添加用户词典 前言 很早便规划的浅谈分词算法,总共分为了五个部分,想聊聊自己在各种场景中使用到的分词方法做 ...

  6. 浅谈分词算法(4)基于字的分词方法(CRF)

    目录 前言 目录 条件随机场(conditional random field CRF) 核心点 线性链条件随机场 简化形式 CRF分词 CRF VS HMM 代码实现 训练代码 实验结果 参考文献 ...

  7. 浅谈可持久化Trie与线段树的原理以及实现(带图)

    浅谈可持久化Trie与线段树的原理以及实现 引言 当我们需要保存一个数据结构不同时间的每个版本,最朴素的方法就是每个时间都创建一个独立的数据结构,单独储存. 但是这种方法不仅每次复制新的数据结构需要时 ...

  8. [算法]求满足要求的进制(辗转相除(欧几里得算法),求最大公约数gcd)

    题目 3在十进制下满足若各位和能被3整除,则该数能被3整除. 5在十六进制下也满足此规律. 给定数字k,求多少进制(1e18进制范围内)下能满足此规律,找出一个即可,无则输出-1. 题解 写写画画能找 ...

  9. 浅谈Tarjan算法及思想

    在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连 ...

随机推荐

  1. Java实现的词频统计——单元测试

    前言:本次测试过程中发现了几个未知字符,这里将其转化为十六进制码对其加以区分. 1)保存统计结果的Result文件中显示如图: 2)将其复制到eclipse环境下的切分方法StringTokenize ...

  2. sublime py不能输入中文

    设置环境变量PYTHONIOENCODING=UTF-8,重启sublime即可 转载请注明博客出处:http://www.cnblogs.com/cjh-notes/

  3. rxjs5.X系列 —— ErrorHandling/Condition/Mathematical系列 api 笔记

    欢迎指导与讨论 : ) 前言 本文是笔者翻译 RxJS 5.X 官网各类operation操作系列的的第四篇 —— ErrorHanding异常处理.Condition Operator情况操作.Ma ...

  4. a标签不能嵌套

    <a href='http://www.baidu.com'> <a href='http://www.google.com'></a> </a> &l ...

  5. 【uoj#175】新年的网警 结论题+Hash

    题目描述 给出一张 $n$ 个点 $m$ 条边的无向连通图,每条边的边权为1.对于每个点 $i$ ,问是否存在另一个点 $j$ ,使得对于任意一个不为 $i$ 或 $j$ 的点 $k$ ,$i$ 到 ...

  6. 【uoj#174】新年的破栈 贪心

    题目描述 给你一个长度为 $n$ 的序列和一个空的双端队列,每次进行3种操作种的一种: 1.将序列中编号最小的数加入到双端队列的队尾:2.从双端队列的队尾取出一个数:3.从双端队列的队头取出一个数. ...

  7. 解决二维数组转为ArrayList集合问题

    1.修改前代码块 String[][] str = { { "语文", "100" }, { "英语", "90" }, ...

  8. C#中string[]数组和list<string>泛型的相互转换 【转】

    http://www.cnblogs.com/szjdw/archive/2012/03/09/2387885.html 1,从System.String[]转到List<System.Stri ...

  9. Spring Batch @SpringBatchTest 注解

    Spring Batch 提供了一些非常有用的工具类(例如 JobLauncherTestUtils 和 JobRepositoryTestUtils)和测试执行监听器(StepScopeTestEx ...

  10. BZOJ4735 你的生命已如风中残烛 【数学】

    题目链接 BZOJ4735 题解 给定一个序列,有的位置为\(w_i - 1\),有的位置为\(-1\),问有多少种排列,使得任意前缀和非负? 我们末尾加上一个\(-1\),就是要保证除了末尾外的前缀 ...