《剑指offer》-表示数值的字符串

请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示数值。 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。

题目是要判断一个表达式是否满足预设规则。其实就是正则匹配。正则匹配的原理,编译原理课上有讲过,用NFA/DFA来判定即可。


class Solution {
private:
	enum STATUS{ END = 0, START, SIGNED1, INTEGER, POINT, FLOAT, EXPONENT, SIGNED2, SCIENCE };
	STATUS dfa[256][9] = { END };
public:
	Solution(){
		for (int i = 0; i < 256; ++i){
			for (int j = 0; j < 9; ++j){
				dfa[i][j] = END;
			}
		}
		initDFA();
	}
	bool isNumeric(char* string){
		STATUS current = START;
		while (*string && current != END){
			current = DFA(current, *string);
			++string;
		}
		switch (current){
		case INTEGER:
		case FLOAT:
		case SCIENCE:
			return true;
		}
		return false;
	}
private:
	void initDFA(){
		char d = '0';
		// 1. START 变迁
		dfa['+'][START] = SIGNED1;
		dfa['-'][START] = SIGNED1;
		dfa['.'][START] = POINT;
		for (d = '0'; d <= '9'; ++d){
			dfa[d][START] = INTEGER;
		}

		// 2. SIGNED1 变迁
		for (d = '0'; d <= '9'; ++d){
			dfa[d][SIGNED1] = INTEGER;
		}
		dfa['.'][SIGNED1] = POINT;

		// 3. INTEGER 变迁
		for (d = '0'; d <= '9'; ++d){
			dfa[d][INTEGER] = INTEGER;
		}
		dfa['.'][INTEGER] = FLOAT;
		dfa['E'][INTEGER] = EXPONENT;
		dfa['e'][INTEGER] = EXPONENT;

		// 4. POINT 变迁
		for (d = '0'; d <= '9'; ++d){
			dfa[d][POINT] = FLOAT;
		}

		// 5. FLOAT 变迁
		for (d = '0'; d <= '9'; ++d){
			dfa[d][FLOAT] = FLOAT;
		}
		dfa['E'][FLOAT] = EXPONENT;
		dfa['e'][FLOAT] = EXPONENT;

		// 6. EXPONENT 变迁
		for (d = '0'; d <= '9'; ++d){
			dfa[d][EXPONENT] = SCIENCE;
		}
		dfa['+'][EXPONENT] = SIGNED2;
		dfa['-'][EXPONENT] = SIGNED2;

		// 7. SIGNED2 变迁
		for (d = '0'; d <= '9'; ++d){
			dfa[d][SIGNED2] = SCIENCE;
		}

		// 8. SCIENCE 变迁
		for (d = '0'; d <= '9'; ++d){
			dfa[d][SCIENCE] = SCIENCE;
		}

		// 其余情况均变迁到 END
	}

	STATUS DFA(STATUS current, char input){
		STATUS ret = START;
		return dfa[input][current];
	}
};
原文地址:https://www.cnblogs.com/zjutzz/p/6664005.html