数组交换
在数组元素交换中,我们通常会拿一个临时的碗取装载临时链接,通常写法是这样的
/**
* 交换元素数组中两个下标元素的位置
*
* @param arr
* @param a
* @param b
*/
public void swapA(int[] arr, int a, int b) {
int tmp = arr[a];
arr[a] = arr[b];
arr[b] = tmp;
}
那么在一些的也有这样写的方法
/**
* 交换元素
*
* @param arr
* @param a
* @param b
*/
public static void swapB(int[] arr, int a, int b) {
arr[a] = arr[a] ^ arr[b];
arr[b] = arr[a] ^ arr[b];
arr[a] = arr[a] ^ arr[b];
}
通常情况下二者当a不等于b的时候两者的作用是一致的,
那么为什么说是通常情况下的,那么下面是个调试当a=b时查看两者的结果;
发现观察看方式B却改变的元素,自己替换自己的时候却发生了自身的内容,所以方式A和方式B是不等的,当然为了耍酷可以简单改写方式B为
/**
* 交换元素
*
* @param arr
* @param a
* @param b
*/
public static void swapB(int[] arr, int a, int b) {
// 这里不能删除,否则自己替换自己发生了改变
if (a == b) {
return;
}
arr[a] = arr[a] ^ arr[b];
arr[b] = arr[a] ^ arr[b];
arr[a] = arr[a] ^ arr[b];
}
中值算法
这个常在二分法中用到,下面来观察下面求中间值的算法
A. (a+b)/2
B. a+(b-a)/2
C. (a+b)>>1
D. a+(b-a)>>1
我们知道算术运算/2和位运算>>1效果上一致的,但在效率上而言,位运算是远大于算术运算;
a+b可能存在越界,即int+int>int 但 a+(b-a)>>1就不会越界,可以分a是大还是小去讨论结果都不会越界,当a大的时候,后面的结果为负a佳航绝对值比自己小的负值是不会越界的,当a小时则更不可能,所以D时最好的实现,既能防越界,也有更好的运算效率。