20.表示数值的字符串
题目
官方地址
代码(正则表达式)
public boolean isNumeric (String str) {
if (str == null || str.length() == 0)
return false;
return new String(str).matches("[+-]?\\d*(\\.\\d+)?([eE][+-]?\\d+)?");
}
在给定的代码中,matches() 方法被用于判断一个字符串是否表示一个数值。下面是对该方法的详细解释:
if (str == null || str.length() == 0):首先,代码检查输入的字符串 str 是否为 null 或者长度为 0。如果是,表示字符串为空,无法进行数值判断,因此返回 false。
new String(str):代码创建了一个新的字符串对象,目的是为了调用 matches() 方法。这里的目的是确保 matches() 方法被调用。
matches("[+-]?\\d*(\\.\\d+)?([eE][+-]?\\d+)?")
:该代码使用正则表达式来判断字符串是否匹配数值的模式。
- [±]?:表示正负号可选,即可有可无。 \d*:表示 0 个或多个数字。
- (\.\d+)?:表示小数部分,其中 \.表示小数点,\d+ 表示一个或多个数字。整个部分可选,表示小数部分可有可无。
- ([eE][±]?\d+)?:表示指数部分,其中[eE] 表示指数符号,[±]? 表示正负号可选,\d+ 表示一个或多个数字。整个部分可选,表示指数部分可有可无。
题解
class Solution {
private int currentIndex;
public boolean isNumber(String s) {
s = s.trim();
int n = s.length();
if (n == 0) {
return false;
}
currentIndex = 0;
boolean numeric = scanInteger(s);
// 如果出现'.',接下来是数字的小数部分
if (currentIndex < n && s.charAt(currentIndex) == '.') {
currentIndex++;
// 下面一行代码用||的原因:
// 1. 小数可以没有整数部分,例如.123等于0.123;
// 2. 小数点后面可以没有数字,例如233.等于233.0;
// 3. 当然小数点前面和后面可以有数字,例如233.666
numeric = scanUsignedInteger(s) || numeric;
}
// 如果出现'e'或者'E',接下来跟着的是数字的指数部分
if (currentIndex < n && (s.charAt(currentIndex) == 'e' || s.charAt(currentIndex) == 'E')) {
currentIndex++;
// 下面一行代码用&&的原因:
// 1. 当e或E前面没有数字时,整个字符串不能表示数字,例如.e1、e1;
// 2. 当e或E后面没有整数时,整个字符串不能表示数字,例如12e、12e+5.4
numeric = scanInteger(s) && numeric;
}
return currentIndex == n && numeric;
}
/**
* 整数的格式可以用[+|-]B表示, 其中B为无符号整数
* @param s
* @return
*/
private boolean scanInteger(String s) {
int n = s.length();
if (currentIndex < n && (s.charAt(currentIndex) == '+' || s.charAt(currentIndex) == '-')) {
currentIndex++;
}
return scanUsignedInteger(s);
}
private boolean scanUsignedInteger(String s) {
int n = s.length();
int beforeIndex = currentIndex;
while (currentIndex < n && '0' <= s.charAt(currentIndex) && s.charAt(currentIndex) <= '9') {
currentIndex++;
}
// 当str中存在若干0-9的数字时,返回true
return currentIndex > beforeIndex;
}
}
-
首先,将字符串的两端空格去除,并获取字符串的长度 n。如果去除空格后的字符串长度为0,直接返回 false。
-
初始化 currentIndex 为0,用于追踪当前扫描的位置。
-
调用 scanInteger(s) 方法判断字符串的整数部分。该方法会检查当前位置是否为正号或负号,如果是则将 currentIndex 增加1,并调用 scanUnsignedInteger(s) 方法判断无符号整数部分。
-
如果当前位置小于字符串长度且当前字符是小数点(‘.’),则将 currentIndex 增加1,并调用 scanUnsignedInteger(s) 方法判断小数部分。注意,小数部分可以没有整数部分,也可以没有小数点后的数字,因此使用逻辑或(||)将结果与 numeric 进行逻辑运算。
-
如果当前位置小于字符串长度且当前字符是指数符号(‘e’ 或 ‘E’),则将 currentIndex 增加1,并调用 scanInteger(s) 方法判断指数部分。指数部分必须包含整数,因此使用逻辑与(&&)将结果与 numeric 进行逻辑运算。
-
最后,判断 currentIndex 是否等于字符串长度,并且 numeric 是否为 true。如果满足条件,表示整个字符串可以解释为一个数值,返回 true;否则返回 false。
scanInteger()
方法用于判断整数部分:
获取字符串的长度 n。
如果当前位置小于字符串长度且当前字符是正号或负号(‘+’ 或 ‘-’),则将 currentIndex 增加1。
调用 scanUnsignedInteger(s) 方法判断无符号整数部分。
返回 scanUnsignedInteger(s) 的结果。
scanUnsignedInteger()
方法用于判断无符号整数部分:
获取字符串的长度 n。
初始化 beforeIndex 为 currentIndex 的值。
当 currentIndex 小于字符串长度且当前字符是数字字符(‘0’ 到 ‘9’ 之间的字符)时,将 currentIndex 增加1。
判断 currentIndex 是否大于 beforeIndex。如果大于,表示字符串中存在若干数字字符,返回 true;否则返回 false。