0%

剑指offer020表示数值的字符串

Problem:

请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串”+100”,”5e2”,”-123”,”3.1416”和”-1E-16”都表示数值。 但是”12e”,”1a3.14”,”1.2.3”,”+-5”和”12e+4.3”都不是。

Intuition:

首先我们来看一下题干里面的数字有哪些特点,不难发现所有的数字都可以大体写成整数+符号(小数点或者E,e)+整数的形式(如果第一个符号是小数点还可能出现第二个符号是e,但是总体来说不会出现比这种情况更复杂的情况了)。实现的时候我们要注意两个点。1.最好用一个全局变量index来存当前扫描到的下标,否则不断对下标进行传参或者进行数组的拷贝很麻烦也很容易出错。2.在进行其他判断之前都要判断数组是否越界,养成良好的习惯。

Solution:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public class CodingInterview_020 {
public static void main(String[] args) {
CodingInterview_020 main=new CodingInterview_020();
//"+100", "5e2", "-123", "3.1416", ".0e2", "1E-1", "+31.4e-1", ".12", "12"
String s="+31.4e-1";
System.out.println(main.isNumeric(s.toCharArray()));
}



//index作为一个全局下标记录当前字符串被扫描到的位置,如果不用全局变量的话一直记录将下标进行传参或者复制数组内容的话会非常不方便
private int index = 0;

public boolean isNumeric(char[] str) {
if (str.length < 1)
return false;
//下面这一行代码执行完后,如果这个str表示的是一个数的话,那么index此时指向的就是小数点或者字母e疑惑直接指向字符串的结尾。
//这一题肯定不能用递归来写,这样5.4.3就会被判定为整数。
boolean flag = scanInteger(str);

if (index < str.length && str[index] == '.') {
index++;
flag = scanUnsignedInteger(str) && flag;
}
//数字里面也可以出现先出现小数点再出现e

if (index < str.length && (str[index] == 'E' || str[index] == 'e')) {
index++;
flag = flag && scanInteger(str);
}

return flag && index == str.length;

}

private boolean scanInteger(char[] str) {
//这个函数包括下面的函数都要小心index<str.length的边界情况
if (index < str.length && (str[index] == '+' || str[index] == '-') )
index++;
return scanUnsignedInteger(str);

}

private boolean scanUnsignedInteger(char[] str) {
int start = index;
while (index < str.length && str[index] >= '0' && str[index] <= '9')
index++;
//这一步要额外注意一下,不然5.这样的测试用例就不会通过。
return start < index; //是否存在整数
}


}