Day53:表示数值的字符串

时间:2022-07-24
本文章向大家介绍Day53:表示数值的字符串,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

剑指Offer_编程题——表示数值的字符串

题目描述:

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

具体要求:

时间限制: C/C++ 1秒,其他语言2秒 空间限制: C/C++32M,其他语言64M

具体实现:

一、背景知识介绍:   在做题之前,我们首先给大家介绍正则表达式,正则表达式在上一篇文章提到过,今天是因为会用到正则表达式,因此我们详细介绍正则表达式的应用。 正则表达式:   正则表达式是用来描述或者匹配一系列符合某个语句规则的字符串。其中的在单个符号中:   ①、 . 符号:匹配单个任意字符。(例如:表达式t.o可以匹配:tno , t#o, teo等, 不可以匹配:tnno, to, Tno, t正o)   ②、 [] :只有方括号里面指定的字符才参与匹配,也只能匹配单个字符。(表达式:t[abcd]n只可以匹配tan,tbn,tcn,tdn。不可匹配thn,tabn,tn等)    | 符号:相当与“或”,可以匹配指定的字符,但是也只能选择其中一项进行匹配。(表达式:t[a|b|c|dd]n只可以匹配tan,tbn,tcn,tddn。不可匹配tbacn,taan,tn等)   ④、表示匹配次数的符号 例如:表达式: [0-9]{3} -[0-9]{2}-[0-9]{3}的匹配格式为:999-99-999;由于 - 符号在正则表达式中有特殊的含义,它表示一个范围,所以在前面加转义字符。   ⑤、^ 符号:表示否,如果用在方括号内,^表示不想匹配的字符。(例如:表达式:[ ^ x] 第一个字符不能是x)   ⑥、S符号:非空字符   ⑦、s符号:空字符,只可以匹配一个空格、制表符、回车符、换页符,不可以匹配自己输入的多个空格。   ⑧、r符号:空格符,与n、tab相同   常用正则表达式有^d+ :非负整数(正整数 + 0)、 ^ [0-9][1-9][0-9] :正整数、^(([0-9]+.[0-9][1-9][0-9])|([0-9][1-9][0-9].[0-9]+)|([0-9][1-9][0-9])) : 正 浮 点 数 、 [ A − Z a − z ] + :正浮点数、^[A-Za-z]+ :正浮点数、[A−Za−z]+ :由26个英文字母组成的字符串等。 思路一:   根据我们题意以及我们刚才介绍的正则表达式的介绍,不难想象本题其实考察的是正则表达式的应用。因此我们首先用Java和python将其实现。 1、用Java解答该题:

public class Solution{
	public boolean isNumeric(char[] str){
		if(str == null)
			return false;
		return new String(str).matches("[+-]?[0-9]*(\.[0-9]*)?([eE][+-]?[0-9]+)?");
	}
}

代码效果图如图所示:

2、接下来用python实现

import re
class Solution:
	def isNumeric(self, s):
		return re.match(r"^[+-]?[0-9]*(.[0-9]*)?([eE][+-]?[0-9]+)?$", s)

代码效果图如图所示:

思路二:   本题其实就是考察正则表达式,因此如果我们一开始就想到正则匹配,那就很简单,关键我们一开始想不到正则匹配这种简单的方法,那用另一种方法进行分别用java和python将其实现: 1、首先我们用java实现:

public class Solution{
	public boolean isNumeric(char []str){
		if (str == null || str.length == 0) {
            return false;
        }
        if (str.length == 1) {
            return str[0] >= '0' && str[0] <= '9';
        }
 
        boolean hasDot = false;
        boolean hasE = false;
        boolean hasSign = false;
 
        for (int i = 0; i < str.length; i++) {
            if (str[i] == '+' || str[i] == '-') {
                
                if (hasSign && str[i - 1] != 'e' && str[i - 1] != 'E') return false;
                
                if (!hasSign && i > 0 && str[i - 1] != 'e' && str[i - 1] != 'E') return false;
                hasSign = true;
            } else if (str[i] == '.') {
                
                if (hasDot || hasE) return false;
                hasDot = true;
            } else if (str[i] == 'e' || str[i] == 'E') {
                
                if (i == str.length -1) return false;
               
                if (hasE) return false;
                hasE = true;
                
            } else if (str[i] < '0' || str[i] > '9') {
                return false;
            }
        }
        return true;
	}
}

代码效果图如图所示:

2、接下来我们可以用python实现:

class Solution:
	def isNumeric(self, s):
		sign, decimal, hasE = False, False, False
		for i in range(0, len(s)):
			if s[i] in ['e', 'E']:
				if i == len(s) - 1 or hasE:
					return False
				hasE = True
			elif s[i] == '.':
				if hasE or decimal:
					return False
				decimal = True
			elif s[i] in ['+', '-']:
				if not sign and i >0  and s[i - 1] not in ['e', 'E']:
					return False
				if sign and s[i - 1] not in ['e', 'E']:
					return False
			else:
				if s[i] < '0' or s[i] > '9':
					return False
		return True

代码效果图如图所示:

思路三:   其实可以利用python中的异常进行判断,使用float类型转换函数,出错就捕获错误,返回False,接下来我们用python将其实现:

class Solution:
	def isNumeric(self, s):
		try:
			ss = float(s)
			return True
		except:
			return False

代码效果图如图所示:

思路四:   其实有一种最简单的算法,什么方法也不用考虑,直接定义两个标志位,分别表示E或者e是否出现过,以及小数点.是否出现过。具体而言:1. 以e(或E)为分隔,获得两个子字符串;e之前的字符串小数点只能出现一次;e之后的字符串不允许出现小数点; 2. 符号位+或-只可能出现在两个子字符串的首位;3. e(或E)、小数点.不能出现在末尾。我们用python将其实现:

class Solution:
	def isNumeric(self, s):
		isAllowDot = True
		isAllowE = True
		for i in range(len(s)):
			if s[i] in "+-" and (i == 0 or s[i - 1] in "eE") and i < len(s) - 1:
				continue
			elif isAllowDot and s[i] == '.':
				isAllowDot = False
				if i >= len(s) - 1 or s[i + 1] not in "0123456789":
					return False
			elif isAllowE and s[i] in "Ee":
				isAllowDot = False
				isAllowE = False
				if i >= len(s) - 1 or s[i + 1] not in "0123456789+-":
					return False
			elif s[i] not in "0123456789":
				return False
		return True

代码效果图如图所示:

总结

  本题是主要通过字符串考察正则表达式的应用。我们在解题之前首先给大家介绍了正则表达式的计算,接下来给出了四种解题思路。其中的正则表达式用了python和java两种方式实现。还有就是通过其他方式进行解答。因此,我们在做题的时候,应该多次尝试各种方法,扩展自己的思维,写出优质的代码。总之,我们要继续加油,争取早日找到工作,Good Luck!!!

参考文献

[1] python3中的RE(正则表达式)-总结 [2] Java 正则表达式的用法和实例 [3] Echo_Yang7 [4] God_white [5] goddaniel [6] 白马长枪儒雅将