剑指offer20题表示数值的字符串:这题实在是太优雅了

目录

  • 前言
  • 一、憨憨初解
    • 1、思路
    • 2、代码
    • 3、战绩
    • 4、反思
  • 二、看懂再解
    • 1、思路
    • 2、代码
    • 3、C++版战绩
  • 总结
前言
题目来源:https://leetcode.cn/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof/
这个题目有官方解释的有限状态自动机,也有用正则肝的,甚至有暴躁老哥打算直接把这题撕了的 , 但是,还得是评论区里人才多 , 总有大佬能肝出来清晰的题解,这波记录一下,食用这个题目的过程 。
剑指offer20题表示数值的字符串:这题实在是太优雅了

文章插图
大佬讲解链接:https://www.bilibili.com/video/BV1KP411L7VH/?p=20&vd_source=a3808e6f1547cd8a5765ed7361e92529
一、憨憨初解1、思路看完题目感觉没什么难的,字符串处理题么应该是,从字符串开始到最后遍历就完事儿,用cur记录遍历的长度,如果最后能够按照题目给的规则遍历完,那么cur就等于字符串的长度就返回true,否则false
2、代码class Solution {public:bool isNumber(string s) {if (s.empty() || s.size() == 0) return false;int cur=0;while(s[cur] == ' ')cur++;//去调首部空格//处理一个整数或者小数if(s[cur] == '+' || s[cur] == '-') cur++;while(s[cur] >= '0' && s[cur] <= '9')cur++;if(s[cur] == '.') cur++;while(s[cur] >= '0' && s[cur] <= '9')cur++;//处理e和E以及一个整数if(s[cur]=='e' || s[cur]=='E') cur++;if(s[cur] == '+' || s[cur] == '-') cur++;while(s[cur] >= '0' && s[cur] <= '9')cur++;while(s[cur] == ' ')cur++;//处理尾部空格return cur==s.size();}};3、战绩
剑指offer20题表示数值的字符串:这题实在是太优雅了

文章插图
4、反思存在一些情况没有考虑,憨憨我直接一波下去了,看题解看的有点懵,然后看大佬视频题解后,理解了思路 , 自己用C++复现了一波;
二、看懂再解1、思路首先判断为空字符串的返回false , 然后用trim去除段首段尾空格;定义三个标准布尔量,分别表示数字和点还要e或者E是否出现过,从开始到结尾进行遍历,如果出现了不符合标准的情况就返回false 。
这个不符合标准的情况规律是大佬以身探出来的,感恩一下前人,自己很难严谨的考虑到这些东西 。
1、小数点出现的时候,前面不能出现过小数点或者是出现过e;
  • 解释:'.'只能在底数上,不能在指数上,且只能出现一次,'.'两边任一边有数字均算一个完整的数字,但单独一个'.'不行 。
2、e或者E出现的时候,前面不能出现过eE,并且必须出现过一个数字;
  • 解释:e、E用来划分底数与指数,只能出现一次,前面为科学计数法的底数,后面为指数;
3、+-符号,只能出现在第一位或者紧接e后面;
  • 解释:'+'、'-'只能作为正负号出现在底数和指数的前面,不能出现在两个数字中间;
特别需要注意的是为了避免123e这种请求,出现e之后就标志is_num为false,最后返回is_num即可!其实不用看解释,理解即可 , 记好这三条规律和一个特别的情况就能快速的编写出解题代码!
2、代码复现的C++版:
class Solution {public:static void trim(string &s){if( !s.empty() ){s.erase(0,s.find_first_not_of(" "));s.erase(s.find_last_not_of(" ") + 1);}}bool isNumber(string s) {if (s.empty() || s.size() == 0) return false;trim(s);bool is_num = false;//判断数字是否出现过bool is_dot = false;//判断.是否出现过bool is_eorE = false;//判断e或者E是否出现过int i = 0,size = s.size();for (; i < size; i++) {//判定为数字 , 则标记is_numif (s[i] >= '0' && s[i] <= '9') {is_num = true;//判定为.需要前面没出现过.并且没出现过e} else if (s[i] == '.' && !is_dot && !is_eorE) {is_dot = true;//判定为e或者E,需要前面没出现过e , 并且出现过数字} else if ((s[i]=='e' || s[i]=='E') && !is_eorE && is_num) {is_eorE = true;is_num = false;//为了避免123e这种请求,出现e之后就标志为false//判定为+-符号,只能出现在第一位或者紧接e后面} else if (s[i] == '-' || s[i] == '+'){if(i!=0 && s[i-1] != 'e' && s[i-1] != 'E'){return false;}} else {return false;}}return is_num;}};大佬的Java版:
class Solution {public boolean isNumber(String s) {//有限状态机// 2.小数点 3.E/e 4. 数字字符 5. -+if(s == null || s.length() <= 0){return false;}char[] res = s.trim().toCharArray();if(res.length <= 0) return false;int n = res.length;boolean is_dot = false;boolean is_e_or_E = false;boolean is_num = false;for(int i = 0; i < n; i++){if(res[i] >= '0' && res[i] <= '9'){is_num = true;} else if(res[i] == '.'){//-+ 8.8.8.8// 前面:不能有重复的小数点,也不能出现 e/Eif(is_dot || is_e_or_E){return false;}is_dot = true;} else if(res[i] == 'e' || res[i] == 'E'){// 前面必须要有一个数字 || 前面不能出现重复的 e/Eif(is_e_or_E || !is_num){return false;}is_e_or_E = true;is_num =false;//11E+ 11E} else if(res[i] == '-' || res[i] == '+'){if(i!=0 && res[i-1] != 'e' && res[i-1] != 'E'){return false;}} else {return false;}}return is_num;}}

推荐阅读