求交換兩個整數最簡單的寫法?
網上有很多極客的寫法,自己寫了一種比較簡單的,請問還有更高效簡潔的嗎?!
int a = 119, b = 256;a ^= b ^ (b = a)-----------------------補充------------------提出這個問題之前,確實經過實測,「a ^= b ^ (b = a)」在js、java、c#下確實得到正確的結果,但是在c++下,出現問題。我不太懂彙編。
個人覺得上面的表達式在編譯器編譯的時候,首先應該轉化成後綴表達式的,然後進入寄存器的。c++出問題,估計是編譯時有優化吧!求懂c++、java、c#、js具體編譯過程的大神講解!
a,b = b,a(Python)
這樣用XOR做,其實未必更快。因為它需要兩次真實的運算操作。用一個額外的臨時變數做交換,實際編譯的時候八成會被優化掉,因為CPU有寄存器。
你這段代碼寫得不對啊,反正貼著聲明,你應該寫成這樣:
int a = 256;
int b = 119;
人家說簡潔沒說少用變數啊c:
int temp=b;
b=a;a=temp;go:a,b=b,a;其他寫法都是耍流氓…悲報經實測,題主的代碼用gcc開-O3編譯之後,被優化成了彙編寫的臨時變數法,三條mov,木有xor……恭喜做無用功……然後我覺得用彙編寫的臨時變數法已經是最快的了,一共只有三行
不是很懂彙編,求彙編高手打臉……
之前面試一家公司的C#,筆試里有道題就是交換兩個變數,但不許引入第三個變數。已經習慣了
temp=b;
b=a;
a=temp;
b=a+b;
a=b-a;
b=b-a;
std::swap
其實啊,騷年你這麼寫有點問題當a==b時 你這代碼會得出不正確的結果所以還是用臨時變數來交換,或者用Python吧
要相信編譯器
臨時變數法最保險
與其糾結在這種地方優化速度不如優化你的演算法
如果你要交換a[i]和a[j]的值的話如果i==j,那麼不用臨時變數有可能出現很大問題腦內交換最簡單,都不用重寫代碼:反正名字已經是a、b這類臨時無意義的了,交換一下又何妨?
inline void swapInt(int a, int b)
{
// 聲明在別的地方
int tmp = a;
a = b;
b = tmp;
}
int a = 119, b = 256;
swapInt(a, b);
list($a, $b) = [$b, $a](PHP)
a=a^b;b=a^b;a=a^b;
利用位運算進行換值操作。
int b = 119, a = 256;
題主的解決思路是能過運算符的優先順序來解決的。
a ^= b ^ (b = a) 等價於 a=a^b^(b=a);等於右邊是:a^b^(b=a)執行順序是:a異或b,再異或(b=a)括弧優先等高於異或,先把a賦值b,相當於直接與a進行異或,這時的值就變成了b.如果知道這個道理了,就可以展開很多種做法了。
再來兩個例子是通過運算符優先順序來解決兩個數交換。先在Java上面親測!其他語言估計一樣!// =====================代碼開始分隔線===========================
public class TestChange {/**
* @param args */ public static void main(String[] args) {int a = 119;
int b = 256;if (a != b) {
// 1.主要根據運算符的優先順序來做的.change001(a, b);
// 2.主要根據運算符的優先順序來做的. change002(a, b); // 3.運用異或 change003(a, b); // 4.運用異或 change004(a, b); } }/**
* 1.主要根據運算符的優先順序來做的.
*/ public static void change001(int a, int b) {a = a + b - (b = a);
print(a, b); }/**
* 2.主要根據運算符的優先順序來做的. */ public static void change002(int a, int b) {b = a + (a = b) * 0;
print(a, b); }/**
* 3.運用異或 */ public static void change003(int a, int b) {a ^= b;
b ^= a; a ^= b; print(a, b); }/**
* 4.運用異或 */ public static void change004(int a, int b) {// a ^= b ^ (b = a)
a = a ^ b ^ (b = a); print(a, b); }/**
* 列印 */ public static void print(int a, int b) { System.out.println(a); System.out.println(b); }}// =====================代碼結束分隔線===========================
其實,兩個數交換也能考出很多點,比如:1.內存溢出 a=a+b;可能會內存溢出? (C,int的最大值是2147483647,加b的話,就會變成負值了)2. 變數釋放 如果採用中間變數,是不是把中間變數釋放掉?C++ 接近 Python 的一種玩法:隨意交換(不限於兩個,不限於整數)tie(a, b, c) = make_tuple(b, c, a);
不算+-,*/的話:
1、幾次異或;2、臨時變數;3、asm的壓棧出棧。個人推薦用異或法或者臨時變數法。c=bb=aa=c
printf (「a=%d,b=%d",b,a)
推薦閱讀:
※高維空間點的旋轉問題?
※matlab中for循環為什麼會慢?
※奇數階幻方構造方法的原理是什麼?
※這是用什麼演算法實現的?
※遞歸有什麼意義?