2012-12-12 16 views
7

在我的採訪中,有人問我實現一個狀態機有100個國家,其中依次在每個州都有100個事件的系統,我回答以下3種途徑:專訪:函數指針VS開關的情況下

  • 如果-else
  • 的switch-case
  • 函數指針

的if-else顯然不適合於這樣的狀態機,因此,主比較是開關殼體之間VS​​函數指針,這裏是叔他根據我的理解比較:

  • 速度方面兩者幾乎相同。
  • 開關情況下比函數指針
  • 函數指針具有更多的存儲器開銷更少模塊化的。

有人能確認是否理解以上是正確的?

+4

函數指針在這種情況下似乎是唯一有效的方法。是的,它的訪問速度很快,但它是一個模塊化和靈活的解決方案。 –

+2

我無法想象硬編碼100個狀態,我寧願在初始化時將它們添加到某個狀態機。這樣可以避免10個屏幕長的if-else/switch-case梯子,使測試和修改變得更加容易 –

+1

不確定這是否能滿足面試官的要求,但是在我剛剛使用的[Ragel](http: //www.complang.org/ragel/)。你會獲得驚人的速度(例如'goto')*和*更容易調試(Ragel可以將狀態轉換圖轉儲爲點格式以供Graphviz使用)。 – unthought

回答

1

可能有函數指針的方法的變體:一個結構,它包括一個函數指針以及其他信息。所以你可以讓一個函數處理幾個案例。

除了這一點,我認爲你是對的。另外,我會考慮有關內存和速度的開銷值得考慮,但希望小到最後可以忽略不計。

+0

如果所有函數都在執行獨立功能,那麼沒有完全按照函數指針方法得到struct的含義,那麼如何才能讓一個函數爲多個案例服務? – user1897724

+0

@ user1897724如果兩種狀態幾乎相同,但一方面不同,則可能值得考慮。 – glglgl

+0

@glglgl你對這個問題有什麼好的看法嗎? – Blackninja543

0

我不知道你的面試官想聽到什麼,我希望這不是太偏離主題,但如果我正在採訪某人,我會給出點以瞭解現有框架的優點和缺點,特別是在這個範圍內。

C++的替代品(如果你可以使用他們,感謝glglgl的指出你似乎想C)將是:

Boost.MSM雖然極快超出該尺度的問題。原因是編譯時間,mpl :: vector/list約束和因爲你將有一個巨大的源文件。

Boost.Statecharts可與100個國家,但每個國家的100個事件會最大程度的發揮MPL ::矢量/列表約束工作。就個人而言,如果我在一個州有100個事件,我會嘗試將它們分組,並使用自定義反應,但顯然取決於應用程序。

我看不出有任何理由Qt的狀態機無法擴展那麼大(請糾正我,如果我錯了),但其數量級慢,所以我從來沒有使用它。

唯一好的C替代我所知道的是:

QP它可在C和C++,並可以擴展那麼大,具有良好的組織,是「超過一個國家機器」,它處理事件隊列,併發和內存管理等。滾動你自己可能會產生更好的性能(取決於你的技能和你投入多少時間),但應該指出的是,事件的內存管理可能最終需要更多的優化而不是狀態機實現它自己。 QP爲你做到了這一點,並且做得很好。

+0

Boost是C++和Qt,不是嗎? – glglgl

+0

正確,我忽略了OP的C標記,Qt也是C++,所以只剩下QP(它也可用於C和C++) – odinthenerd

0

您可以指定有關您的狀態和事件的更多詳細信息。 假設你的狀態是連續的整數。那麼你可以

  1. 寫一個表來包含所有狀態和每個狀態處理函數。 當收到一個事件時,引用這個表並調用相應的處理函數。

  2. 對於每個狀態,編寫一個包含所有事件及其事件處理函數的表。處理狀態事件時查找此表。

這兩個表中查找的時間複雜度爲O(1),和空間複雜度爲O(m * n個)

但是,你怎麼能有FSM與100個國家和事件100類型? 我建議你簡化你的FSM設計,1〜100的數字可能是一個特定事件的參數。