不借助第三個變數實現兩個變數交換的思考

2021-07-04 01:47:52 字數 1778 閱讀 3915

網上存在三種方法:

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溢位等問題)。舉一反三,可以有無窮種方法,但原理都是一樣的。

JAVA不借助第三個變數實現兩個變數交換的思考

package mypackage public class demo 方法1 public void xchan01 int a,int b 方法2 public void xchan02 int a,int b 方法3 兩數交換不一定需要第三個元素 演算法問題 巧妙交換,提出的缺點會溢位經測驗是...

不借助第三個變數交換兩個變數的值

通常我們的做法是 尤其是在學習階段 定義乙個新的變數,借助它完成交換。如下 int a,b a 10 b 15 int t t a a b b t 這種演算法易於理解,特別適合幫助初學者了解電腦程式的特點,是賦值語句的經典應用。在實際軟體開發當中,此演算法簡單明瞭,不會產生歧義,便於程式設計師之間的...

實現兩個值的交換(不借助第三個變數)

今天總結兩個不借助第三個變數實現兩個值的交換的方法 int main int main 今天主要聊聊第乙個方法,因為可讀性較強,並且聽一些老師說,這個方法也被很多網際網路公司作為面試題,但其實這個方法是有bug的,隱藏的很深,我們來分析分析。include void swap 1 int a,int...