题目
思路及代码
/**
* 分析:整体分两种
* A[.[B]][e|EC] .B[e|EC]
*
* 要求:
* A:整数,可正可负
* B:整数,只能正
* C:整数,可正可负
*
* 思路主要是判断ABC的值是否符合要求,从字符串的前面开始检查判断。
*
* PS:
* 1. 本题做法中两个辅助函数返回的都是对象,本来是返回一个布尔值的,不过需要保存index的值,所以就返回一个包含布尔值和index的对象
* 2. 两个辅助函数会在不符合要求或者字符串末尾停止扫描字符。
*/
var isNumber = function(s) {
// 先把前后空格去掉
var s = s.trim();
// 空字符串
if (s.length === 0) return false;
var index = 0;
// 是否数值的标志(从index位置起,到不是数字的位置停下)
var obj1 = scanInteger(s, index);
var isNumberFromIndex = obj1.isInteger;
index = obj1.index;
// 如果出现'.',接下来是数字的小数部分
if (s[index] === '.') {
++index;
var obj2 = scanUnsignedInteger(s, index);
// isNumberFromIndex = obj2.isUnsignedInteger;
index = obj2.index;
// 下面一行代码用||的原因:
// 1. 小数可以没有整数部分,例如.123等于0.123;
// 2. 小数点后面可以没有数字,例如233.等于233.0;
// 3. 当然小数点前面和后面可以有数字,例如233.666
isNumberFromIndex = obj2.isUnsignedInteger || isNumberFromIndex;
}
if (s[index] === 'e' || s[index] === 'E') {
++index;
var obj3 = scanInteger(s, index);
index = obj3.index;
// 下面一行代码用&&的原因:
// 1. 当e或E前面没有数字时,整个字符串不能表示数字,例如.e1、e1;
// 2. 当e或E后面没有整数时,整个字符串不能表示数字,例如12e、12e+5.4
isNumberFromIndex = obj3.isInteger && isNumberFromIndex;
}
// 如果index !== s.length,说明还有其他非符合要求的字符,比如字母等
return isNumberFromIndex && index === s.length;
}
// 扫描不带符号整数的字符,返回一个包含布尔值和index的对象
var scanUnsignedInteger = function(s, index) {
// 把参数index存起来
var before = index;
while (index <= s.length - 1 && s[index] >= '0' && s[index] <= '9') {
++index;
}
return {
isUnsignedInteger: index > before, // 如果字符不是0-9之中的其中一个,说明不是数字
index
};
}
// 扫描整数字符(可带正负号),返回一个包含布尔值和index的对象
var scanInteger = function(s, index) {
if (s[index] === '+' || s[index] === '-') {
++index;
}
return {
isInteger: scanUnsignedInteger(s, index).isUnsignedInteger,
index: scanUnsignedInteger(s, index).index,
}
}