有 1 到 10000 共 10000 個數,如果我從中隨機拿走乙個數,你如何知道我拿走了哪個?
先把 10000 個數相乘,然後再將拿走乙個數之後的 9999 個數相乘,兩者相除即可。
這個演算法是正確的,但是會有兩個潛在的問題:
針對前面提出的問題,同事想到了使用加法,先求出 10000 個數的和,再減去 9999 個數的和。
這樣資料不會溢位,而且加法的效率比乘法也要高很多,即使資料中包含 0,也沒有任何問題。
然後就過關了,自己回去之後思考了一下,覺得還可以擴充套件,假設所有的數加起來之後仍然會溢位,那該如何處理,比如從 1 到 (264-1),於是想到了位操作,與、或,異或中,要數異或最為神奇,代入一看,果然合適: 先將所有的數異或起來,然後將拿走乙個數之後的數異或起來,兩者結果再異或,便是拿走的那個數。
我用 a,b,c,d 4 個數來做演示,因為異或符合結合律和交換律(你可以用 0,1 試一下),於是:
a^b^c^d = (a^b^c)^d
d = (a^b^c^d)^(a^b^c)
此處用異或的好處在於
不會溢位
異或的速度要快於加法
擴充套件一下題目,如果提供的不是整數,而是浮點數,會有問題嗎? 當然沒有,因為是在位級別上操作,無論是整數還是浮點數,在這個演算法看來,都是一堆位,處理起來沒有什麼差別。
再擴充套件一下題目,如果提供的數本身就超出了內建型別的表示範圍,如在 1 到 2128,該如何處理? 這個問題是在寫這篇文章的過程中想到的,暫時沒有好的辦法。
一道邏輯題
前幾天在網上看到一道題目 將54張撲克牌按照某種次序進行排列,然後取出第一張放至底部,然後將現在的第一張翻開拿出來,不斷迴圈,直至手中沒有撲克牌,而且拿出撲克牌的順序依次是紅心a k 方片a k 黑桃a k 梅花a k 大王 小王。這道題目讓我想起了小時候老爸給我出的題目,取一幅撲克牌同花色的a k...
一道邏輯思維題
新聞上新加坡一道為十五六歲學生設計的奧數題被人放上網,不料惹得西方國家網民絞盡腦汁爭相答題。許多人驚呼,新加坡孩子竟然要做這麼難的數學題啊!值得注意的是,英國 美國等西方國家網民普遍震驚,而一些亞洲國家網民則相對淡定。對這一現象,不少人表示 只能呵呵!對於多年不動腦筋的學渣試著理解一下先 alber...
筆試裡的一道邏輯題
火車上,來自美 法 韓 俄四國的甲 乙 丙 丁四位旅客恰好相聚在某個車廂中。他們每個人除了會說本國語言外,還會說其他三國語言中的一種,有一種語言三個人都會說。這四位旅客交談的有關情況如下 乙不會說英語,當甲與丙交談時,他卻能替他們作翻譯 甲是南韓人,丁不會說韓語,但他倆卻能毫無困難地交談 乙 丙 丁...