欧几里得算法
求两个数的最大公约数:
/**
*
* @param a 整数
* @param b 整数
* @return 两个整数的最大公约数
*/
public static int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}
扩展欧几里得
/**
*
* @param a
* @param b (a,b)两个整数
* @param x
* @param y (x,y)满足 ax+by=gcd(a,b)
* @return a b最大公约数 x,y满足条件
*/
public static int extend_gcd(int a,int b,int x,int y){
if(b==0){
x=1;
y=0;
return a;
}else {
int r=extend_gcd(b,a%b,y,x);
y-=x*(a/b);
return r;
}
}
素数筛法
素数筛法是一种用来筛选素数的算法。最简单的素数筛法是埃氏筛法(Sieve of Eratosthenes)。该算法的基本思想是:首先将数字从小到大列出来,然后用2去筛,将2留下,其他的数都删去;再用下一个素数,也就是3筛,将3留下,其他的数都删去;接下来用下一个素数5筛,首先将5×2=10以后的数删去,再将5×3=15以后的数删去,接下来用下一个素数7筛,不断重复下去......直到筛完为止。这样得到的就是素数。
/**
*
* @param n 判别素数的范围 [0-n]
*/
public static void sieveOfEratosthenes(int n) {
boolean prime[] = new boolean[n+1];
Arrays.fill(prime,true);
for(int p = 2; p*p <=n; p++) {
if(prime[p] == true) {
for(int i = p*p; i <= n; i += p)
prime[i] = false;
}
}
for(int i = 2; i <= n; i++) {
if(prime[i] == true)
System.out.print(i + " ");
}
}
素数判定
public static boolean isPrime(int n) {
if (n <= 1) {
return false;
}
if (n <= 3) {
return true;
}
if (n % 2 == 0 || n % 3 == 0) {
return false;
}
for (int i = 5; i * i <= n; i += 6) {
if (n % i == 0 || n % (i + 2) == 0) {
return false;
}
}
return true;
}
质因数分解
质因数分解是指将一个整数n分解成若干个质因数相乘的形式。例如,将整数36表示为2^2 * 3^2的形式。
N的质因数要么时N本身(素数),要么一定小于
。因此可以利用小于
的数对N试除,直到不能除为止。如果剩下的数不是1,那就是N的最大质因数。
public static void primeFactors(int n) {
while (n%2==0) {
System.out.print(2 + " ");
n /= 2;
}
for (int i = 3; i <= Math.sqrt(n); i+= 2) {
while (n%i == 0) {
System.out.print(i + " ");
n /= i;
}
}
if (n > 2)
System.out.print(n);
}
快速幂
递归
public static double power(double x, int n) {
if(n==0)
return 1;
double v = power(x, n/2);
if (n % 2 == 0) {
return v * v;
} else {
return v * v * x;
}
}
循环
public static double power(double x, int n) {
double result = 1;
while (n > 0) {
if (n % 2 == 1) {
result = result * x;
}
x = x * x;
n = n / 2;
}
return result;
}
进制转换
使用Java语言
public class Main {
public static void main(String[] args) {
String a=Integer.toString(100,2);
//将10进制100转化为2进制
System.out.println(a);
}
}
1100100
public class Main {
public static void main(String[] args) {
long a=Integer.parseInt("f1",16);
//将16进制转化为10进制
System.out.println(a);
}
}
241
辗转取余
public static String decimalToAny(int decimal, int base) {
StringBuilder result = new StringBuilder();
while (decimal > 0) {
int remainder = decimal % base;
result.append(remainder);
decimal = decimal / base;
}
return result.reverse().toString();
}
public class Main {
public static void main(String[] args) {
System.out.println(decimalToAny(100,2));//100的2进制
System.out.println(decimalToAny(100,8));
System.out.println(decimalToAny(100,16));
/**
* 如果是转换成十六进制,需要额外处理余数大于9的情况,使用0-9和A-F表示即可。
*/
}
public static String decimalToAny(int decimal, int base) {
StringBuilder result = new StringBuilder();
while (decimal > 0) {
int remainder = decimal % base;
result.append(remainder);
decimal = decimal / base;
}
return result.reverse().toString();
}
}
1100100
144
64
位运算
加
public static int add(int a, int b) {
while (b != 0) {
int carry = (a & b) << 1;
a = a ^ b;
b = carry;
}
return a;
}
减
public static int subtract(int a, int b) {
return add(a, add(~b, 1));
}
乘
public static int multiply(int a, int b) {
int result = 0;
while (b > 0) {
if ((b & 1) != 0) {
result = add(result, a);
}
a = a << 1;
b = b >> 1;
}
return result;
}
除
public static int divide(int a, int b) {
int sign = ((a < 0) ^ (b < 0)) ? -1 : 1;
a = Math.abs(a);
b = Math.abs(b);
int quotient = 0;
for (int i = 31; i >= 0; i--) {
if ((a >>> i) >= b) {
quotient += 1 << i;
a -= b << i;
}
}
return sign * quotient;
}
判断两个数是否为异号
public static boolean Alien_sign(int a,int b){
return (a^b)<0;
}
消除n 2进制最后一位1
public static int remove_one(int n){
return n&(n-1);
}
低位0变1
n|=n+1;
低位1变0
n&=n-1;
Java中支持所有基本的位运算操作,如与(&)、或(|)、异或(^)、左移(<<)、右移(>>)和无符号右移(>>>)。
int x = 5;
int y = 6;
int result = x & y;
运算后result为4,因为二进制下5为101,6为110,取与后为100。
int x = 5;
int y = 6;
int result = x | y;
运算后result为7,因为二进制下5为101,6为110,取或后为111。
int x = 5;
int y = 6;
int result = x ^ y;
运算后result为3,因为二进制下5为101,6为110,取异或后为011。
int x = 5;
int result = x << 2;
运算后result为20,因为二进制下5为00000101,左移两位后为00010100。
int x = 20;
int result = x >> 2;
运算后result为5,因为二进制下20为00010100,右移两位后为00000101。
int x = -20;
int result = x >>> 2;
运算后result为1073741803,因为二进制下-20为1111111111111111111111111101100,无符号右移两位后为0011111111111111111111111101100。