本文涉及知识点
字符串
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++**实现。