【字符串】65. 有效数字

本文涉及知识点

字符串

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]包括非数字,返回假。

返回真。

代码

核心代码

cpp 复制代码
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;
};

单元测试用例

cpp 复制代码
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++**实现。

相关推荐
1 9 J4 分钟前
Java 上机实践4(类与对象)
java·开发语言·算法
passer__jw7672 小时前
【LeetCode】【算法】3. 无重复字符的最长子串
算法·leetcode
passer__jw7672 小时前
【LeetCode】【算法】21. 合并两个有序链表
算法·leetcode·链表
sweetheart7-72 小时前
LeetCode22. 括号生成(2024冬季每日一题 2)
算法·深度优先·力扣·dfs·左右括号匹配
李元豪3 小时前
【智鹿空间】c++实现了一个简单的链表数据结构 MyList,其中包含基本的 Get 和 Modify 操作,
数据结构·c++·链表
UestcXiye4 小时前
《TCP/IP网络编程》学习笔记 | Chapter 9:套接字的多种可选项
c++·计算机网络·ip·tcp
一丝晨光4 小时前
编译器、IDE对C/C++新标准的支持
c语言·开发语言·c++·ide·msvc·visual studio·gcc
景鹤4 小时前
【算法】递归+回溯+剪枝:78.子集
算法·机器学习·剪枝
_OLi_5 小时前
力扣 LeetCode 704. 二分查找(Day1:数组)
算法·leetcode·职场和发展
丶Darling.5 小时前
Day40 | 动态规划 :完全背包应用 组合总和IV(类比爬楼梯)
c++·算法·动态规划·记忆化搜索·回溯