王道论坛机试指南学习笔记(三)数学问题

1. 2的n次方

- 移位

//'<<','>>'为移位符号
//二进制中表示左右移动n位
//相当于十进制中2的n次方
1 << n;

- power

//普通求法,求x的n次方
public static int power(int x, int n){
	int result = 1;
	for (int i = 0; i < n; i++) {
		result *= x;
	}
	return result;
}

2. 特殊值

- 最大值

int max = Math.max(a, b);

- 绝对值

int abs = Math.abs(x);

3. 取整

//向下取整
double x = Math.floor(y);
//向上取整
double x = Math.ceil(y);
//四舍五入
double x = Math.round(y);

4. 数位拆解

- 数学方法

  • 按照数学思想,取余数,逐位计算

    //将小于100000000的大整数分割存储为每位数的列表
    public static List<Integer> splitBigInt(long x){
        int y = 100000000;
        List<Integer> list = new ArrayList<>();
        while (y>0){
            int r = (int)x/y;
            list.add(r);
            x = x%y;
            y /= 10;
        }
        return list;
    }
    //将两个列表中的每位数依次相乘并加和
    public static int specialMulti(List<Integer> a, List<Integer> b){
        int result = 0;
        for (int i = 0; i < a.size(); i++) {
            for (int j = 0; j < b.size(); j++) {
                result += a.get(i)*b.get(j);
            }
        }
        return result;
    }
    

- 代码方法

  • 按照代码的思想,将数字转为String,直接计算

    public static int specialMulti2(String a, String b){
        int result = 0;
        for (int i = 0; i < a.length(); i++) {
            for (int j = 0; j < b.length(); j++) {
                result += (a.charAt(i)-'0')*(b.charAt(j)-'0');
            }
        }
        return result;
    }
    

5. 进制转换

- n转10

//进制数在2~16之间
public static int changeSystem2Ten(int system, String str){
    int length = str.length(), result = 0;
    for (int i = length-1; i >= 0; i--) {
        char ch = str.charAt(i);
        int temp = 0;
        if(ch>='0'&&ch<='9') temp = ch - '0';
        else if(ch>='a'&&ch<='z') temp = ch-'a'+10;
        else if(ch>='A'&&ch<='Z') temp = ch-'A'+10;
        result += temp*power(system, length-i-1);
    }
    return result;
}

- 10转n

public static String changeSystemFromTen(int system, int num){
    String result = "";
    int r, temp;
    if(num==0){
        result = "0";
        return result;
    }
    while (num!=0){
        temp = num/system;
        r = num%system;
        String str = String.valueOf(r);
        if(r>9){
            switch (r){
                case 10:
                    str = "A";
                    break;
                case 11:
                    str = "B";
                    break;
                case 12:
                    str = "C";
                    break;
                case 13:
                    str = "D";
                    break;
                case 14:
                    str = "E";
                    break;
                case 15:
                    str = "F";
                    break;
            }
        }
        result = str + result;
        num = temp;
    }
    return result;
}

6. GCD & LCM

- GCD

  • 欧几里得算法求最大公约数
    在这里插入图片描述

  • 代码

    public static int GCD(int x, int y){
        if(x<=0&&y<=0) return -1;
        else if (y==0) return x;
        else return GCD(y, x%y);
    }
    

- LCM

public static int LCM(int x, int y){
    return x*y/GCD(x, y);
}

7. 质数

- 判断质数

public static boolean isPrime(int x){
    if(x<0) return false;
    if(x<2) return true;
    int s = (int)Math.floor(Math.sqrt(x));
    for (int i = 2; i <= s; i++) {
        if(x%i==0)return false;
    }
    return true;
}

- 素数筛法

  • 从2开始遍历区间内的全部整数,将每个素数的全部倍数标记为非素数
public static List<Integer> findPrimeInDomain(int max){
    boolean[] mark = new boolean[max];
    List<Integer> primeList = new ArrayList<>();
    //初始化,默认全部数字为质数
    for (int i = 0; i < max; i++) {
        mark[i] = true;
    }
    for (int i = 2; i < max; i++) {
        //当前为非质数,跳过
        if(!mark[i]) continue;
        //找到一个质数,加入列表
        primeList.add(i);
        //从i*i开始标记,因为小于i*i的非质数一定已经被小于i的质数标记过
        for (int j = i*i; j < max; j+=i) {
            mark[j] = false;
        }
    }
    return primeList;
}

- 分解质因数

public static HashMap<Integer, Integer> factorizePrimeFactor(int x){
    //使用哈希表,存储x中包含的质因数以及包含的个数
    HashMap<Integer, Integer> resultMap = new HashMap<>();
    //利用素数筛法,获取当前区间内的全部质数列表
    List<Integer> primeList = findPrimeInDomain(x);
    int index = 0, prime = primeList.get(index), count = 0;
    //若x不为1,则继续分解
    while (x!=1){
        //当x能分解出多个质因数,循环分解
        while (x%prime==0){
            //若哈希表中已有此质数,则个数加一
            if(resultMap.containsKey(prime)){
                count = resultMap.get(prime)+1;
            }
            //若表中无此质数,则个数为1
            else {
                count = 1;
            }
            //使用put方法,覆盖原有质数的哈希对
            resultMap.put(prime, count);
            x /= prime;
        }
        //若当前质数不能整除x,则计算下一个质数
        index += 1;
        prime = primeList.get(index);
    }
    return resultMap;
}

8. 二分求幂

- 求a^b

  • 循环求解效率低,需要执行b次乘法;
  • 应该充分利用平方的概念,将b转化为二进制,求b分解出的2的n次方的和;
  • 每次对1000取余,降低数量级,结果只要后三位。
public static int power2(int x, int n){
    int result = 1;
    while (n != 0){
        if(n%2==1){
            result *= x;
            result %= 1000;
        }
        n /= 2;
        x *= x;
        x %= 1000;
    }
    return result;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值