Skip to content

Instantly share code, notes, and snippets.

@foobra
Last active May 22, 2017 01:46
Show Gist options
  • Save foobra/f1caf875d05fe27a848a061dc8095a6d to your computer and use it in GitHub Desktop.
Save foobra/f1caf875d05fe27a848a061dc8095a6d to your computer and use it in GitHub Desktop.
word-count FSM OOP Implement
#include <stdio.h>
#include <map>
#include <utility>
#include <functional>
enum STATE {
IN,
OUT,
COUNT,
};
class Fsm2State {
public:
using JudgeLambda = std::function<std::pair<STATE,STATE>(char)>;
using EnterLambda = std::function<void(void)>;
using ExitLambda = std::function<void(void)>;
Fsm2State() = delete;
explicit Fsm2State(STATE state, JudgeLambda judge, EnterLambda enter = [](){}, ExitLambda exit = [](){})
{
state_ = state;
judge_ = judge;
enter_ = enter;
exit_ = exit;
}
STATE state_;
JudgeLambda judge_;
EnterLambda enter_;
ExitLambda exit_;
};
static std::map<STATE, Fsm2State> AllFsm2States = {
{OUT, Fsm2State(OUT, [](char c){
return (c == ' ' || c == '\t') ? std::make_pair(OUT, OUT) : std::make_pair(OUT, IN);
}, [](){
printf("OUT Enter\n");
}, [](){
printf("OUT Exit\n");
})},
{IN, Fsm2State(IN, [](char c){
return (c != ' ' && c != '\t') ? std::make_pair(IN, IN) : std::make_pair(IN, OUT);
}, [](){
printf("IN Enter\n");
}, [](){
printf("IN Exit\n");
})},
};
// can't compile
// static_assert(AllFsm2States.size() == int(COUNT), "All States should define");
class Fsm2Transform {
public:
using TransformLambda = std::function<void(int *)>;
using StatePair = std::pair<STATE, STATE>;
Fsm2Transform() = delete;
explicit Fsm2Transform(StatePair state, TransformLambda transform = [](int *_){})
{
state_ = state;
transform_ = transform;
}
STATE executeTransform(StatePair pair, int *count)
{
AllFsm2States.at(pair.first).exit_();
transform_(count);
AllFsm2States.at(pair.second).enter_();
return pair.second;
}
private:
StatePair state_;
TransformLambda transform_;
};
static std::map<Fsm2Transform::StatePair, Fsm2Transform> AllFsm2Transform = {
{
{OUT, OUT}, Fsm2Transform({OUT, OUT}),
},
{
{OUT, IN}, Fsm2Transform({OUT, IN}, [](int *count){
*count = *count + 1;
})
},
{
{IN, IN}, Fsm2Transform({IN, IN}),
},
{
{IN, OUT}, Fsm2Transform({IN, OUT}),
},
};
int main()
{
char c;
int count = 0; // word count
STATE state = OUT;
while ( scanf("%c", &c) != EOF && c != '\n' ) {
auto pair = AllFsm2States.at(state).judge_(c);
state = AllFsm2Transform.at(pair).executeTransform(pair, &count);
}
printf("word count: %d\n",count);
return 0;
}
@foobra
Copy link
Author

foobra commented May 22, 2017

image5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment