本話題要討論的是一道面試題目:交換兩個變量的值。兩個變量而已,看似再簡單不過了,不過一道簡單的題目可以使用多種方式來完成, 其中有比較普通的實現(xiàn), 也有相對高明的實現(xiàn),雖然是一道簡單的題目,但是通過面試者對該題目的認知能力,就可以看出面試者的水平。
創(chuàng)新互聯(lián)堅持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都網(wǎng)站制作、成都做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的湖州網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!重點摘要:
1 通過中間變量交換。
2 通過求和與求差交換。
3 通過異或交換。
通過第 3 個變量
首先,我們給出最簡單的方式。
【例】 交換兩個變量的值。
package chapter2; 2. 3. public class Swap { 4. public static void main(String[] args) { 5. int x = 5; 6. int y = 10; 7. swap(x, y); 8. System.out.println(x); 9. System.out.println(y); 10. Value v = new Value(5, 10); 11. swap(v); 12. System.out.println(v.x); 13. System.out.println(v.y); 14. } 15. //無效的交換 16. public static void swap(int x, int y) { 17. int temp = x; 18. x = y; 19. y = temp; 20. } 21. //有效的交換 22. public static void swap(Value value) { 23. int temp = value.x; 24. value.x = value.y; 25. value.y = temp; 26. } 27.} 28. 29.class Value { 30. int x; 31. int y; 32. 33. public Value(int x, int y) { 34. this.x = x; 35. this.y = y; 36. } 37.}
程序運行結(jié)果如下:
5 10 10 5
這個程序同時給出了有效的交換(第22~26 行)與無效的交換(第16~20 行)。因為形參的改變是無法反作用于實參的,所以不能使用變量交換的方式,而是要使用通過引用來修改其成員變量的方式。這就類似與C / C++的語言中的指針效果。
通過相加的方式
通過第3個臨時變量,可以成功交換兩個變量的值,不過,有時,面試題目的要求會比較苛刻,就是不允許借助于臨時變量。這樣,就有些復(fù)雜了。
【例】 交換兩個變量的值2。
package chapter2; 2. 3. public class Swap2 { 4. public static void main(String[] args) { 5. Value v1 = new Value(5, 10); 6. swap(v1); 7. System.out.println("v1 的交換結(jié)果: "); 8. System.out.println(v1.x); 9. System.out.println(v1.y); 10. Value v2 = new Value(1200000000, 1500000000); 11. swap(v2); 12. System.out.println("v2 的交換結(jié)果: "); 13. System.out.println(v2.x); 14. System.out.println(v2.y); 15. Value v3 = new Value(-1200000000, -1500000000); 16. swap(v3); 17. System.out.println("v3 的交換結(jié)果: "); 18. System.out.println(v3.x); 19. System.out.println(v3.y); 20. } 21. 22. public static void swap(Value v) { 23. v.x = v.x + v.y; 24. v.y = v.x - v.y; 25. v.x = v.x -v.y; 26. } 27.}
程序運行結(jié)果如下:
v1的交換結(jié)果:
10 5
v2的交換結(jié)果:
1500000000 1200000000
v3的交換結(jié)果:
-1500000000 -1200000000
核心部分就是swap 方法(第22~26 行),該方法的3 條語句解釋為:
v.x = v.x + v.y; // 將 v.x 與 v.y 的和存儲在 v.x 中 v.y = v.x - v.y; //v.x – v.y 的值就是以前 v.x 的值,賦值給 v.y v.x = v.x -v.y; //v.x – v.y 的值就是以前 v.y 的值,賦值給 v.x
這樣,沒有通過臨時變量,也同樣交換了兩個變量的值。也許上面的方法一時不太容易理解,那么可以這樣考慮:
int z = v.x + v.y;v.y = z – v.y;v.x = z - v.y;
只不過這里使用另外一個變量z,而上面使用v.x 來存儲v.x 與v.y 的和,但是交換的效果是相同的。
注意程序的第10 行與第15 行,v.x 與v.y 的初始值非常大(?。?,這樣一來,當(dāng)執(zhí)行swap方法時(以第10 行為例):
v.x = v.x + v.y;
十六進制求和如下所示:
47868c00 ( v.x ) + 59682f00 ( v.y ) 結(jié)果: a0eebb00 ( v.x + v.y )
注意這個結(jié)果的最高位為1,結(jié)果為負數(shù)(十進制值為1594967296,也就是v.x 與v.y 的和已經(jīng)超過了int 類型的大(小)值,發(fā)生溢出。
執(zhí)行接下來的語句:
v.y = v.x - v.y;
這個計算就是使用溢出后的值1594967296減去v.y(1500000000),從int 類型的求差角度來說,結(jié)果再一次溢出了,十六進制求差如下所示:
a0eebb00 ( v.x + v.y ) 59682f00 ( v.y ) 結(jié)果: 47868c00 (結(jié)果 v.y )
經(jīng)過兩次溢出以后,又再次得出了我們期望的值。同樣,swap 方法的第3 條語句:
v.x = v.x -v.y;
a0eebb00 ( v.x + v.y ) 47868c00 ( v.y )
結(jié)果:59682f00(結(jié)果v.x)
也是發(fā)生了溢出,不過最后的差值也得出了期望的結(jié)果??梢钥闯?,當(dāng)兩個數(shù)之和很大(?。r,雖然發(fā)生了溢出,不過最后還是陰差陽錯地得到了正確的結(jié)果。盡管結(jié)果正確,這種相加的方式還不算十分可取。
通過異或的方式
位異或運算符(^)有這樣一個性質(zhì),就是兩個整型數(shù)據(jù)x 與y,有:
(x ^ y ^ y) == x
這說明,如果一個變量x 異或另外一個變量y 兩次,結(jié)果為x。通過這一點,可以實現(xiàn)交換變量的值。
【例】交換兩個變量的值3。
1.package chapter2; 2. 3. public class Swap3 { 4. public static void main(String[] args) { 5. Value v = new Value(5, 10); 6. swap(v); 7. System.out.println(v.x); 8. System.out.println(v.y); 9. } 10. 11. public static void swap(Value v) { 12. v.x = v.x ^ v.y; 13. v.y = v.x ^ v.y; 14. v.x = v.x ^ v.y; 15. } 16.}
程序運行結(jié)果如下:
10 5
swap 方法(第11~15 行)并不復(fù)雜,只有3 條語句:
v.x = v.x ^ v.y; (1) v.y = v.x ^ v.y; (2) v.x = v.x ^ v.y; (3)
可以這樣看:執(zhí)行(1)后,v.x 的值就是v.x(異或運算之前的值)與v.y 異或后的結(jié)果。類似數(shù)學(xué)上的代入法,將v.x(值為v.x ^ v.y)代入(2)中,于是(2)賦值運算符(=右側(cè)的表達式相當(dāng)于:
v.x ^ v.y ^ v.y //v.x與v.y都是運算之前的值
這個值就是v.x(異或運算之前的值)、然后賦值給左側(cè)的v.y。此時,v.y 的值就是異或運算之前v.x 的值。然后將v.x(值為v.x ^ v.y)、v.y(值為異或運算之前v.x 的值)代入(3)中賦值運算符右側(cè),代入后表達式相當(dāng)于:
v.x ^ v.y ^ v.x //v.x與v.y都是運算之前的值
。推薦:http://www.lemonpai.com/1508.html
這個值就是v.y,然后賦值給v.x,至此,完成兩個變量的交換。異或方式要比相加方式更加可取,因為異或運算不涉及溢出。綜合這3 種方式而言,第1 種方式最容易理解,第3 種方式相對成熟老練,如果是個人編寫程序,建議還是使用最簡單的方式,這樣不容易出錯,而且代碼具有可讀性,便于后期的維護,如果是在面試過程中,那就可以選擇第3 種方式來證明下自己的能力。
總結(jié):
1. 一個變量x 異或另一個變量y 兩次,結(jié)果的值為x。
2. 異或運算可以交換兩個變量的值,并且這種方式比相加交換的方式更可取些。
舉一反三
既然相加(第2 種方式)能夠?qū)崿F(xiàn)交換兩個變量的值,那么相減肯定也能實現(xiàn)。編寫一個程序,不要借助第3 個臨時變量,實現(xiàn)相減操作交換兩個變量的值。
本文作者梁勇出自檸檬派,請注明出處
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。
分享文章:大數(shù)據(jù)Java-交換變量的3種方式-創(chuàng)新互聯(lián)
URL鏈接:http://muchs.cn/article24/ddhjce.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供Google、微信小程序、小程序開發(fā)、網(wǎng)站策劃、營銷型網(wǎng)站建設(shè)、品牌網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容