《剑指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 false
和if()
但是如果想要通过调用函数的方式,我有必须知道每一部分的起始和结束位置
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 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步