Re: [問題] 針對一些考題的疑問。

看板C_and_CPP作者 (閉上眼的魚)時間12年前 (2012/01/08 18:58), 編輯推噓2(205)
留言7則, 6人參與, 最新討論串3/6 (看更多)
2012/01/10 修正範例錯誤,新增三份註解 ※ 引述《Arton0306 (Ar藤)》之銘言: 我只是想針對 Q2 做一點意見。 : : Q2.寫一個檢查輸入為3倍數的函數,但不能使用除法和餘數。 : : 除了使用 : : while(input>2){input-=3 check=input}if(check)... : : 這種算法外,還有更好的算法嗎? : 這方法不錯了 : 不然利用3倍數的特性 寫一個function 把原數字轉字串後取出每個位的數字 求和 : 看是否大於9 是的話 recursive 不是的話 若數字是0 3 6 9那就是3倍數 之前某論壇也是看到這題,目前大多都放在這解法上, 後來想到另一解法。 看一下這特性 - 97 mod 3 = (64+32 + 1) mod 3 = 1 mod 3 = 1 這特性是花五分鐘觀查出來的,我也不保證這是最快的方式, (面試的時候可能是很久的時候,所以第一次看到可能會想不到) 2^n + 2^(n+1) 必為 3 之倍數 所以用 shift right + and gate 可做一點加速,效率會不會比較快留著待分析 ( 和布斯乘法器一樣,有些情況會比較慢 ) 類似觀念可以變成用 3bits、4bits 方式分析,(3 bits 可能不好做或不能做) ( 就像是改善形的布斯乘法器 ) unsigned Mod3(unsigned x) { unsigned sum; do{ sum = 0; while(x) { sum+=x&0x3; // 取最後 2 bits x>>=2; } x = sum; }while(sum>3); return sum==3 ? 0 : sum; // 最後等於 3 額外判斷 } 這應也不是最快的方式,在猜想最快的方式應該是用 floating multi. 去做, 可能一、二行就出來了,只是那個 magic number 可能面試的時候時間有限, 找不出來吧。 ----- 這兩天網路掛掉,想加註解都沒辦法,下面提供一點其他想法。 [註1] sum+=x&0x3 ,其實可直接寫類似 sum+= ( (x&0x3==0x3) ? 0 : x&0x3 ); 直接將 3 跳過,傳回值也比較直覺 return sum; [註2] 如 bleed1979 大所云 (#1F2Pr4Of),後來也覺得 shift right 是否不合題意, 此處若不用 shift right, div, mod ,想到的方式是改用 shift left (變乘法了) + 0x03 mask (也是配合 shift left) 完成, 枝節不多細磨, 有興趣亦可實作。 [註3] 其實觀查出來是很單純的列出數列 1 2 4 8 16 32 64 ... 後來也觀查出任意數 n 之解法,chubiei 大推導漂亮 (#1F2Q6CBz), 有興趣之網友可繼續詳參該文之討論。 -- If there is no tomorrow, I want to see u last time. -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 180.177.76.201

01/08 20:07, , 1F
推!數學的方法很帥!
01/08 20:07, 1F

01/08 20:11, , 2F
謝謝 A 大稱讚,這份code還有改善空間便是 ^^
01/08 20:11, 2F

01/08 21:29, , 3F
讚,小弟我這邊看了覺得受益良多。
01/08 21:29, 3F

01/08 21:43, , 4F
mod 的地方好像有寫錯...32+64+1 是97呀...
01/08 21:43, 4F
這裡確實寫錯,不過答案相符無誤。97 mod 3 = 1

01/08 21:54, , 5F
樓上(Y)
01/08 21:54, 5F

01/08 21:54, , 6F
而且1 mod 3 應該是1
01/08 21:54, 6F

01/08 21:59, , 7F
推數學解!
01/08 21:59, 7F
※ 編輯: EdisonX 來自: 180.177.69.239 (01/10 11:07) ※ 編輯: EdisonX 來自: 180.177.69.239 (01/10 11:14)
文章代碼(AID): #1F2NQvJn (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1F2NQvJn (C_and_CPP)