Stein's Algorithm 求最大公约数
来源:互联网 发布:360彩票源码 编辑:程序博客网 时间:2024/04/30 21:06
原文:http://www.blackwasp.co.uk/SteinsAlgorithm.aspx
Stein's algorithm provides an enhanced version of the Euclidean algorithm for calculating the greatest common divisor (GCD) for a pair of integers. Stein's algorithm provides greater efficiency by making use of the bitwise shift operators.
Greatest Common Divisor
In an earlier article I showed a C# version of the Euclidean algorithm, described by the Greek mathematician,Euclid of Alexandria. This algorithm can be used to calculate the greatest common divisor (GCD) of two integers. The GCD is the largest whole number that both integers can be divided by without generating a remainder. For example, the GCD of 210 and 124 is 42, as both values can be divided by 42 without remainder, giving results of 5 and 3 respectively.
The most basic version of the Euclidean algorithm works by repeated subtraction. I won't describe it here as it is covered in the earlier article. It can be incorporated into a C#method as follows:
public static uint Euclid(uint value1, uint value2){ while (value1 != 0 && value2 != 0) { if (value1 > value2) value1 -= value2; else value2 -= value1; } return Math.Max(value1, value2);}
NB: The method is shown as static so that it can be called directly from the Main method of a console application project.
Stein's Algorithm
Stein's algorithm, published in 1967 by Josef Stein, is another algorithm for calculating the GCD of two values. It is optimised for use in computing, utilising fastbitwise shifts rather than the usually slower repeatedsubtraction, division or modulus operations. Computers that use the .NET framework generally have processors that natively support division so the efficiency difference may not be so pronounced. However, the algorithm is still interesting.
Stein's algorithm uses a number of rules:
- Like the Euclidean algorithm, if either of the two values is zero, the result of the algorithm is the other value. This can be returned immediately.
- If the two integer values are equal, the GCD is this value and can be returned immediately.
- If both of the values are even numbers we know that the value two is a common divisor. We can divide both values by two, using a shift operation, and find the GCD of the two new values. Multiplying this result by two, using a second shift operation, gives the GCD of the original values. ie. GCD(a,b) = 2·GCD(a/2,b/2).
- If only one of the values is even, we know that the value two is not a common divisor. We can therefore divide the even value by two and recalculate the GCD. ie.GCD(even,odd) = GCD(even/2,odd).
- If both of the values are odd, we need to use subtraction in the same manner as in a single step of the Euclidean algorithm. The smaller value is subtracted from the larger and the result is used with the smaller value to calculate the GCD. ie.GCD(large,small) = GCD(large-small,small). We can go a step further than this. When one odd value is subtracted from another we know that the result will be even. This means that we will be calculating the GCD of an odd and an even value. We can therefore divide the even number by two, as in step 4. ie. GCD(large,small) = GCD((large-small)/2,small).
Creating the Stein Method
Let's create a method that implement's Stein's algorithm. Start by creating the signature, which matches that of the earlier Euclid method.
public static uint Stein(uint value1, uint value2){}
To implement rules 1 and 2, we need to check if either of the two values are zero or if they match. These scenarios cause a value to be returned without further recursive calls to the method.if (value1 == 0) return value2;if (value2 == 0) return value1;if (value1 == value2) return value1;
Finally we can determine which of the values are odd and which are even, in order that we can apply the remaining rules with a recursive call. The firstif statement identifies when both values are even and applies rule 3. The second and third if statements capture one even and one odd number, both applying rule 4. The last if statement and the final else statement are executed when both values are odd. They both apply rule 5.bool value1IsEven = (value1 & 1u) == 0;bool value2IsEven = (value2 & 1u) == 0; if (value1IsEven && value2IsEven) returnStein(value1 >> 1, value2 >> 1) << 1;else if (value1IsEven && !value2IsEven) returnStein(value1 >> 1, value2);else if (value2IsEven) returnStein(value1, value2 >> 1);else if (value1 > value2) returnStein((value1 - value2) >> 1, value2);else returnStein(value1, (value2 - value1) >> 1);
Testing the Method
To perform a simple test, add the following line of code to the Main method and run the program. This calculates the GCD of 116,150 and 232,704. The result should be 202.
int
gcd = Stein(116150, 232704);
// 202
C版本:
int Stein(int value1, int value2){if (value1 == 0) return value2;if (value2 == 0) return value1;if (value1 == value2) return value1;int value1IsEven = (value1 % 2) == 0;int value2IsEven = (value2 % 2) == 0;if (value1IsEven && value2IsEven)return Stein(value1 >> 1, value2 >> 1) << 1;else if (value1IsEven && !value2IsEven)return Stein(value1 >> 1, value2);else if (value2IsEven)return Stein(value1, value2 >> 1);else if (value1 > value2)return Stein((value1 -value2) >> 1, value2);elsereturn Stein(value1, (value2 - value1) >> 1);}
- Stein's Algorithm 求最大公约数
- Stein算法 求最大公约数
- stein算法求最大公约数
- Stein算法求最大公约数
- Stein算法求最大公约数
- Euclid's Algorithm 求最大公约数
- 求最大公约数的算法-Euclid & stein
- Stein算法求最大公约数 ( ANSI C )
- Stein算法——求最大公约数
- Stein算法(求两个数最大公约数)
- 求最大公约数的欧几里德算法(Euclid's Algorithm)
- Algorithm - 求最大公约数
- 求最大公约数的Stein算法以及高精度实现
- HDU 2028 Lowest Common Multiple Plus (Stein算法 求最大公约数)
- 欧几里德和stein两种算法求最大公约数
- 求最大公约数的两种算法(Euclid&&Stein)
- stein算法求gcd
- 最大公约数(Gcd)两种算法(Euclid && Stein)
- SAX、DOM、PULL的比较
- 正则表达式
- (使用树结构来支持并查集变成8.4.3)UVA 10158 War(并查集的经典题目: 敌友关系)
- jsp和Servlet中文乱码汇总
- 如何设计一款Java框架?
- Stein's Algorithm 求最大公约数
- sqlmap简易教程–帮助文档个人使用经验解析
- 3. rtx任务间的通信--event flags
- HDU 4115 2-sat 石头剪刀布 拆点+约束
- FFMPEG结构体分析:AVCodecContext
- pandaborad初体验
- uva-465
- 数据库语句 select * from table where 1=1 的用法和作用
- 使用Ant进行ssh和scp操作