·一、位运算
1. int类型的数据在大多数语言中,以32位的二进制数表示。
2. 设计一个函数,以打印int类型的二进制形式,思路如下:
循环遍历整数的32位(即从31到0),对于每一位执行以下操作:
使用位运算符 “&” 将当前位与二进制掩码 1 << i 进行按位与运算。这将保留当前位的值并清除其他位上的值。
检查当前位的值。如果它为0,则输出"0";否则,输出"1"。
重复上述步骤,直到所有位都被处理完毕。
public static void print(int num){//输出int类型的二进制形式
for (int i = 31; i >=0 ; i--) {
System.out.print((num&(1<<i))==0?"0":"1");
}
System.out.println();
}
为什么遍历时,是从31位到0位,而不是从0位到32位?
**答:**在输出时,是从左到右依次输出每一位的值,因此最低位(即二进制数的最右边一位)输出在了最前面,而最高位(即二进制数的符号位,如果是负数则为 1)输出在了最后面。因此,这种输出方式会得到二进制数的反向输出结果。如果想要正常输出二进制数,需要将循环的处理顺序从第 31 位到第 0 位进行。
3. 关于int类型的数据,在C++当中为无符号数,而在Java当中为有符号数,因此:
在C++当中,int能表示的数值的范围为:0~2^32-1;
而在Java中,因为有符号位(符号位为1表示负数),所以int能表示的数值的范围为:-231~231-1;
关于负数:第32位必为1,其余31位取反再+1即为负数绝对值(正负转换都是:~a+1);
⚠️所有正数都有负数对应,但是系统最小的负数取反加一还是自己;
左移:<< 最后一位补零 右移:>> 不带符号(符号位补0) >>>带符号(符号位不动,其余右移)。
System.out.println("2⃣️查看Java中int的最大最小值:");
int max=Integer.MAX_VALUE;
int min=Integer.MIN_VALUE;
System.out.println(max);
System.out.println(min);
print(max);
print(min);
print(-1);
System.out.println("3⃣️️验证与非或运算:");
int a = 12319283;
int b = 3819283;
print(a);
print(b);
print(~b);
System.out.println("=============");
print(a | b);
print(a & b);
print(a ^ b);//抑或:不同为1,相同为0
二、算法
1.定义
1)有具体的问题
2)有设计解决这个问题的具体流程
3)有评价处理流程的可量化指标
2.分类
1)明确知道怎么算的流程
2)明确知道怎么试的流程
三、阶乘的算法(给定一个参数N,返回1!+2!+3!+…+N!的结果)
1.解法一
老老实实算每个阶乘然后加起来:1!+2!+3!+…+n!
2.解法二
每次用上次得到的乘积再乘上这次的新数字再相加:1!+1!×2+2!×3+…+(n-1)!×n
public static long SOF(long n){
long sum=0;
long ans=1;
for (long i = 1; i <=n; i++) {
ans*=i;
sum+=ans;
}
System.out.println(ans);
System.out.println(sum);
return sum;
}
四、三种经典排序
1.选择排序(Selection Sort)
-
在全部数字当中,挑选最小的数,推到第一位
-
然后总长度-1,在剩下的数当中挑选,再补到目前的第一位(总长度的第2位)以此类推
-
public static void selectSort(int[] arr){//选择排序主体 if(arr==null || arr.length<2){ return ; } for (int i = 0; i < arr.length; i++) {//i的值代表从左到右 int minIndex=i;//默认i是最小值 for (int j = i+1; j < arr.length; j++) {//从i的右边开始遍历 minIndex= arr[j]<arr[minIndex]? j : minIndex ;//锁定i后方的最小值的下标 } swap(arr,i,minIndex);//交换到最前面i的位置 } }
2.冒泡排序(Bubble Sort)
-
两两比较,每次只和相邻位置的数比大小
-
按大小更换左右位置,然后向后推进
-
当推到最后一位时,重回第一位开始比较
-
public static void bubbleSort(int[] arr){ if(arr==null || arr.length<2){ return ; } for (int i = arr.length-1; i >0 ; i--) {//每次循环冒泡完最大值都在最右边,所以每次范围从右向左-1 for (int j = 0; j < arr.length-1; j++) {//从左往右冒泡的过程 if (arr[j]>arr[j+1]){//如果大,就交换 swap(arr,j,j+1); } } } }
3.插入排序(Insertion Sort)
-
第一次前两个排序,第二次前三个排序,以此类推
-
在排序的过程中,将每次新加入的数字按大小顺序插入到前几位已经排好的数当中,以此类推
-
public static void insertSort(int[] arr){//插入排序主体 if(arr==null || arr.length<2){ return ; } for (int i = 1; i < arr.length; i++) { for (int j = i-1; j >= 0 && arr[j+1]<arr[j]; j--) { swap(arr,j,j+1); //注意,此处是j+1而不是i,因为在每一次的循环中,i是固定的,代表右边界。而j的值每次向左递减 } } }