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.666numeric = 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.4numeric = 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的数字时,返回truereturn 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。