從「交換兩個變數而不用臨時變數」談起

2021-05-25 19:52:15 字數 2124 閱讀 1605

問題:寫乙個函式,實現交換兩個變數,但不能用臨時變數?

分析:交換兩個變數的這一功能,我們用的比較多,也可以很容易的寫出乙個出來,但是題目要求的是不能用臨時變數。並且題目也沒有說明變數是什麼型別,它是int,char,double,還是自定義的結構體,或者是類型別,雖然可以用模板從某種程度上解決這一些問題,但對於自定義的型別,還是不是很好處理。在這裡先從最簡單的說起,假設這裡的變數是int型的。

一般如果我們要寫乙個交換整形變數的**是

code:

1:  inline

void swap(int *a,int *b)   

2:     

我們用到了臨時變數temp。

思考乙個問題我們為什麼要用到臨時變數呢?我們平常交換東西時,是否用到了臨時的媒介呢?

比方說我手上有乙個蘋果,你手上有乙個桔子,我想和你交換,是如何進行的,用到媒介沒有呢?我們好像是直接交換的,這其中似乎沒有用到什麼媒介,但是仔細想想過程是用到了媒介的。交換可以歸納為兩種方法,1:將物品直接從乙個人的左手放到乙個人的右手2:借助其它的容器,如果盤,先將物品放在果盤中,再去拿自己要的。其實這兩個也只是乙個方法而已,第乙個借助的「容器」是我們的身上的另乙隻空閒的手,很容易忽略掉這個問題,以為我們沒有用到其它媒介,要是想想我們只有乙隻手如何交換呢。

結論1:物質是有載體的,不管這物質是實體的,還是虛體。乙個載體在同一時間上只能承載一種物質,於是在交換兩個載體承載的物質時,是不可能同時進行的,估都要用到其它的媒介載體。回到計算機的問題上,存放變數也有載體的,它是記憶體,而變數可以說是一種虛體物質。這從直觀上解釋一般為什麼我們寫交換變數函式時要用到臨時變數,也直接反映了程式設計不是離生活很遠的,它不是另乙個世界的思維。

即然如此,是不是沒有辦法了?方法只給那些勤於思考的人的。是一定要用到載體媒介嗎?不用到就不行嗎?

結合程式設計特點,可以有如下的**

code:

1:  inline

void swap(int *a, int *b)   

2:    

是不是很有意思,真的沒有用到其它的臨時變數啊!那我們上面的結論1是不是錯了呢?當然不是,為什麼可以直接就可以交換了呢?還是用上面的例子來說,兩個人交換蘋果和桔子但是每人只有乙個手,也不借助其它的容器,那如何進行喲?有辦法,就只是用乙個手拿兩樣東西,也就是說先將蘋果(桔子)給另乙個人用乙隻手拿著,再從他手上拿桔子(蘋果)。基本也就是**的意思了。

結論2:看似不可能,但卻可以的,要做的是仔細的去挖掘,多思考。

那上面的**是不是就沒有問題了?有。要考慮溢位的問題,程式中有乙個加法,很可能使結果超出範圍,也就是說乙隻手要是拿不了乙個蘋果和桔子怎樣辦?

要相信有問題是可以解決的,可以用assert等等方面處理一下,但不是最好,繼續有如下的**

1: inline void swap(int *a, int *b) 2: 這是什麼?一眼看不出是什麼是嗎?不慌,我們可以慢慢的一步步的分析。 對於位運算與、或、非,我們在處理資料的時候是經常要用到的。我們經常要用到的東西也是在基礎的。 設ubittest為測試數,值為2^n,也就是第n位為1。udate為需要處理的資料。

code:

1.將udate的第n位置1   

udate = udate|ubittest   

2.將udate的第n位置0   

udate = udate&~ubittest   

3.將udate的第n位取反   

udate = udate ^ubittest  

掌握熟悉了這些在看上面的**是不是要輕鬆多了,不是要溢位嗎?不是乙隻手拿不下蘋果和桔子嗎?不要緊,我們可以一部分的交換啊,把蘋果切開,桔子剝開來去交換,這樣總可以拿下來吧。

結論3:載體承載物質是必需的,我們不能以改變,卻可以改變載體承載的性質。載體的容量大小不能改變,但可以去改變承載物體的大小,照樣可以達到想要的目的。真的是山窮水復疑無路,柳暗花明又一村。

到這裡為止,對於簡單的整形變數的交換的情況,已經基本上說清楚了,但並不是說可以去支援任何型別,在這裡只是從最簡單的例子開始,只是起個引子的作用,是給一些思路的問題。對於這個問題,還可以從內聯彙編的方面去處理,可以看看彙編的**是如何,從中得到一些啟發;對於各種不同型別處理也有其各自的問題需要去處理,如對於類物件怎樣去處理拷貝。對於好的庫也可以去看看他們是怎樣去寫swap這個函式的。如stl,boost等,從中應該可以學到不少的。

從「交換兩個變數而不用臨時變數」談起

問題 寫乙個函式,實現交換兩個變數,但不能用臨時變數?分析 交換兩個變數的這一功能,我們用的比較多,也可以很容易的寫出乙個出來,但是題目要求的是不能用臨時變數。並且題目也沒有說明變數是什麼型別,它是int,char,double,還是自定義的結構體,或者是類型別,雖然可以用模板從某種程度上解決這一些...

不用臨時變數,交換兩個變數的值

在學習c語言的時候,涉及到兩個變數值的交換,其中用到臨時變數。類似於 temp a a b b temp 這樣的語句,如果在沒有臨時變數的情況下,該如何做呢?網路上的人們給出了兩種方法 一 異或法 a a b b b a a a b 二 加減法 a a b b a b a a b 其實我們看加減法更...

不用臨時變數交換兩個數的值

就地交換兩個數是比較經典而且基礎的演算法之一。我們要交換兩個數字,通常的做法就建立乙個中間變數,然後進行迴圈賦值,比如說下面的 void switch int p1,int p2 這種做法是最常見的一種交換兩個數字的方法,但研究演算法的人總是會提出比較詭異的問題,比如說在手持裝置中,記憶體資源很寶貴...