Java異或運算應(yīng)用場景詳解
基本概念
異或運算,符號為XOR或者^,是二進(jìn)制的運算,運算法則為相同為0,不同為1,我記得時候反正總會忘(和同或記反),所以這里直接把異或理解為"不進(jìn)位的二進(jìn)制相加".舉個栗子:
1000111 和 1110001 異或
按照不進(jìn)位相加的運算方法:最小位都是1 相加為2也就是10(二進(jìn)制運算), 因為是不進(jìn)位的運算 所以直接本位為0 就可以了,其他位如法炮制:0110110.
重要性質(zhì)
異或運算符合交換律和結(jié)合律
交換律:a^b^c^d 和 a^d^c^b是一樣的
結(jié)合律:a^b^c^d和a^(b^c)^d是一樣的
0^N==N
N^N==0
應(yīng)用場景
1.利用異或交換兩個數(shù)
絕大多數(shù)這個操作都是沒屁硌楞嗓子的無意義操作....它的好處就是不用申請額外空間完成操作,但是不用異或操作也可以實現(xiàn)不申請額外空間的交換(異或操作還有可能出錯)---不創(chuàng)建臨時變量交換兩個變量傳送門(可以看下這篇博客)
int a = 10; int b = 11; a = a^b; b = a^b; a = a^b; System.out.println(a); System.out.println(b);
這三個a^b你懵不懵?反正我第一次看見是挺懵的
設(shè) a的初始值為x b的初始值為y
a = x^y
b = (x^y)^y 因為y^y為0 x^0為x 所以b中現(xiàn)在存儲的數(shù)據(jù)為 x(交換完成)
a = x^y^x 同理 ==x
(寄!寫著寫著發(fā)現(xiàn)按值傳遞按址傳遞好不懸給忘了)
值得一提的是因為異或操作的性質(zhì),如果a和b是同一塊內(nèi)存的話 會導(dǎo)致最后交換結(jié)果為0
2.一個數(shù)組中有一個數(shù)出現(xiàn)了奇數(shù)次,其他數(shù)都出現(xiàn)了偶數(shù)次,找到并打印這個數(shù)
這題用性質(zhì)做爽的一匹,直接把他們?nèi)籍惢蛟谝黄鹁托辛?根據(jù)結(jié)合律,出現(xiàn)偶數(shù)個的數(shù)全都異或在一起變成零,而奇數(shù)個數(shù)的數(shù)異或在一起會剩下一個,然后本身和0異或還是本身;
public static int select(int arr[]) { int sum = 0; for(int i = 0;i<arr.length;i++) { sum^=arr[i]; } return sum; } public static void main(String[] args) { int [] arr = {1,1,1,1,3,3,3,3,3,5,5,5,5}; int a = select(arr); System.out.println(a); }
3.取一個二進(jìn)制數(shù)中的最后一個1
如1001110 取得就是倒數(shù)第二個
我們先設(shè)N是一個二進(jìn)制數(shù)
N: 1 0 0 0 1 1 1 1 1 1 1
~N: 0 1 1 1 0 0 0 0 0 0 0(取反)
~N+1:0 1 1 1 0 0 0 0 0 0 1
然后把N和~N+1進(jìn)行按位與(&)操作
得到 0 0 0 0 0 0 0 0 0 0 1
public static int selectlastone(int n) { int n1 = ~n+1; int s = n&n1; return s; } public static void main(String[] args) { int n = 10; System.out.println(Integer.toBinaryString(n));//按二進(jìn)制打印n int a = selectlastone(n); System.out.println(Integer.toBinaryString(a));//按二進(jìn)制打印a }
4.一個數(shù)組中有兩個數(shù)出現(xiàn)了奇數(shù)次,其他數(shù)都出現(xiàn)了偶數(shù)次,找到并打印這個數(shù)
public static int select(int[] arr) { int eor = 0; for (int i = 0; i < arr.length; i++) { eor ^= arr[i]; } int rightOne = (~eor+1)&eor; // 提取出最右的1 int onlyOne = 0; for (int i = 0 ; i < arr.length;i++) { if ((arr[i] & rightOne) != 0) { onlyOne ^= arr[i]; } } System.out.println(onlyOne);//onlyOne是其中一個 return eor ^ onlyOne;//返回的是另一個 } public static void main(String[] args) { int [] arr= {1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4}; int a = select(arr); System.out.println(a); }
設(shè)這兩個單獨的數(shù)分別為a b
先把所有數(shù)字都異或在一起 偶數(shù)消除掉 留下的是 a^b
a和b至少有一位是不同的 所以a^b里面至少有一個1 我們?nèi)〕鲎笥疫叺? 得到rightone
a或者b不同的話 這個位置上肯定其中一個是 1 一個是 0;
我們假設(shè)a這個位置上是1 b這個位置上是0
(反正除了我們要找的數(shù)以外都是偶數(shù)個,剩下的那些本位置為1的數(shù)是0個還是6個8個都不重要)
可以把這個數(shù)組分為兩組 A組 這個位上為1的元素 B組 這個位上為0的元素
而在A組中 包含偶數(shù)個其他元素和奇數(shù)個a 所以再次轉(zhuǎn)變成問題2求出onlyone
然后再有a^b = eor a^eor = b 求出另一個元素
5.求二進(jìn)制數(shù)中有多少個1
public static int onecount(int a) { int count = 0; while(a!=0) { int rightone = ((~a)+1)&a; count++; a ^= rightone; } return count; } public static void main(String[] args) { int a = 55; int count = onecount(a); System.out.println(count); }
用應(yīng)用3輕松解決
總結(jié)
到此這篇關(guān)于Java異或運算應(yīng)用場景詳解的文章就介紹到這了,更多相關(guān)Java異或運算內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java定時任務(wù)實現(xiàn)優(yōu)惠碼的示例代碼
在Java中實現(xiàn)定時任務(wù)來發(fā)放優(yōu)惠碼,我們可以使用多種方法,比如使用java.util.Timer類、ScheduledExecutorService接口,或者更高級的框架如Spring的@Scheduled注解,這篇文章主要介紹了Java定時任務(wù)實現(xiàn)優(yōu)惠碼的實例,需要的朋友可以參考下2024-07-07使用SpringBoot項目導(dǎo)入openfeign版本的問題
這篇文章主要介紹了使用SpringBoot項目導(dǎo)入openfeign版本的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03SpringBoot配置文件中系統(tǒng)環(huán)境變量存在特殊字符的處理方式
這篇文章主要介紹了SpringBoot配置文件中系統(tǒng)環(huán)境變量存在特殊字符的處理方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-02-02Java?C++題解leetcode1441用棧操作構(gòu)建數(shù)組示例
這篇文章主要為大家介紹了Java?C++題解leetcode1441用棧操作構(gòu)建數(shù)組示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10IDEA創(chuàng)建SpringBoot父子Module項目的實現(xiàn)
本文主要介紹了IDEA創(chuàng)建SpringBoot父子Module項目的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05Java Math類、Random類、System類及BigDecimal類用法示例
這篇文章主要介紹了Java Math類、Random類、System類及BigDecimal類用法,結(jié)合實例形式分析了java數(shù)值運算相關(guān)的Math類、Random類、System類及BigDecimal類基本功能與使用技巧,需要的朋友可以參考下2019-03-03Java實現(xiàn)有限狀態(tài)機(jī)的推薦方案分享
有限狀態(tài)機(jī)又稱有限狀態(tài)自動機(jī),簡稱狀態(tài)機(jī),是表示有限個狀態(tài)以及在這些狀態(tài)之間的轉(zhuǎn)移和動作等行為的數(shù)學(xué)模型,這篇文章主要給大家介紹了關(guān)于Java實現(xiàn)有限狀態(tài)機(jī)的推薦方案,需要的朋友可以參考下2021-11-11通過spring注解開發(fā),簡單測試單例和多例區(qū)別
這篇文章主要介紹了通過spring注解開發(fā),簡單測試單例和多例區(qū)別,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08