剑指OFFER笔记_20_表示数值的字符串_JAVA实现
题目:表示数值的字符串
- 请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
解题思路
- 这题需要仔细查看合法和不合法的用例分别有哪些特点:
- 开头允许出现空格,结尾允许出现空格,字符串中间不允许。
- 正负号只允许出现在底数的整数部分之前和指数之前,不可以出现在底数的小数部分之前。
- 小数点只允许出现一次。指数部分不允许出现小数。
- 可以没有整数部分而只有小数部分,即“-.3e2”是合法的。
- e或E只允许出现一次。
- 数字部分允许以0开头,也允许出现".0e2"这种情况。
- 以上都是在力扣上测试的时候一次次试错出来的。。。一把辛酸泪。。。面试的时候和考官可以提前问清楚,也能体现对特殊情况的周到考虑。
- 之后可以利用一些boolean类型的变量作为标志位,对每一个字符进行检索的时候根据标志位是否符合规则来进行判断,若不符合直接返回false,否则允许continue检索下一个字符。
- 当全部检索完毕也没有返回false的时候,需要检查一下是否出现了数字位。
代码
函数主体部分代码
package q20;
public class Solution {
public boolean isNumber(String s) {
if (s == null || s.length() == 0)
{
return false;
}
char[] chars = s.toCharArray();
boolean numberOccur = false; //判断整数是否已经出现
boolean dotOccur = false; //判断小数点是否已经出现
boolean eOccur = false; //判断e/E是否已经出现
boolean flagOccur = false; //判断符号位是否已经出现
boolean endSpace = false; //判断是否出现了结尾的空格
boolean startSpace = false; //判断是否出现了开头的空格
for (int i = 0; i < chars.length; i++) {
//当检测到正负号的时候,必须为第一位或者是'e'/'E'的后一位
if (chars[i] == '+' || chars[i] == '-')
{
if (endSpace)
{
return false;
}
if ((!startSpace && i != 0 && chars[i-1] != 'e' && chars[i-1] != 'E') ||
(startSpace && chars[i-1] != ' ' && chars[i-1] != 'e' && chars[i-1] != 'E'))
{
return false;
}
flagOccur = true;
}
//当检测到数字时,无特殊要求,将numberOccur置true
else if (chars[i] >= '0' && chars[i] <= '9')
{
if (endSpace)
{
return false;
}
numberOccur = true;
}
//当检测到小数点时,前面只能有数字和正负号,不能有小数点和Ee
else if (chars[i] == '.')
{
if (dotOccur || eOccur || endSpace)
{
return false;
}
//此时后面必须有数字,否则会出现'.E13' '-3.E10'这种非法情况
dotOccur = true;
}
//当检测到eE时,之前不可以有eE 或者 没有数字
else if (chars[i] == 'e' || chars[i] == 'E')
{
if (eOccur || !numberOccur || endSpace)
{
return false;
}
eOccur = true;
numberOccur = false;
}
else if (chars[i] == ' ')
{
//当空格出现在开头的时候允许
if (!numberOccur && !dotOccur && !eOccur && !flagOccur)
{
startSpace = true;
continue;
}
endSpace = true;
}
//其他非法输入一律返回false
else
{
return false;
}
}
if (!numberOccur)
{
return false;
}
return true;
}
}
测试部分代码
- 此段部分中测试用例并没有包含所有情况
package q20;
public class TestApp {
public static void main(String[] args) {
Solution s = new Solution();
String[] legalStrs = {"2", "-2", "3.14", "-3.14",
"2.3e10", "-2.3e10", "3.4e-3", "-3.4e-3",
".2", "-.2", ".3e4", "-.3e4", " -3"};
for (int i = 0; i < legalStrs.length; i++) {
System.out.print(s.isNumber(legalStrs[i]) + " ");
}
System.out.println();
String[] illegalStrs = {".3.3", "3e", "3e1.1", "3e.1"};
for (int i = 0; i < illegalStrs.length; i++) {
System.out.print(s.isNumber(illegalStrs[i]) + " ");
}
}
}
运行结果截图
LeetCode运行截图
- 一把辛酸泪啊,一次次试错,一次次的去填上那些坑去满足那奇怪的测试用例。。