[問題] if 判斷大量狀態

看板C_and_CPP (C/C++)作者 (Midnight Sun)時間14年前 (2012/03/11 20:09), 編輯推噓3(3010)
留言13則, 8人參與, 最新討論串1/3 (看更多)
語言:C或C++ 問題(Question): 各位好,想請教關於在需要判斷狀態做不同動作 而狀態規模很大的情況下,是否有更好的寫法 比如說寫一個簡單的 GUI(Windows Form) 上面有很多選項,根據使用者選取不同的選項,程式需要做相對應的動作 if (useOption1 && useOption3) { //cube 1-3- functionA(); functionB(); } else if (useOption1 && useOption2 && useOption4) { //cube 12-4 functionA(); } else if (useOption3) { //cube --3- functionC(); } ... else { functionB(); } 問題的假設:這些選項無法獨立出來,所以變成有 2^選項 種狀態 每個狀態要做的事情可能有些相關有些非相關 需要判斷的狀態還是佔整體空間的少數,而剩下的都做預設的動作 搜尋了一下,感覺跟FSM還有function pointer有關,但還是不太清楚怎麼改善 關於問題的規模 選項: 20種 狀態: 2^20 需要判斷的cube:10000 想問像這類判斷的問題,在大規模時有沒有兼具效率與可維護度的通解? 還是有書籍講到關於這方面的軟體工程知識呢? -- 如何寫出無法維護的程式碼 How To Write Unmaintainable Code http://thc.org/root/phun/unmaintain.html -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.32.216.207

03/11 20:32, , 1F
#1FMBb9lE (Programming) 這一串對你這問題也許有用
03/11 20:32, 1F

03/11 20:32, , 2F
programming版 [問題] 新手發問 "!!"的意思
03/11 20:32, 2F

03/11 20:33, , 3F
被樓上搶先了....Orz
03/11 20:33, 3F
感謝,我去看了一下,但感覺還是沒有解決問題 事實上我可以把每個判斷用一個 class State 包起來(=編碼) 用 switch 還是沒有改善重點 重點是我怎麼減低 evaluate 的次數? @@ switch (encode) { //cube 100100011-- 10010001100: 10010001101: 10010001110: 10010001111: doSomething1(); break; //cube 00-00101110 00000101110: 00100101110: doSomething2(); break; ... default: doSomething10001(); } 問題的重點 1. 要檢查的部分條件(cube)必須擴展成特定state(minterm) 2. 沒有保證state會不會不小心重複 3. 10000多種檢查很難維護,每一次做動作都要檢查10000多次

03/11 21:03, , 4F
把要狀態轉成一個數字, 呼叫 function array 中相對應項
03/11 21:03, 4F

03/11 21:03, , 5F
的函式? 比如每個函式給個數字代表對應到的狀態?
03/11 21:03, 5F

03/11 21:59, , 6F
useOption能否建成array?
03/11 21:59, 6F

03/11 22:00, , 7F
我覺得只有程式好維護,判斷不會少。
03/11 22:00, 7F

03/11 22:01, , 8F
03/11 22:01, 8F

03/11 22:31, , 9F
純粹好奇,原PO的程式是在處理蛋白質的問題嗎?
03/11 22:31, 9F

03/11 22:32, , 10F
有沒有辦法把所有狀態mapping成一個整數再用switch?
03/11 22:32, 10F

03/12 17:20, , 11F
都用成map了,怎麼不用map+func pointer?
03/12 17:20, 11F
想到比較具體的例子如下 void MonsterDecideStrategy(State s) { if (s.isHpLow && s.hasExit) { Run(); } else if (s.isHpLow && s.hasTank) { HideBehindTank(); } else if (s.isHpLow && s.hasHealer) { CallForHeal(); } else if (s.isHpLow && !s.hasExit) { Hide(); } else if (!s.isHpLow && s.hasParty) { Assist(); } else if (!s.isHpLow && s.isEnemyAway) { CastSpell(); } ... else if (!s.hasReligion && s.isGodNear) { Pray(); } else { Idle(); } } 遇到這種 code 是否是設計上可以改進? 感覺還是要有 tropical72 說的使用 FSM 來維持狀態檢查(避免重複) ※ 編輯: BlazarArc 來自: 114.32.216.207 (03/12 19:30)

03/12 19:49, , 12F
我的建議是,簡化一點你的問題,直接實際function ptr 和
03/12 19:49, 12F

03/12 19:49, , 13F
FSM, 其中的優裂在coding過程中自己最能體會。
03/12 19:49, 13F
文章代碼(AID): #1FN9No7e (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1FN9No7e (C_and_CPP)