FSM c++多种实现方法
bcode parser不使用switch实现
B编码中有四种类型:string,integer,dictionary,list。示例分别如下:
integer: i43e 表示数字32。
string: 5:world 前面数字表示字符长度为5,字符串为world。
dictionary: d9:publisher3:bobe表示key:publisher,value:bob。
list:l4:worlde 表示列表成员world。
实现1:
这种主要也是利用函数指针来保存一个processor,每个processor对应一个状态。处理完对应的区块信息就返回下一种处理方法。对于嵌套类型,可以使用递归来做。
class BecodeParser{
public:
void start(const std::string& str)
{
std::string::const_iterator itr = str.cbegin();
shiftState(itr);
while( itr != str.cend() ) {
processor(itr);
}
}
void processDictionary(std::string::const_iterator& itr) {
// process
shiftState(++itr);
}
void processList(std::string::const_iterator& itr) {
// process
shiftState(++itr);
}
void processInterger(std::string::const_iterator& itr) {
// process
shiftState(++itr);
}
void processString(std::string::const_iterator& itr) {
// process
shiftState(++itr);
}
void shiftState(std::string::const_iterator& itr){
if( *itr == 'l') processor = processList;
if( *itr == 'i') processor = processInterger;
if( isNumber(itr) ) processor = processString;
}
void(*processor)(std::string::const_iterator& itr); // 这儿可以使用boost::function来保存函数对象。
boost::function<void(std::string::const_iterator& )> processsor_;
//这样就可以搭配bind,lambda使用,发挥函数编程优势
};
实现2:
利用和类型来实现,在TypeScript中有和类型,但是c++中则没有。但是cpp可以用基类指针来模拟和类型。具体实现见代码。
class AbsBecodeType{
public:
virtual AbsBecodeType* Parser(std::string::const_iterator& itr);
};
class ListParser: public AbsBecodeType{
public:
virtual AbsBecodeType* Parser(std::string::const_iterator& itr);
};
class DictionaryParser: public AbsBecodeType{
public:
virtual AbsBecodeType* Parser(std::string::const_iterator& itr);
};
class IntergerParser: public AbsBecodeType{
public:
virtual AbsBecodeType* Parser(std::string::const_iterator& itr) {
// processe
if( *itr == l) return std::make_shared<ListParser>();
}
};
void processBcodeStr(const std::string& str) {
std::shared_ptr<AbsBecodeType> processor = std::make_shared<IntergerParser>();
std::string::const_iterator itr = str.cbegin();
while( itr != str.cend() ) {
processor.reset(processor->Parser(itr));
}
}
实现3:
这一种实现是常见的一种方式。定义一个state,然后在这个state里面周转。今天刷题(leetcode No.8) 又收货了一种状态定义的方式。
int get_col(char c) {
if (isspace(c)) return 0;
if (c == '+' or c == '-') return 1;
if (isdigit(c)) return 2;
return 3;
}
unordered_map<string, vector<string>> table = {
{"start", {"start", "signed", "in_number", "end"}},
{"signed", {"end", "end", "in_number", "end"}},
{"in_number", {"end", "end", "in_number", "end"}},
{"end", {"end", "end", "end", "end"}}
};
state = table[state][get_col(c)];

浙公网安备 33010602011771号