Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
一、题目描述:
题目来源:LeetCode>表示数值的字符串
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
数值(按顺序)可以分成以下几个部分:
若干空格
一个 小数 或者 整数
(可选)一个 'e' 或 'E' ,后面跟着一个 整数
若干空格
小数(按顺序)可以分成以下几个部分:
(可选)一个符号字符('+' 或 '-')
下述格式之一:
至少一位数字,后面跟着一个点 '.'
至少一位数字,后面跟着一个点 '.' ,后面再跟着至少一位数字
一个点 '.' ,后面跟着至少一位数字
整数(按顺序)可以分成以下几个部分:
(可选)一个符号字符('+' 或 '-')
至少一位数字
部分数值列举如下:
["+100", "5e2", "-123", "3.1416", "-1E-16", "0123"]
部分非数值列举如下:
["12e", "1a3.14", "1.2.3", "+-5", "12e+5.4"]
示例 1:
输入:s = "0"
输出:true
示例 2:
输入:s = "e"
输出:false
示例 3:
输入:s = "."
输出:false
示例 4:
输入:s = " .1 "
输出:true
提示:
1 <= s.length <= 20
s 仅含英文字母(大写和小写),数字(0-9),加号 '+' ,减号 '-' ,空格 ' ' 或者点 '.' 。
二、思路分析:
思路一:
- 通过字符'e'或'E'为界限,分别判断两边左边字符串是否是整数或小数,以及右边字符串是否是整数。
- 通过一个boolean类型的flag变量用来保证只会出现一个小数点号'.'
思路二:
- 首先定义四个flag,对应四种字符
是否有数字:hasNumberFlag
是否有e:hasEFlag
是否有正负符号:hasSignFlag
是否有点:hasDotFlag
- 定义字符串长度n以及字符串索引index
- 先处理开头的空格,index相应的后移
- 进入循环,遍历字符串
- 如果当前字符c是数字:将hasNumberFlag置为true,index往后移动一直到非数字或遍历到末尾位置;如果已遍历到末尾(index == n),结束循环
- 如果当前字符c是'e'或'E':如果e已经出现或者当前e之前没有出现过数字,返回fasle;否则令hasEFlag = true,并且将其他3个flag全部置为false,因为要开始遍历e后面的新数字了
- 如果当前字符c是+或-:如果已经出现过+或-或者已经出现过数字或者已经出现过'.',返回flase;否则令hasSignFlag = true
- 如果当前字符c是'.':如果已经出现过'.'或者已经出现过'e'或'E',返回false;否则令hasDotFlag = true
- 如果当前字符c是' ':结束循环,因为可能是末尾的空格了,但也有可能是字符串中间的空格,在循环外继续处理
- 如果当前字符c是除了上面5种情况以外的其他字符,直接返回false
- 处理空格,index相应的后移
- 如果当前索引index与字符串长度相等,说明遍历到了末尾,但是还要满足hasNumberFlag为true才可以最终返回true,因为如果字符串里全是符号没有数字的话是不行的,而且e后面没有数字也是不行的,但是没有符号是可以的,所以4个flag里只要判断一下hasNumberFlag就行;所以最后返回的是hasNumberFlag && index == n
- 如果字符串中间有空格,按以上思路是无法遍历到末尾的,index不会与n相等,返回的就是false
三、AC 代码:
思路一:
class Solution {
public boolean isNumber(String s) {
s = s.trim();
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == 'e' || s.charAt(i) == 'E') {
String leftString = s.substring(0, i);
String rightString = s.substring(i + 1, s.length());
return (isInteger(leftString) || isDecimal(leftString)) && isInteger(rightString);
}
}
return isInteger(s) || isDecimal(s);
}
public boolean isInteger(String str) {
if (str.equals("")) return false;
if (str.charAt(0) == '+' || str.charAt(0) == '-') {
if (str.length() <= 1) return false;
for (int i = 1; i < str.length(); i++) {
if (str.charAt(i) < '0' || str.charAt(i) > '9') return false;
}
} else {
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) < '0' || str.charAt(i) > '9') return false;
}
}
return true;
}
public boolean isDecimal(String str) {
if (str.equals("")) {
return false;
}
if (str.charAt(0) == '+' || str.charAt(0) == '-') {
if (str.length() <= 2) {
return false;
}
boolean pointerFlag = true;
for (int i = 1; i < str.length(); i++) {
if (pointerFlag && str.charAt(i) == '.') {
pointerFlag = false;
continue;
}
if (str.charAt(i) < '0' || str.charAt(i) > '9') {
return false;
}
}
} else {
if (str.length() <= 1) {
return false;
}
boolean flag = true;
for (int i = 0; i < str.length(); i++) {
if (flag && str.charAt(i) == '.') {
flag = false;
continue;
}
if (str.charAt(i) < '0' || str.charAt(i) > '9') {
return false;
}
}
}
return true;
}
}
思路二:
class Solution {
public boolean isNumber(String s) {
int n = s.length();
int index = 0;
boolean hasNumberFlag = false;
boolean hasEFlag = false;
boolean hasSignFlag = false;
boolean hasDotFlag = false;
while (index < n && s.charAt(index) == ' ')
index++;
while (index < n) {
while (index < n && s.charAt(index) >= '0' && s.charAt(index) <= '9') {
index++;
hasNumberFlag = true;
}
if (index == n) break;
char c = s.charAt(index);
if (c == 'e' || c == 'E') {
if (hasEFlag || !hasNumberFlag) return false;
hasEFlag = true;
hasNumberFlag = false;
hasSignFlag = false;
hasDotFlag = false;
} else if (c == '+' || c == '-') {
if (hasSignFlag || hasNumberFlag || hasDotFlag) {
return false;
}
hasSignFlag = true;
} else if (c == '.') {
if (hasDotFlag || hasEFlag) return false;
hasDotFlag = true;
} else if (c == ' ') {
break;
} else {
return false;
}
index++;
}
while (index < n && s.charAt(index) == ' ')
index++;
return hasNumberFlag && index == n;
}
}