一、基础思想篇
1. 二进制
二进制属于一种进位制法,其中基数为2,也就是说,二进制的数位就是2^n的形式
计算机为什么使用二进制?
- 二进制的数据表达具有抗干扰能力强、可靠性高的优点。
- 二进制非常适合逻辑运算
在Java中通过BigInteger可以进行二进制的转换运算
import java.math.BigInteger;
public class Lesson1_1 {
/**
* @Description: 十进制转换成二进制
* @param decimalSource
* @return String
*/
public static String decimalToBinary(int decimalSource) {
BigInteger bi = new BigInteger(String.valueOf(decimalSource)); //转换成BigInteger类型,默认是十进制
return bi.toString(2); //参数2指定的是转化成二进制
}
/**
* @Description: 二进制转换成十进制
* @param binarySource
* @return int
*/
public static int binaryToDecimal(String binarySource) {
BigInteger bi = new BigInteger(binarySource, 2); //转换为BigInteger类型,参数2指定的是二进制
return Integer.parseInt(bi.toString()); //默认转换成十进制
}
}
二进制的位操作
向左位移
二进制左移一位就是表示数字翻倍,要注意数字溢出
向右位移
二进制右移一位等于除以2的商然后取整
Java代码左移和右移
import java.math.BigInteger;
public class Lesson1_2 {
/**
* @Description: 向左移位
* @param num-等待移位的十进制数, m-向左移的位数
* @return int-移位后的十进制数
*/
public static int leftShift(int num, int m) {
return num << m;
}
/**
* @Description: 向右移位
* @param num-等待移位的十进制数, m-向右移的位数
* @return int-移位后的十进制数
*/
public static int rightShift(int num, int m) {
return num >>> m;
}
}
java代码中规定了两种右移
逻辑右移:右移一位,左边补0。例:1010 1111 -> 0101 0111
算术右移:术右移时保持符号位不变,除符号位之外的右移一位并补符号位 1。补的 1 仍然在符号位之后。例:11···1001011 -> 111···100101
或(|)
参与操作的位中只要有一个位是 1,那么最终结果就是 1(真)。例:110101 或 100011 -> 110111
与(&)
参与操作的位中必须全都是 1,那么最终结果才是 1(真),否则就为 0(假)。例:110101 与 100011 -> 100001
异或(^)
参与操作的位相同,那么最终结果就为 0(假),否则为 1(真)。例:110101 异或 100011 -> 010110
2.余数
-
余数的特性:整数是没有边界的,可能是正无穷,也可能是负无穷。余数却总在一个固定的范围内。生活中可以使用余数来计算星期几,web编程中也可以用余数来计算分页
-
同余定理:两个整数 a 和 b,如果它们除以正整数 m 得到的余数相等,我们就可以说 a 和 b 对于模 m 同余。同余定理其实就是用来分类的
-
求余过程就是一个哈希函数,每个编程语言都有对应的哈希函数Hash,也是把任意长度的输入(又叫做预映射pre-image)通过哈希算法变换成固定长度的输出,该输出就是散列值
3.迭代法
迭代法,简单来说,其实就是不断地用旧的变量值,递推计算新的变量值。
迭代法一般可以使用循环语言来实现,例如
public class Test {
/**
* @Description: 算算舍罕王给了多少粒麦子
* @param grid-放到第几格
* @return long-麦粒的总数
*/
public static long getNumberOfWheat(int grid) {
long sum = 0; // 麦粒总数
long numberOfWheatInGrid = 0; // 当前格子里麦粒的数量
numberOfWheatInGrid = 1; // 第一个格子里麦粒的数量
sum += numberOfWheatInGrid;
for (int i = 2; i <= grid; i ++) {
numberOfWheatInGrid *= 2; // 当前格子里麦粒的数量是前一格的2倍
sum += numberOfWheatInGrid; // 累计麦粒总数
}
return sum;
}
}
迭代法的应用:
- 求数值的精确或者近似解。典型的方法包括二分法和牛顿迭代法。
- 在一定范围内查找目标值。典型的方法包括二分查找。
- 机器学习算法中的迭代。相关的算法或者模型有很多,比如 K- 均值算法、PageRank 的马尔科夫链、梯度下降法等等。迭代法之所以在机器学习中有广泛的应用,是因为很多时候机器学习的过程,就是根据已知的数据和一定的假设,求一个局部最优解。而迭代法可以帮助学习算法逐步搜索,直至发现这种解。