入室盗窃
2005年10月21号,历史会记住这个日子,即便历史记不住这个日子,我也会记住这个日子。因为,就在这一天,有个可爱的小偷,可能不止一个,光顾了我的房间。拿走了我的笔记本电脑,一个手机,一个移动硬盘,一个画图板,一套西装……
回到家大概六点,开开心心拿着钥匙准备开门,却发现房门虚掩。一瞬间脑筋里面想了很多,但是最后分析的结果是被盗了。果然,进门发现被翻得乱七八糟,笔记本不见了。欲哭无泪啊,赶紧打了110报警,然后就是警察来,然后我跟着去做笔录,反正是一套例行公事下来以后,我心里面很清楚,找不回来了,最可惜的是我硬盘上的资料啊,从本科到现在,一段记忆就这样消失了。可恨的小偷居然两个硬盘都拿走,也不给我留下一个备份,Curse他一百遍,一百遍!!!
花一晚上时间写的分数的类
/*
* 创建日期 2005-10-18
*
*/
package jet.math;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author Jet Yang
*
*/
public class Fraction {
private int numerator; // 分子
private int denominator; // 分母
private int gcd; // 最大公约数
/**
* @return denominator 。
*/
public int getDenominator() {
return denominator;
}
/**
* @return numerator 。
*/
public int getNumerator() {
return numerator;
}
public Fraction(String fraction) {
parseFraction(fraction);
}
/**
* Parse a String to Fraction format.
*
* @param fraction
* String to be parsed.
*/
private void parseFraction(String fraction) {
if (validateFraction(fraction)) {
String[] results = fraction.split("/");
numerator = Integer.valueOf(results[0]).intValue();
denominator = Integer.valueOf(results[1]).intValue();
} else {
throw new NumberFormatException( "For input string: \""+ fraction
+ "\"");
}
}
/**
* Validate the format of inputted String.
*
* @param fraction
* String inputted.
* @return Is validated.
*/
private boolean validateFraction(String fraction) {
Pattern pattern = null;
Matcher matcher = null;
pattern = Pattern.compile( "^-?\\d+/[0-9]*[1-9][0-9]*$$");
matcher = pattern.matcher(fraction);
return matcher.matches();
}
/**
* Simple by divide gcd
*
*/
public void simplify() {
gcd = this.getGcd(numerator, denominator);
numerator = numerator / gcd;
denominator = denominator / gcd;
}
/**
* Get the gcd value.
*
* @param a
* @param b
* @return 最大公约数
*/
private int getGcd( int a, int b) {
if (a < b) { //arrange so that a>b
int temp = a;
a = b;
b = temp;
}
if (0 == b) { //the base case
return a;
}
if (a % 2 == 0 && b % 2 == 0) { //a and b are even
return 2 * getGcd(a / 2, b / 2);
}
if (a % 2 == 0) {// only a is even
return getGcd(a / 2, b);
}
if (b % 2 == 0) {// only b is even
return getGcd(a, b / 2);
}
return getGcd((a + b) / 2, (a – b) / 2);// a and b are odd
}
/**
* Returns a Fraction whose value is (this + fraction).
*
* @param
fraction
* value to be added to this Fraction.
*
@returnthis + fraction
*/
public Fraction add(Fraction fraction) {
int numerator = this.numerator * fraction.denominator
+ this.denominator * fraction.numerator;
int denominator = this.denominator * fraction.denominator;
returnnew Fraction(String.valueOf(numerator) + "/"
+ String.valueOf(denominator));
}
/**
* Returns a Fraction whose value is (this – fraction).
*
* @paramfraction
* value to be subtracted from this Fraction.
* @return this – fraction
*/
public Fraction subtract(Fraction fraction) {
int numerator = this.numerator * fraction.denominator
– this.denominator * fraction.numerator;
int denominator = this.denominator * fraction.denominator;
returnnew Fraction(String.valueOf(numerator) + "/"
+ String.valueOf(denominator));
}
/**
* Returns a Fraction whose value is (this * fraction),
*
* @paramfraction
* value to be multiplied by this Fraction.
* @returnthis * fraction
*/
public Fraction multiply(Fraction fraction) {
int numerator = this.numerator * fraction.numerator;
int denominator = this.denominator * fraction.denominator;
returnnew Fraction(String.valueOf(numerator) + "/"
+ String.valueOf(denominator));
}
/**
* Returns a Fraction whose value is (this / fraction).
*
* @paramfraction
* value by which this Fraction is to be divided.
* @returnthis / fraction
*/
public Fraction divide(Fraction fraction) {
int numerator = this.numerator * fraction.denominator;
int denominator = this.denominator * fraction.numerator;
returnnew Fraction(String.valueOf(numerator) + "/"
+ String.valueOf(denominator));
}
/**
* Converts this Fraction to a double.
*
* @returnthis Fraction converted to a double.
*/
public double doubleValue() {
return (double) numerator / (double) denominator;
}
/**
* Converts this Fraction to a float.
*
* @returnthis Fraction converted to a float.
*/
public float floatValue() {
return (float) numerator / (float) denominator;
}
/**
* Converts this Fraction to a int.
*
* @returnthis Fraction converted to a int.
*/
public int intValue() {
return numerator / denominator;
}
/**
* Converts this Fraction to a long.
*
* @returnthis Fraction converted to a long.
*/
public long longValue() {
return (long) numerator / (long) denominator;
}
/**
*ReturnsthestringrepresentationofthisFraction.
*
*@returnStringrepresentationofthisFraction.
*/
public String toString() {
return String.valueOf(numerator) + "/" + String.valueOf(denominator);
}
/**
*ConvertsthisFractiontoasimpleformat.
*
*@returnthisFractionconvertedtoasimplevalue.
*/
public Fraction simpleValue() {
Fraction fraction = new Fraction(String.valueOf(numerator) + "/"
+ String.valueOf(denominator));
fraction.simplify();
return fraction;
}
}
最大公约数算法
1、欧几里德算法和扩展欧几里德算法
欧几里德算法
欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数。其计算原理依赖于下面的定理:
定理:gcd(a,b) = gcd(b,a mod b)
证明:a可以表示成a = kb + r,则r = a mod b
假设d是a,b的一个公约数,则有
d|a, d|b,而r = a – kb,因此d|r
因此d是(b,a mod b)的公约数
假设d 是(b,a mod b)的公约数,则
d | b , d |r ,但是a = kb +r
因此d也是(a,b)的公约数
因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等,得证
欧几里德算法就是根据这个原理来做的,其算法用C++语言描述为:
void swap(int & a, int & b)
{
int c = a;
a = b;
b = c;
}
int gcd(int a,int b)
{
if(0 == a )
{
return b;
}
if( 0 == b)
{
return a;
}
if(a > b)
{
swap(a,b);
}
int c;
for(c = a % b ; c > 0 ; c = a % b)
{
a = b;
b = c;
}
return b;
}
2、Stein算法
欧几里德算法是计算两个数最大公约数的传统算法,他无论从理论还是从效率上都是很好的。但是他有一个致命的缺陷,这个缺陷只有在大素数时才会显现出来。
考虑现在的硬件平台,一般整数最多也就是64位,对于这样的整数,计算两个数之间的模是很简单的。对于字长为32位的平台,计算两个不超过32位的整数的模,只需要一个指令周期,而计算64位以下的整数模,也不过几个周期而已。但是对于更大的素数,这样的计算过程就不得不由用户来设计,为了计算两个超过64位的整数的模,用户也许不得不采用类似于多位数除法手算过程中的试商法,这个过程不但复杂,而且消耗了很多CPU时间。对于现代密码算法,要求计算128位以上的素数的情况比比皆是,设计这样的程序迫切希望能够抛弃除法和取模。
Stein算法由J. Stein 1961年提出,这个方法也是计算两个数的最大公约数。和欧几里德算法 算法不同的是,Stein算法只有整数的移位和加减法,这对于程序设计者是一个福音。
为了说明Stein算法的正确性,首先必须注意到以下结论:
gcd(a,a) = a,也就是一个数和他自身的公约数是其自身
gcd(ka,kb) = k gcd(a,b),也就是最大公约数运算和倍乘运算可以交换,特殊的,当k=2时,说明两个偶数的最大公约数必然能被2整除
C++/java 实现
// c++/java stein 算法
int gcd(int a,int b){
if(a<b)//arrange so that a>b{
int temp = a;
a = b;
b=temp;
}
if(0==b)//the base case
return a;
if(a%2==0 && b%2 ==0)//a and b are even
return 2*gcd(a/2,b/2);
if ( a%2 == 0)// only a is even
return gcd(a/2,b);
if ( b%2==0 )// only b is even
return gcd(a,b/2);
return gcd((a+b)/2,(a-b)/2);// a and b are odd
}