天天看点

剑指offer面试题54 表示数字的字符串(java实现)

解题思路:

1.在数值之前可能有一个表示正负的‘+’或者‘-’,接下来是若干个0到9的数位表示数值的整数部分(在某些小数里可能没有数值的整数部分)。如果数值是一个小数,那么在小数点后面可能会有若干个0到9的数位表示数值的小数部分。如果数值用科学技术法表示,接下来是一个'e'或者‘E’,以及紧跟着的一个整数(可以有正负号)表示指数。

2.判断一个字符串是否符合上述模式时,首先看第一个字符是不是正负号。如果是,在字符串上移动一个字符,继续扫描剩余的字符串中0-9的数位。如果是一个小数,则将遇到小数点。另外,如果是用科学计数法表示的数值,在整数或者小数的后面还可能遇到‘e’或者‘E’。编写代码时时刻需要判断数组是否越界。

public class Solution {

	public boolean isNumeric(char[] str) {

		if (str == null || str.length == 0) {
			return false;
		}
		int index = 0;
		// 如果第一位是正数或者负数
		if (str[index] == '+' || str[index] == '-') {
			index++;
		}
		// 如果此时达到数组的长度,证明此时字符数组为“+”,“-”
		if (index == str.length) {
			return false;
		}
		boolean isNumeric = true;
		index = scanDigits(str, index);
		// 扫描数字部分,扫完之后,index肯定指向非整数字符或者到达数组的末尾
		if (index < str.length) {
			// 继续扫描后面部分
			if (str[index] == '.') {
				// 如果此时index指向字符为小数点,则继续往后判断是否为小数位
				// 从第index+1位开始继续扫描,直到扫到第一个非数字字符或者数组结尾
				index++;
				index = scanDigits(str, index);
				if (index < str.length) {
					// 未扫描到数组尾部,此时index指向第一个非数字字符,判断是否为指数部分的开头(e或者E)
					if (str[index] == 'e' || str[index] == 'E') {
						// 判断e和E之后的字符是否满足指数条件
						index++;
						if (index == str.length) {
							// 此时类似于“123.46e”,不是数值
							isNumeric = false;
						} else {
							// 在不越界的情况下判断是否为指数
							// 此时加1后还得判断数组是否越界
							isNumeric = isExponential(str, index);
						}
					} else {
						// index所指字符为e,E之外的字符,肯定不是数值
						isNumeric = false;
					}

				} else {
					// 扫描到数组结尾,此时的数值类似“+123.456”
					isNumeric = true;
				}

			} else if (str[index] == 'e' || str[index] == 'E') {
				// 如果此时index指向字符为e或者E,则继续往后判断是否为指数位
				index++;
				if (index == str.length) {
					// 此时类似于“123e”,不是数值
					isNumeric = false;
				} else {
					// 在不越界的情况下判断是否为指数
					// 此时加1后还得判断数组是否越界
					isNumeric = isExponential(str, index);
				}

			} else {
				// 如果此时index指向字符所指向字符为非上述字符,则该字符数组肯定不是数值
				isNumeric = false;

			}
		} else {
			// 已经扫描到字符串尾部,此时的字符串应为“234“
			isNumeric = true;
		}

		return isNumeric;

	}

	// 扫描从e之后的字符是否是指数,题目中的指数部分不允许有小数
	private boolean isExponential(char[] str, int index) {
		// 此时index指向e之后的第一个字符,肯定不越界,至少是length前一个字符
		if (str[index] == '+' || str[index] == '-') {
			// 如果此时所指字符为+,-号.index后移一位
			index++;
		}

		// 找到第一个非数字字符或者到达数组尾部则循环结束
		while (index < str.length && str[index] >= '0' && str[index] <= '9') {
			index++;
		}

		if (index == str.length) {
			// 此时指数部分满足要求
			return true;
		} else {
			return false;
		}

	}

	private int scanDigits(char[] str, int index) {
		while (index < str.length && str[index] >= '0' && str[index] <= '9') {
			index++;
		}
		return index;

	}