本文涉及知识点
字符串
LeetCode65. 有效数字
给定一个字符串 s ,返回 s 是否是一个 有效数字。
 例如,下面的都是有效数字:“2”, “0089”, “-0.1”, “+3.14”, “4.”, “-.9”, “2e10”, “-90E3”, “3e+7”, “+6e-1”, “53.5e93”, “-123.456e789”,而接下来的不是:“abc”, “1a”, “1e”, “e3”, “99e2.5”, “–6”, “-+3”, “95a54e53”。
 一般的,一个 有效数字 可以用以下的规则之一定义:
 一个 整数 后面跟着一个 可选指数。
 一个 十进制数 后面跟着一个 可选指数。
 一个 整数 定义为一个 可选符号 ‘-’ 或 ‘+’ 后面跟着 数字。
 一个 十进制数 定义为一个 可选符号 ‘-’ 或 ‘+’ 后面跟着下述规则:
 数字 后跟着一个 小数点 .。
 数字 后跟着一个 小数点 . 再跟着 数位。
 一个 小数点 . 后跟着 数位。
 指数 定义为指数符号 ‘e’ 或 ‘E’,后面跟着一个 整数。
 数字 定义为一个或多个数位。
 示例 1:
 输入:s = “0”
 输出:true
 示例 2:
 输入:s = “e”
 输出:false
 示例 3:
 输入:s = “.”
 输出:false
 提示:
 1 <= s.length <= 20
 s 仅含英文字母(大写和小写),数字(0-9),加号 ‘+’ ,减号 ‘-’ ,或者点 ‘.’ 。
字符串
n = s.length
 预处理:
 一,将E替换成e。
 二,将-替换成+。
 如果包括e,且其下标为pos,则:
 s[pos+1…n-1]不能为空,且必须是整数。
 判断s[0,pos-1]是不是十进制数,is12。
 如果不包括e,is12(pos-1)。
is12
不能为空。
 如果s[0]是加号,left=1,否则left=0。
 s[left…r]不能为空。
 s[left…r]不能只有一个小数点。
 s[left…r]有0或1个小数点,其它全部是数字。
is2
如果s[left…r]包括非数字,返回假。
 返回真。
isint(是否整数)
不能为空。
 如果s[left]是加号left++。
 如果s[left…r]包括非数字,返回假。
 返回真。
代码
核心代码
class Solution {
public:
	bool isNumber(string s) {
		m_s = s;
		std::replace(m_s.begin(), m_s.end(), '-', '+');
		std::replace(m_s.begin(), m_s.end(), 'E', 'e');
		int pos = m_s.find('e');
		if (-1 == pos) {
			return Is12(m_s.length() - 1);
		}
		return Is12(pos - 1) && IsInt(pos + 1, m_s.length() - 1);
	}
	bool Is12(int r) {
		if (r < 0 ) { return false; }
		int left = ('+' == m_s[0]) ? 1 : 0;
		const int len = r - left + 1;
		if (len <= 0) { return false; }
		if ((1 == len) && ('.' == m_s[left])) { return false; }
		int pos = std::find(m_s.begin()+left, m_s.begin() + r + 1, '.') - m_s.begin();
		if (r + 1 == pos) {
			return Is2(left, r);
		}
		return Is2(left,pos - 1) && Is2(pos + 1, r);
	}
	bool Is2(int left, int r) {
		for (; left <= r; left++) {
			if (!isdigit(m_s[left])) { return false; }
		}
		return true;
	}
	bool IsInt(int left, int r) {
		const int len = r - left + 1;
		if (len <= 0) { return false; }
		if (('+' == m_s[left]) && (1 == len)) { return false; }
		if ('+' == m_s[left]) { left++; }
		for (; left <= r; left++) {
			if (!isdigit(m_s[left])) { return false; }
		}
		return true;
	}
	string m_s;
};
单元测试用例
template<class T1,class T2>
void AssertEx(const T1& t1, const T2& t2)
{
	Assert::AreEqual(t1 , t2);
}
template<class T>
void AssertEx(const vector<T>& v1, const vector<T>& v2)
{
	Assert::AreEqual(v1.size(), v2.size());	
	for (int i = 0; i < v1.size(); i++)
	{
		Assert::AreEqual(v1[i], v2[i]);
	}
}
template<class T>
void AssertV2(vector<vector<T>> vv1, vector<vector<T>> vv2)
{
	sort(vv1.begin(), vv1.end());
	sort(vv2.begin(), vv2.end());
	Assert::AreEqual(vv1.size(), vv2.size());
	for (int i = 0; i < vv1.size(); i++)
	{
		AssertEx(vv1[i], vv2[i]);
	}
}
namespace UnitTest
{
	string s;
	TEST_CLASS(UnitTest)
	{
	public:
		TEST_METHOD(TestMethod0)
		{
			s = "0";
			auto res = Solution().isNumber(s);
			AssertEx( true, res);
		}
		TEST_METHOD(TestMethod1)
		{
			s = "e";
			auto res = Solution().isNumber(s);
			AssertEx(false, res);
		}
		TEST_METHOD(TestMethod2)
		{
			s = ".";
			auto res = Solution().isNumber(s);
			AssertEx(false, res);
		}
		TEST_METHOD(TestMethod3)
		{
			s = "1E1";
			auto res = Solution().isNumber(s);
			AssertEx(true, res);
		}
		TEST_METHOD(TestMethod4)
		{
			s = "1e1";
			auto res = Solution().isNumber(s);
			AssertEx(true, res);
		}
		TEST_METHOD(TestMethod5)
		{
			s = "+12";
			auto res = Solution().isNumber(s);
			AssertEx(true, res);
		}
		TEST_METHOD(TestMethod6)
		{
			s = "-1";
			auto res = Solution().isNumber(s);
			AssertEx(true, res);
		}	
		TEST_METHOD(TestMethod8)
		{
			s = ".e2";
			auto res = Solution().isNumber(s);
			AssertEx(false, res);
		}
		TEST_METHOD(TestMethod9)
		{
			s = ".-4";
			auto res = Solution().isNumber(s);
			AssertEx(false, res);
		}
		TEST_METHOD(TestMethod10)
		{
			s = "1e.";
			auto res = Solution().isNumber(s);
			AssertEx(false, res);
		}
		TEST_METHOD(TestMethod11)
		{
			s = "+.8";
			auto res = Solution().isNumber(s);
			AssertEx(true, res);
		}
		TEST_METHOD(TestMethod12)
		{
			s = "+.";
			auto res = Solution().isNumber(s);
			AssertEx(false, res);
		}
		TEST_METHOD(TestMethod13)
		{
			s = "4e+";
			auto res = Solution().isNumber(s);
			AssertEx(false, res);
		}
		TEST_METHOD(TestMethod14)
		{
			s = "+e3";
			auto res = Solution().isNumber(s);
			AssertEx(false, res);
		}
	};
}

扩展阅读
视频课程
先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
 https://edu.csdn.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
 https://edu.csdn.net/lecturer/6176
相关推荐
| 我想对大家说的话 | 
|---|
| 《喜缺全书算法册》以原理、正确性证明、总结为主。 | 
| 按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。 | 
| 有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注 | 
| 闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。 | 
| 子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。 | 
| 如果程序是一条龙,那算法就是他的是睛 | 
测试环境
操作系统:win7 开发环境: VS2019 C++17
 或者 操作系统:win10 开发环境: VS2022 C++17
 如无特殊说明,本算法用**C++**实现。




















