Files
envi-code/SourceCode/Code2026/inc/verifyNumberString.h
T
2026-09-28 15:28:50 +08:00

145 lines
3.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
#include <vector>
#include <string>
template <typename CharType>
class verifyNumberString
{
public:
typedef std::basic_string<CharType> string;
private:
enum State
{
START, // 0: 起始状态(含前导空格)
SIGN, // 1: 符号位(正负号)
INTEGER, // 2: 整数部分
POINT_HEAD, // 3: 小数点(前面无数字)
POINT_AFTER_INT, // 4: 整数后的小数点
FRACTION, // 5: 小数部分
EXP, // 6: 指数标识(e/E)
EXP_SIGN, // 7: 指数符号
EXP_INT, // 8: 指数整数部分
SPACE // 9: 空格后缀
};
public:
verifyNumberString(const CharType *psz): m_string(psz){}
verifyNumberString(const string &str): m_string(str){}
bool verify();
bool operator !();
private:
int getType(CharType c);
static const std::vector<std::vector<int>> &getStates();
public:
string m_string;
};
template <typename CharType>
int verifyNumberString<CharType>::getType(CharType c)
{
if (c == static_cast<CharType>(' ')) return 0; // 空格
if (c == static_cast<CharType>('+') ||
c == static_cast<CharType>('-')) return 1; // 符号
if (c >= static_cast<CharType>('0') &&
c <= static_cast<CharType>('9')) return 2; // 数字
if (c == static_cast<CharType>('.')) return 3; // 小数点
if (c == static_cast<CharType>('e') ||
c == static_cast<CharType>('E')) return 4; // 指数标识
return 5; // 其他字符
}
// 状态转移表(延迟初始化,线程安全)
template <typename CharType>
const std::vector<std::vector<int>>& verifyNumberString<CharType>::getStates()
{
static std::vector<std::vector<int>> st;
if (st.empty())
{
st.resize(10, std::vector<int>(6, -1));
// 状态0: START
st[START][0] = START; // 空格 -> 保持START
st[START][1] = SIGN; // 符号 -> 进入SIGN
st[START][2] = INTEGER; // 数字 -> 进入INTEGER
st[START][3] = POINT_HEAD; // 小数点 -> 进入POINT_HEAD
// 状态1: SIGN
st[SIGN][2] = INTEGER; // 数字 -> 进入INTEGER
st[SIGN][3] = POINT_HEAD; // 小数点 -> 进入POINT_HEAD
// 状态2: INTEGER
st[INTEGER][2] = INTEGER; // 数字 -> 保持INTEGER
st[INTEGER][3] = POINT_AFTER_INT; // 小数点 -> POINT_AFTER_INT
st[INTEGER][4] = EXP; // 指数标识 -> 进入EXP
st[INTEGER][0] = SPACE; // 空格 -> 进入SPACE
// 状态3: POINT_HEAD
st[POINT_HEAD][2] = FRACTION; // 数字 -> 进入FRACTION
// 状态4: POINT_AFTER_INT
st[POINT_AFTER_INT][2] = FRACTION; // 数字 -> 进入FRACTION
st[POINT_AFTER_INT][4] = EXP; // 指数标识 -> 进入EXP
st[POINT_AFTER_INT][0] = SPACE; // 空格 -> 进入SPACE
// 状态5: FRACTION
st[FRACTION][2] = FRACTION; // 数字 -> 保持FRACTION
st[FRACTION][4] = EXP; // 指数标识 -> 进入EXP
st[FRACTION][0] = SPACE; // 空格 -> 进入SPACE
// 状态6: EXP
st[EXP][1] = EXP_SIGN; // 符号 -> 进入EXP_SIGN
st[EXP][2] = EXP_INT; // 数字 -> 进入EXP_INT
// 状态7: EXP_SIGN
st[EXP_SIGN][2] = EXP_INT; // 数字 -> 进入EXP_INT
// 状态8: EXP_INT
st[EXP_INT][2] = EXP_INT; // 数字 -> 保持EXP_INT
st[EXP_INT][0] = SPACE; // 空格 -> 进入SPACE
// 状态9: SPACE
st[SPACE][0] = SPACE; // 空格 -> 保持SPACE
}
return st;
}
// 验证数字字符串
template <typename CharType>
bool verifyNumberString<CharType>::verify()
{
State current = START;
const std::vector<std::vector<int>> &states = getStates(); // 获取状态转移表
for (size_t i(0); i < m_string.size(); ++i)
{
int type = getType(m_string[i]);
int next = states[current][type];
if (next == -1) return false;
current = static_cast<State>(next);
}
// 有效结束状态
return (current == INTEGER
|| current == POINT_AFTER_INT
|| current == FRACTION
|| current == EXP_INT
|| current == SPACE);
}
// 重载 ! 操作符
template <typename CharType>
bool verifyNumberString<CharType>::operator!()
{
return !verify();
}
#ifdef _UNICODE
typedef verifyNumberString<wchar_t> VNST;
#else
typedef verifyNumberString<char> VNST;
#endif