剑指offer——表示数值的字符串
终于写完了上一个复杂的题目,接下来继续练习字符串相关的题目,原题目链接:表示数值的字符串。
为了方便直接观看,此处还是先抄一下题目。
题目描述:
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100","5e2","-123","3.1416","-1E-16",都表示数值;但是"12e","1a3.14","1.2.3","+-5",和"12e+4.3"都不是。
题目分析:
要判断字符串是否表示数字,除了要判断是否包含数字外,还需要判断一些特殊字符如'+','-','e','E','.';以及这些字符出现的次数和位置。
我直接想到的方法依然是取出每个字符单独进行判断,对不同的符号,找出不同的限制条件:
'+','-'该符号必须出现在'e'或'E'之后,或者在最开始的位置;该符号之后必须是数字或者'.'
'e','E'后面不能有小数点,并且只能出现一次;该符号之后只能是数字或者'+','-'
'.'只能出现一次;
由于这种的判断对字符之间的依赖性特别强;所以单独判断的话代码写起来非常的繁琐;针对这种问题,可以选用正则表达式方法。
正则表达式的一些格式:
正则表达式以^开头,以$结尾;
一般多个可能会出现的字符会放在[]之间,表示出现其中的一个;单个字符放在\\之后
[]?表示方括号中间的字符可以存在也可以不存在;
\\d表示数字0-9;等价于[0-9];
后缀*表示前面的符号可以匹配0次或多次;
后缀+表示前面的符号至少要匹配一次
(?:)?表示这个分组可以出现也可以不出现,冒号后可以放字符
对于字符串是否为数字,可以先设置完整的规则要求:正负号(可选)整数(可选)小数点(可选)整数(可选)(这两部分不能单独考虑)e/E(可选)正负号(可选)整数。这三部分也不能单独考虑
针对上面的规则,可以得到如下的正则表达式:
^[+-]?\\d*(?:\\.\\d*)?(?:[eE][+-]?\\d+)?$
其中小数部分整体考虑,e/E部分也整体考虑;小数部分:(?:\\.\\d*)?可以整体出现,也可以整体不出现
e/E部分同理:(?:[eE][+-]?\\d+)?,此处需注意,出现了e/E后,必须要有一个整数
整理代码如下:
1 public boolean isNumeric(char[] str) { 2 String pattern = "^[+-]?\\d*(?:\\.\\d*)?(?:[eE][+-]?\\d+)?$"; 3 String s = new String(str); 4 return Pattern.matches(pattern,s); 5 }
牛客网运行已通过。