Last active
May 22, 2017 01:46
-
-
Save foobra/f1caf875d05fe27a848a061dc8095a6d to your computer and use it in GitHub Desktop.
word-count FSM OOP Implement
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
Author
foobra
commented
May 22, 2017
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment