2023-09-09 15:15阅读: 9评论: 0推荐: 0

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

这种按照一定规则来验证字符串的题看起来很麻烦,想到另外一道类似的是验证 IP 地址

……我觉得我理不清这个判断逻辑以及各个逻辑间的关系以控制逻辑

bool isNumber(string s) {
// 首先这个字符串可能得样式为
// [若干可能的空格][[+/-][num./num.num/.num/num]][E/e][[+/-][num]][若干可能的空格]
int begin = 0;
while (s[begin] == ' ' && begin<s.size()) begin++;
// 得到第一个不为空的位置,开始验证
if (s[begin] == s.size()) return false;// 一个全是空格的字符串
int ePlace = begin;
while (s[ePlace] != 'E' && s[ePlace] != 'e' && ePlace < s.size()) {
ePlace++;
}
if (s[begin] >= 48 && s[begin] <= 57) {
// 字符是一个数字
}
else {
if (s[begin] == '+' || s[begin] == '-') begin++;
else
}
return false;
}

比如:如果我想要从头到尾一个一个可能性地判断就会非常的复杂繁琐,我需要考虑每一种可能,写很多的return falseif()

但是如果想要通过调用函数的方式,我有必须知道每一部分的起始和结束位置

bool isNumber(string s) {
// 首先这个字符串可能得样式为
// [若干可能的空格][[+/-][num./num.num/.num/num]][E/e][[+/-][num]][若干可能的空格]
int begin = 0;
while (s[begin] == ' ' && begin<s.size()) begin++;
// 得到第一个不为空的位置,开始验证
if (s[begin] == s.size()) return false;// 一个全是空格的字符串
int ePlace = begin;
while (s[ePlace] != 'E' && s[ePlace] != 'e' && ePlace < s.size()) {
ePlace++;
}
return false;
}
// 判断是不是一个合法的整数
bool isInteger(string &str,int begin,int end){
if (begin >= end && str[begin] == '+' || str[begin] == '-' || (str[begin] >= 48 && str[begin] <= 57)) {
begin++;
while (str[begin] >= 48 && str[begin] <= 57) {
begin++;
if (begin == end) return true;
}
}
return false;
}
// 判断是不是一个合法的小数
bool isDcimal(string &str,int begin,int end) {
if (begin >= end) return false;
if (str[begin] == '+' || str[begin] == '-') begin++;
else if (str[begin] >= 48 && str[begin] <= 57) {
// 是一个数字,后面可以是小数点也可以是数字
begin++;
}
else if (str[begin == '.']) {
// 小数点开头,后面必须有数字
begin++;
while (str[begin] >= 48 && str[begin] <= 57) {
begin++;
if (begin == end) return true;
}
}
return false;
}

不管是哪样,这么分类讨论太麻烦了,而且也很容易出错

书上官解

官解和力扣题目有差异,力扣要求更多,主要是会有空格,前后中间都有可能有空格

给官解打了补丁 AC

bool isNumber(string s) {
const char* pointer = s.c_str();// 获取字符指针
while (*pointer == ' ') ++pointer;// 跳过前导空格
bool numeric = scanInteger(&pointer);
if (*pointer == '.') {
++pointer;
/*
* 为什么会有||运算?
* 小数点前面可有可无,后面可有可无,但是不能都无
* [带符号数字].[不带符号数字]
*/
numeric = scanUnsignedInteger(&pointer) || numeric;
}
if (*pointer == 'E' || *pointer == 'e') {
++pointer;
// E前面和后面都必须有数字
numeric = scanInteger(&pointer) && numeric;
}
// 如果指针停在了空格,需要检查空格后面还有没有字符
if (numeric) {
while (*pointer == ' ') ++pointer;
return *pointer == '\0';
}
return false;
}
bool scanInteger(const char** str) {
if (**str == '+' || **str == '-') ++(*str);
return scanUnsignedInteger(str);
}
bool scanUnsignedInteger(const char** str) {
const char* before = *str;
while (**str != '\0' && **str!=' ' && **str >= '0' && **str <= '9') ++(*str);
return *str > before;// 是有效长度的字符串,只要字符串存在从当前位置开始的一段数字就返回true
}

后面有机会的话试着当做一个 正则表达式的练习题题做一遍

本文作者:YaosGHC

本文链接:https://www.cnblogs.com/yaocy/p/17687091.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   YaosGHC  阅读(9)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起