Re: [問題] swith_case 用法

看板C_and_CPP作者 (totem)時間9年前 (2015/06/15 16:13), 9年前編輯推噓1(1010)
留言11則, 3人參與, 最新討論串4/4 (看更多)
※ 引述《tropical72 (藍影)》之銘言: : ※ 引述《totemist (totem)》之銘言: : <恕刪> : : input是相同的512筆data : : 經由case去選擇不同的處理方式 : <恕刪> : : 補充說明(Supplement): : : 因為我是要做濾波器(fir filter - bandpass) : : 我希望能給使用者自己選擇頻率(0~540hz,每60hz為一單位) : : 所以我總共要做C10取2 有 45個case要做 : <恕刪> : : ex: : : printf("enter A=100_500 or D=200_600 = "); : : 就是直接給使用者看著指令選擇 : : 但是我想做到的是給使用者自動輸入想要的頻寬 : : 只是覺得這樣對使用者比較方便,不用把我45個代號看完就可以自動輸入這樣 : 對於敘述其實有點看不懂,因裡面算出來的數字我真沒辦法對上 Orz : 0~540 , 每 60 hz 為一個單位 , 這樣只會切成 10 分, : 為什麼後面多出了 C(10,2) = 45 個 conditions ? : A=100_500 代表若輸入的是 'A', filter 範圍是 (100,500) : D=200_600 代表若輸入的是 'D', filter 範圍是 (200,600) : 以下的敘述猜測就是 Feis 所提的方法。 : 根據最後一段敘述,我假設你需要的是 要做45次判斷,依序執行相對應之函式, : 那你倒是可以這麼做 : const int iBoundCount = 45; : const int iLowerBand[iBoundCount] = { 100,200,150,180,200, .... } ; : const int iUpperBand[iBoundCount] = { 500.700.600.400.600. .... } ; : iLowerBand 和 iUpperBand 可以用 struct stBand { int m_iLower , m_iUpper}; : 這裡不贅述。另上面這些常數可以寫到檔案裡面去,程式初始化時從檔案讀出, : 這裡也不贅述。值得注意的是,如果你的 Bound 範圍是有規律的,事實上,上面的表 : 可以不用建立,只是為了說明方便,我還是以建表方式說明。 : 再來是使用者輸入的時候,你可以讓使用者自己去輸入 : lower bound 及 upper bound ,再去搜尋對應到的是哪一個 index : int iUserLower , iUserUpper ; // 假設已拿到數值 : int iSelIndex ; // 判斷輸入數值落在陣列裡的哪個區間。 : for(iSelIndex = 0 ; iSelIndex < iBoundCount ; ++iSelIndex) : if( iLowerBound[iSelIndex] == iUserLower && : iUpperBound[iSelIndex] == iUserUpper ) : break; : if(iSelIndex == iBoundCount) { // 這裡是使用者輸入的值沒在兩個 array 找到 } : else { // 這裡是使用者輸入的值剛好在 Lower[iSelIndex]/Upper[iSelIndex] } : 換句話說,到這裡得到的 iSelIndex 會是 [ 0, iBoundCount ] 之連續整數。 : 如果硬要用 switch 寫的話還是可以,就變成了 : switch(iSelIndex) : { : case 0 : func0() ; break; : case 1 : func1() ; break; : case 2 : func2() ; break; : ... : case 44 : func44() ; break; : default : InputError(); break; // 這裡是 iSelIndex == 45 : } : 這樣看起來好像沒什麼改變對不對? 不對唷!關鍵是 iSelIndex 已經調整成 0~45, : 它又可以拿來當陣列的索引值了,這時候就需要 函式指標陣列 了。 : 假設你的 function 每個都長得一樣,都是長成 void func(void) ; (長其他樣子也行, : 重點是要長得一樣),上面的 switch 可被拿掉變成 : typedef void (*pFilterFunc)(void) ; : pFilterFunc pFuncAry[iBoundCount] = { : func1 , func2 , func3 , func4 , func5 , ... , func45 : }; : if(iSelIndex != iBoundCount) // 別忘了剛剛的 iSelIndex 怎來的 : { : // User Input Error Process : } : else : { : pFuncAry[iSelIndex] () ; // 使用函式指標陣列進行呼叫函式 : } : 好了,你要的東西上面應該已經提供一套 solution 給你了,但其他更好的架構 : 方式,像是 : struct { : int iLowerBound ; : int iUpperBound ; : void (*pFilter)() ; : }FilterInfo[] = { : {100,200, func1}, : {200,500, func2}, : ... : {150,700, func45} : }; : 資料結構和詳細作法我也不再贅述了,也只是上述的東西再包過而已。然後這是用 : 純 C 的刻法,另一種解法是 C++ template ,這個我也不贅述。 : 重點是…嗯…你可以先確認一下,知不知道什麼是函式指標,什麼是函式指標陣列。 : 不知道的話必須先補起來,才能討論比較簡潔、"好一點點" 的架構。 : 但.是 (如果沒有但是的話下面可以不用看了...) : 但.是. 如果好死不死,那些 func1 , func2 的 prototype 長得不一樣的話呢? : 像是 void func1(int, int) , double func2(double, int) , ... etc , : 這裡其實我覺得還是直接用 45 個 switch-case 下去硬幹會比較方便, : 走 C 風格的話還是可以用 函式指標陣列,只是所有函式必須改寫成 : void func(void *) 或是 int func( void *) ,至於 C++ 有沒有比較好的解法? : 嗯,我想是有的,只是我也沒用過,也想知道。 這幾天又重回這個問題啦!!!! 經過學長的提點,這次的想法跟Tropical大有點像 首先我先把我原本45個1維array,變成一個2維的array: myfilter[45][406] 然後我目前想法是 設一個 int filter_id 然後利用Fpass和Fstop 找對應filter_id 一對一 函數的關係 Fpass Fstop filter_id 0 60 0 0 120 1 . . . . 0 540 8 60 120 9 60 180 10 . . . 60 540 16 120 180 17 120 240 18 . . . 120 540 23 . . . . 一直到最後 480 540 44 共有45個filter_id (0~44) 這樣的好處是 只要能找到filter_id,就能簡化把filer變成 myfilter[filter_id][406]; 在function就不用像我之前那樣硬是要用45個case 一個就可以搞定了 只是我目前找的規律性還沒有很好,有點硬湊OAQ 也是分了很多if else來找filter_id if (Fpass == 0) filter_id = (Fstop/60)-1; else if (Fpass == 60) filter_id = (Fpass/10)+(Fstop/60)+(Fstop/60)-1; else if (Fpass == 120) filter_id = (Fpass/10)+(Fstop/60)+(Fstop/60)-1; else if (Fpass ==180) filter_id = (Fpass/10)+(Fstop/60)+2; . . 方法不同 . . else (Fpass == 480) filter_id = 44; 有沒有人能有更簡潔的關係式來找filter_id呢? 謝謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 140.114.28.223 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1434356020.A.ADF.html ※ 編輯: totemist (140.114.28.223), 06/15/2015 16:14:21
WOW 太猛啦!!!!! 請問這樣的公式是怎麼想出來的呢? 是經過Try-&-error 還是真的有甚麼規律性可以看的出來~~ 謝謝F大!!! ORZ ※ 編輯: totemist (140.114.28.223), 06/15/2015 16:41:26

06/15 16:50, , 2F
應該只是基礎的離散數學
06/15 16:50, 2F

06/15 16:53, , 3F
9+8+7+6+5+4+3+2+1
06/15 16:53, 3F

06/15 17:05, , 4F
這是等差級數和n[(2*a1+(n-1)*d)]/2
06/15 17:05, 4F

06/15 17:30, , 5F
F大借抄一部分,感恩! https://ideone.com/Mzs6f3
06/15 17:30, 5F

06/15 17:32, , 6F
這不是程式這是數學來著...XD
06/15 17:32, 6F

06/15 17:45, , 7F
a1=9帶入就會發現是F大的答案了
06/15 17:45, 7F
原來如此,又增廣見聞了OAQ 謝謝各位大大這樣不願其煩的給予指教Orz ※ 編輯: totemist (140.114.28.223), 06/15/2015 18:49:43

06/15 20:20, , 8F
所以我之前發的不算是廢文了嗎…滿滿的感動
06/15 20:20, 8F
Tropical大大,當然不是廢文阿OAQ 我還是一直有再思考的 只是我的目前程式能力還不足以應付你們建議的方法 我會努力繼續學習的!!! ※ 編輯: totemist (36.226.229.199), 06/16/2015 00:04:52

06/16 14:34, , 9F
加油吧! 問題 => 找規律 => 思考 => Divide & Conquer
06/16 14:34, 9F

06/16 14:36, , 10F
你的方向是對的,想出自己解法,再看看人家解法,就會進
06/16 14:36, 10F

06/16 14:36, , 11F
步!
06/16 14:36, 11F
文章代碼(AID): #1LVeaqhV (C_and_CPP)
文章代碼(AID): #1LVeaqhV (C_and_CPP)