位运算-查找数组中唯一成对的数
基礎(chǔ)實例一:使用位運算判斷數(shù)的奇偶性
實例代碼:
public class Test {public static void main(String[] args) {System.out.println(isOdd(49));System.out.println(isOdd(50));}// 與運算public static boolean isOdd(int i){return (i & 1) != 0; // 奇數(shù)最后一位二進制為 1,偶數(shù)最后一位二進制為 0} }基礎(chǔ)實例二:位運算判斷一個數(shù)轉(zhuǎn)為二進制后的第i位數(shù)是0還是1
實例代碼:
public class Test {public static void main(String[] args) {// 與運算 int x = 85;System.out.println("x的第五位二進制位的數(shù)為:" + ((((x&(1<<4))>>4)==1)?"1":"0"));// 比如85的二進制為1010101,我們將它的二進制與1向左移4位來做與運算// 就是 1010101 & 0010000 得出結(jié)果0010000 再右移4位 即可得出結(jié)果} }
基礎(chǔ)實例三:位運算交換兩個整數(shù)變量的值
實例代碼:
public class Test {// 異或運算public static void main(String args[]){int a=10;int b=20;a=a^b;b=b^a;a=a^b;System.out.println(a+"\t"+b);// 異或運算性質(zhì) x ^ x ^ y == y,因為x ^ x == 0,0 ^ y == y} }基礎(chǔ)實例四:使用位運算,不用判斷語句,求整數(shù)的絕對值
實例代碼:
public class Test {// 異或運算public static void main(String args[]){System.out.println(my_abs(-53));System.out.println(my_abs(53));}public static int my_abs(int a){/*** 對一個數(shù)進行位運算,是在這個數(shù)的補碼上運行的* 正數(shù)的補碼是原碼,負數(shù)的補碼為原碼除了最高的符號為,取反,然后加一* int 型,先右移31位取符號位 如果a位正數(shù),i=0;a為負數(shù),i=-1* 一個數(shù)與-1即與0xFFFFFFFF異或就相當(dāng)與取反* 因此,a與i異或后再減i(因為i為0或-1,所以減i即是要么加0要么加1)也可以得到絕對值*/int i = a >> 31;return ((a ^ i) -i);} }異或運算特點:
題目一:找出唯一成對的數(shù)
1-1000這1000個數(shù)放在含有1001個元素的數(shù)組中,只有唯一的一個元素值重復(fù),其他均只出現(xiàn)一次。每個數(shù)組元素只能訪問一次,設(shè)計一個算法,將它找出來;不用輔助存儲空間,能否設(shè)計一個算法實現(xiàn)?
解題思路:這里使用的原理是連續(xù)的數(shù)字異或可以消除重復(fù),A ^ A=0,( A ^ A ) ^ B ^ ( C ^ C ) =B,但是我們的題目有兩個元素重復(fù),假如使用一次異或那么這個重復(fù)的元素就會被消掉了。所以這里有一個小技巧,就是使用兩次異或,先對不包含重復(fù)值數(shù)組進行異或,在對包含重復(fù)值的數(shù)組進行異或,這樣下來,就相當(dāng)于除了重復(fù)值每個值都異或了兩次,而重復(fù)的值異或了三次,這樣異或下來,就只剩一個重復(fù)的值了,就成功找出來了。為了方便測試,這里只使用了11個元素的數(shù)組,自行改成1001即可(示例代碼也給出了使用輔助存儲空間的解法)。這里有一個特殊的點,就是這里給出了數(shù)組是1-1000連續(xù)的數(shù)并且只有唯一一個元素值重復(fù),所以才能構(gòu)造進行異或兩次的解法。
實例代碼:
import java.util.Random;public class 唯一成對的數(shù) {public static void main(String[] args) {int N = 11;int [] arr = new int[N];for (int i = 0; i < arr.length-1; i++) {arr[i] = i+1;}// 最后一個數(shù),是隨機數(shù)arr[arr.length-1] = new Random().nextInt(N-1)+1;// 隨機下標int index = new Random().nextInt(N);swap(arr, index, arr.length-1);for (int i = 0; i < arr.length; i++) {System.out.print(arr[i]+ " ");}System.out.println();int x1=0;for(int i=1;i <= N -1;i++){x1 = (x1^i); // 求得1到N-1這些連續(xù)的數(shù)的異或}for(int i=0;i < N ;i++){x1 = (x1^arr[i]); // 再與原來的數(shù)組arr異或,這樣重復(fù)的數(shù)就有三個,不重復(fù)的數(shù)有兩個,異或消除重復(fù)后,剩下的就是重復(fù)的數(shù)了}System.out.println(x1);System.out.println("使用輔助空間實現(xiàn)============");int []helper = new int[N];for (int i = 0; i < helper.length; i++) {helper[arr[i]]++;}for (int i = 0; i < helper.length; i++) {if (helper[i]==2) {System.out.println(i);break;}}}public static void swap(int[] array,int x,int y){int xx = array[x];int yy = array[y];array[x] = yy;array[y] = xx;}}運行結(jié)果:
題目二:找出落單的那個數(shù)
一個數(shù)組里除了某一個數(shù)字之外,其他的數(shù)字都出現(xiàn)了兩次。請寫出程序找出這個只出現(xiàn)一次的數(shù)字。
解題思路:這個題目經(jīng)過上一個題目的學(xué)習(xí),就很簡單了,直接進行異或即可。
實例代碼:
public class Test {// 異或運算public static void main(String args[]){int []a = {1,1,2,2,3,4,3};int x1 = 0;for (int i = 0; i < a.length; i++) {x1 = x1 ^ a[i];}System.out.println(x1);} }
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/xiaoyh/p/10247283.html
總結(jié)
以上是生活随笔為你收集整理的位运算-查找数组中唯一成对的数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梦到要着火的冒烟是什么意思
- 下一篇: react-native-Cocoapo