LeetCode题目:表示数值的字符串

30 篇文章 1 订阅
17 篇文章 0 订阅

题目描述:

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

这道题在《剑指offer》上的讲解思路是用分割法:将字符串根据小数点“.”和E或者e把字符串切分成整数,小数,幂数三个部分,分别判断是否合法。但是这种方法需要考虑的特殊情况有很多种,比如小数点前面没有数字,或者小数点后面没有数字也是合法的,这个情况需要处理就有点麻烦;再比如,切分幂数部分的时候,根据e还是根据E,也要分情况讨论,还有要讨论正负号的一些情况,所以事先起来有点复杂,面试中肯定不是一时半会儿就写出来的。
LeetCode的题解里面看到一位大神的思路,清晰简单:
1、先对字符串做一个trim的操作,防止空格符对字符串的判断造成干扰。
2、将字符串转化为字符数组,一个个字符判断。
3、设置三个标志位:numSeen,dotSeen,eSeen分别表示前面有没有出现过数字,小数点和e或者E,初始化都是false。
4、遍历字符数组:
a) 找到一个数字时,将numSeen设为true,如果后面遇到e时,前面没有数字,是不合法的;
b) 找到小数点 ‘.’ 时,判断小数点和e前面有没有出现过(dotSeen和eSeen),如果前面已经出现过,就是不合法的,如果还没有出现不合法,就把dotSeen设置为true,表示这是小数点已经出现过了,如果再次出现就直接返回false;
c) 找到一个e或者E时,判断前面有没有出现数字(numSeen)或者前面有没有出现过e或者E(eSeen),如果前面还没出现过数字,或者已经出现过e了,就是不合法的,返回false;如果没有返回false,就把eSeen设置为true,同时把numSeen设置为false,因为后面必须要跟数字的;
d) 找到一个“+”或者“-”时,这两个符号的出现只有两种情况是合法的,要么出现在第一个字符,要么它的前一个字符是e或者E,其他情况都是不合法的,返回false。
e) 其他情况,字符数组里面出现了不是数字,不是小数点,不是e或者E的情况,全部都是不合法的,返回false;
5、最后,本来遍历的过程中如果没有出现返回false,就应该返回true,但是遍历过程中考虑出现e或者E,后面没有数字的情况,但是已经重设了numSeen为false,所以最终的返回结果取决于e后面还有没有出现数字。

代码(Java):

public class Solution {
	public static void main(String[] args) {
		String s = "+123.45E+12";
		System.out.println(isNumber(s));
	}
	
	public static boolean isNumber(String s) {
		if(s == null || s.length() == 0) { //输入为空,直接返回false
			return false;
		}
		s = s.trim(); //先对字符串裁剪一下,去掉字符串前后的空格,防止空格对判断产生干扰
		
		//这里设置三个符号位,表示前面的判断里面有没有出现过数字,小数点和e
		boolean numSeen = false;  //前面出现过数字,这个在判断e的时候会用到,如果出现了e,但是后面是没有数字的,是不合法的,false
		boolean dotSeen = false;  //前面有没有出现过小数点,如果出现小数点的时候判断,前面已经出现过小数点和e了,则是不合法的,false
		boolean eSeen = false;   //前面有没有出现个e,如果出现e是判断,前面已经出现过e了,或者前面还没有出现过数字,则是不合法的,false
		
		char[] str = s.toCharArray();  //将字符串转化为字符数组方便处理
		
		for(int i = 0;i<str.length;i++) { //对字符数组里面的字符每个都判断一下
			if(str[i] >= '0' && str[i] <= '9') { //第一种情况,最常见的,出现了数字,就把numSeen设置为true
				numSeen = true;
			}else if(str[i] == '.') { //第二种情况,出现了小数点,判断如果已经出现过了,或者前面已经出现过了e,就返回false
				if(dotSeen == true || eSeen == true) {
					return false;
				}
				dotSeen  = true;  //如果没有返回false,来到这里小数点就已经出现过了,把dotSeen设为true
			}else if(str[i] == 'e' || str[i] == 'E') { //第三种情况,出现e了,如果e已经出现过了,后者前面数字还没有出现过,则false
				if(eSeen == true || numSeen == false) {
					return false;
				}
				eSeen = true;  //来到这里如果没有返回false,这是e已经出现过了,将ESeen设为true
				numSeen = false; //出现e之后,后面必须要有数字,不然是不合法的,false
			}else if(str[i] == '+' || str[i] == '-'){ //第四中情况,出现正负号了,正负号的出现,只能有两种情况
				if(i != 0 && str[i-1] != 'e' && str[i-1] != 'E') { //要么是出现在第一个字符,要么就是出现在e之后,其他都是不合法的
					return false;
				}
			}else { //还有其他情况,遇到不是数字,不是小数点,不是e的肯定是不合法的。
				return false;
			}
		}
		return numSeen; //最后返回numSeen标志位,本来整个过程没有返回false就应该返回true的,但是还要考虑到e之后必须要跟有数字,所以返回numSeen
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值