浅谈Stein算法求最大公约数(GCD)的原理及简单应用
一、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)的原理及简单应用的更多相关文章
- 浅谈欧几里得算法求最大公约数(GCD)的原理及简单应用
一.欧几里得算法及其证明 1.定义: 欧几里得算法又称辗转相除法,用于求两数的最大公约数,计算公式为GCD(a,b)=GCD(b,a%b): 2.证明: 设x为两整数a,b(a>=b)的最大公约 ...
- Stein算法求最大公约数
首先引进一个符号:gcd是greatest common divisor(最大公约数)的缩写,gcd( x,y ) 表示x和y的最大公约数.然后有一个事实需要了解:一个奇数的所有约数都是奇数.这个很容 ...
- 浅谈分词算法(3)基于字的分词方法(HMM)
目录 前言 目录 隐马尔可夫模型(Hidden Markov Model,HMM) HMM分词 两个假设 Viterbi算法 代码实现 实现效果 完整代码 参考文献 前言 在浅谈分词算法(1)分词中的 ...
- 浅谈分词算法基于字的分词方法(HMM)
前言 在浅谈分词算法(1)分词中的基本问题我们讨论过基于词典的分词和基于字的分词两大类,在浅谈分词算法(2)基于词典的分词方法文中我们利用n-gram实现了基于词典的分词方法.在(1)中,我们也讨论了 ...
- 浅谈分词算法(5)基于字的分词方法(bi-LSTM)
目录 前言 目录 循环神经网络 基于LSTM的分词 Embedding 数据预处理 模型 如何添加用户词典 前言 很早便规划的浅谈分词算法,总共分为了五个部分,想聊聊自己在各种场景中使用到的分词方法做 ...
- 浅谈分词算法(4)基于字的分词方法(CRF)
目录 前言 目录 条件随机场(conditional random field CRF) 核心点 线性链条件随机场 简化形式 CRF分词 CRF VS HMM 代码实现 训练代码 实验结果 参考文献 ...
- 浅谈可持久化Trie与线段树的原理以及实现(带图)
浅谈可持久化Trie与线段树的原理以及实现 引言 当我们需要保存一个数据结构不同时间的每个版本,最朴素的方法就是每个时间都创建一个独立的数据结构,单独储存. 但是这种方法不仅每次复制新的数据结构需要时 ...
- [算法]求满足要求的进制(辗转相除(欧几里得算法),求最大公约数gcd)
题目 3在十进制下满足若各位和能被3整除,则该数能被3整除. 5在十六进制下也满足此规律. 给定数字k,求多少进制(1e18进制范围内)下能满足此规律,找出一个即可,无则输出-1. 题解 写写画画能找 ...
- 浅谈Tarjan算法及思想
在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连 ...
随机推荐
- 【转】MySQL数据表中记录不存在则插入,存在则更新
mysql 记录不存在时插入在 MySQL 中,插入(insert)一条记录很简单,但是一些特殊应用,在插入记录前,需要检查这条记录是否已经存在,只有当记录不存在时才执行插入操作,本文介绍的就是这个问 ...
- HDU4472_Count
题目的意思简单,给你n个点,每个点(除根节点)都有且只有一个父节点.现在问你这些节点关系组成的图有多少种情况满足同一层节点上每个点的后继节点数量相等. 很简单,对于n节点,直接枚举n-1的的所有约数情 ...
- Arrays.toString 如果传入的是对象 那么调用的是此对象的toString
Arrays.toString(Object[] obj) 如果传入参数的是对象 那么调用的是此对象的toString
- 【uoj#164】[清华集训2015]V 线段树维护历史最值
题目描述 给你一个长度为 $n$ 的序列,支持五种操作: $1\ l\ r\ x$ :将 $[l,r]$ 内的数加上 $x$ :$2\ l\ r\ x$ :将 $[l,r]$ 内的数减去 $x$ ,并 ...
- (转)java web自定义分页标签
转载至http://liuxi1024.iteye.com/blog/707784 效果如图: 1.JSP规范1.1版本后增加了自定义标签库.实现自定义标签的步骤 (1)开发自定义标签处理类. (2) ...
- 【刷题】BZOJ 4196 [Noi2015]软件包管理器
Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖( ...
- 使用Unity5.1进行VR开发的配置(最新的未必是最好的!!!)
随着Unity5.1的发布,之前的Oculus Rift和Gear VR 开发流程发生了巨大的变化,这也算是小白鼠们必须付出的代价了~ 那么Unity5.1和Oculus的整合究竟发生了哪些变化,对开 ...
- Insert Node in Sorted Linked List
Insert a node in a sorted linked list. Have you met this question in a real interview? Yes Example ...
- LOJ #6036.「雅礼集训 2017 Day4」编码 Trie树上2-sat
记得之前做过几道2-sat裸体,以及几道2-sat前缀优化建图,这道题使用了前缀树上前缀树优化建图.我们暴力建图肯定是n^2级别的,那么我们要是想让边数少点,就得使用一些骚操作.我们观察我们的限制条件 ...
- Python之旅:装饰器
装饰器就是闭包函数的一种应用场景 一.为何要用装饰器 开放封闭原则:软件一旦上线后,就应该遵循开放封闭原则,即对修改源代码是封闭的,对功能的扩展是开放的 也就是说我们必须找到一种解决方案:能够在不修该 ...