JAVA不借助第三个变量实现两个变量交换的思考
生活随笔
收集整理的這篇文章主要介紹了
JAVA不借助第三个变量实现两个变量交换的思考
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
網上存在三種方法:
1) 算術運算
簡單來說,就是通過+和-運算來實現。代碼如下:
int a,b; a=10;b=12; a=b-a;?? //a=2;b=12 b=b-a;?? //a=2;b=10 a=b+a;?? //a=12;b=10
通過以上運算,a和b中的值就進行了交換。表面上看起來很簡單,但是不容易想到,尤其是在習慣標準算法之后。
此算法與標準算法相比,多了三個計算的過程,但是沒有借助臨時變量。(以下稱為算術算法)
2) 指針操作
對指針的操作實際上進行的是整數運算。比如:兩個int指針相減得到一個整數N,該整數表示兩個指針變量在內存中的儲存位置隔了N*sizeof(int)個字節;int指針和一個整數相加,例如“a+10”表示以a為基地址,偏移為10*sizeof(int)處的int變量。所以我們完全可以通過和算術算法類似的運算來完成指針變量值的交換,從而達到交換變量的目的。即:
int *a,*b;??? a=new int(10);??? ??? //給指針賦值 b=new int(20);??? ??? //a=0x00030828,b=0x00030840 a=(int*)(b-a);??? ??? //a=0x00000006 b=(int*)(b-int(a));?? //b=0x00030828 a=(int*)(b+int(a));?? //a=0x00030840
需要注意的是:最后三句話中,只有第一句是兩個指針之間的計算,其他都是指針和整數的計算,否則會導致計算錯誤,嚴重導致系統出錯。
通過以上運算a、b的地址就完成了交換,a指向了原先b指向的值,b指向原先a指向的值!
此算法同樣沒有使用第三變量就完成了值的交換,與算術算法比較它顯得不好理解,但是它有它的優點即在交換很大的數據類型時,比如說自定義的大型結構或者類,它的執行速度比算術算法快。因為它交換的時地址,而變量值在內存中是沒有移動過的。(以下稱為地址算法)
3) 位運算
通過異或運算也能實現變量的交換,這也許是最為神奇的,請看以下代碼:
int a=10,b=12;? //a=1010^b=1100; a=a^b;??? //a=0110^b=1100; b=a^b;??? //a=0110^b=1010; a=a^b;??? //a=1100=12;b=1010; ? 如果仔細思考,可以發現實際上有無數種方法。為什么需要第三個變量?我想這是絕大多數初學編程時都思考過的問題。我本身是做信號的,所以從信息的角度來分析。兩個變量,必然存在兩份信息(姑且以份為單位),如果直接交換,a=b,則a原來的信息丟失,所以引入一個臨時變量來保存a的信息,以確保信息完整性。也就是說,temp的作用就是保存交換過程可能損失的信息量,那么只要這個信息量不損失,則無需temp.做編解碼的人都知道,編碼的是殘差數據。殘差數據包含的就是那額外的信息量。那么,完全可以在交換過程中傳遞額外信息,也就是a,b之間的耦合信息,則交換過程不會發生信息丟失,也就無需第三個變量。這耦合信息可以是a-b,也可以是a^b,還可以是a*b.如: a=a*b; a=a/b; b=a/b; 同樣可以完成交換(僅提供思路,未考慮除0溢出等問題)。舉一反三,可以有無窮種方法,但原理都是一樣的。
簡單來說,就是通過+和-運算來實現。代碼如下:
int a,b; a=10;b=12; a=b-a;?? //a=2;b=12 b=b-a;?? //a=2;b=10 a=b+a;?? //a=12;b=10
通過以上運算,a和b中的值就進行了交換。表面上看起來很簡單,但是不容易想到,尤其是在習慣標準算法之后。
此算法與標準算法相比,多了三個計算的過程,但是沒有借助臨時變量。(以下稱為算術算法)
2) 指針操作
對指針的操作實際上進行的是整數運算。比如:兩個int指針相減得到一個整數N,該整數表示兩個指針變量在內存中的儲存位置隔了N*sizeof(int)個字節;int指針和一個整數相加,例如“a+10”表示以a為基地址,偏移為10*sizeof(int)處的int變量。所以我們完全可以通過和算術算法類似的運算來完成指針變量值的交換,從而達到交換變量的目的。即:
int *a,*b;??? a=new int(10);??? ??? //給指針賦值 b=new int(20);??? ??? //a=0x00030828,b=0x00030840 a=(int*)(b-a);??? ??? //a=0x00000006 b=(int*)(b-int(a));?? //b=0x00030828 a=(int*)(b+int(a));?? //a=0x00030840
需要注意的是:最后三句話中,只有第一句是兩個指針之間的計算,其他都是指針和整數的計算,否則會導致計算錯誤,嚴重導致系統出錯。
通過以上運算a、b的地址就完成了交換,a指向了原先b指向的值,b指向原先a指向的值!
此算法同樣沒有使用第三變量就完成了值的交換,與算術算法比較它顯得不好理解,但是它有它的優點即在交換很大的數據類型時,比如說自定義的大型結構或者類,它的執行速度比算術算法快。因為它交換的時地址,而變量值在內存中是沒有移動過的。(以下稱為地址算法)
3) 位運算
通過異或運算也能實現變量的交換,這也許是最為神奇的,請看以下代碼:
int a=10,b=12;? //a=1010^b=1100; a=a^b;??? //a=0110^b=1100; b=a^b;??? //a=0110^b=1010; a=a^b;??? //a=1100=12;b=1010; ? 如果仔細思考,可以發現實際上有無數種方法。為什么需要第三個變量?我想這是絕大多數初學編程時都思考過的問題。我本身是做信號的,所以從信息的角度來分析。兩個變量,必然存在兩份信息(姑且以份為單位),如果直接交換,a=b,則a原來的信息丟失,所以引入一個臨時變量來保存a的信息,以確保信息完整性。也就是說,temp的作用就是保存交換過程可能損失的信息量,那么只要這個信息量不損失,則無需temp.做編解碼的人都知道,編碼的是殘差數據。殘差數據包含的就是那額外的信息量。那么,完全可以在交換過程中傳遞額外信息,也就是a,b之間的耦合信息,則交換過程不會發生信息丟失,也就無需第三個變量。這耦合信息可以是a-b,也可以是a^b,還可以是a*b.如: a=a*b; a=a/b; b=a/b; 同樣可以完成交換(僅提供思路,未考慮除0溢出等問題)。舉一反三,可以有無窮種方法,但原理都是一樣的。
總結
以上是生活随笔為你收集整理的JAVA不借助第三个变量实现两个变量交换的思考的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Webstorm PhpStorm的序
- 下一篇: GridBagLayout布局管理器应用