判断给出的字符串是否是数字
一些例子:
"0"=>true
" 0.1 "=>true
"abc"=>false
"1 b"=>false
"3e10"=>true
" 0.1 "=>true
"abc"=>false
"1 b"=>false
"3e10"=>true
class Solution {
public:
bool isNumber(const char *s) {
string str(s);
int k = str.find_first_not_of(' ');
if(str[k]=='+' || str[k]=='-')
k++;
int p=0, num1=0;
for(;str[k]>='0' && str[k]<='9' || str[k]=='.';k++)
s[k] == '.'?p++:num1++;
if(p>1 || num1<1)
return false;
if(str[k] == 'e' || str[k]=='E')
{
k++;
if(str[k] == '+' || str[k]=='-')
k++;
int num2 = 0;
for(;str[k]>='0' && str[k]<='9';k++)
num2++;
if(num2==0)
return false; } for(;str[k]==' ';k++); return str[k]=='\0';
}
};
public boolean isNumber(String s) {
return s.matches("(\\s)*([+-])?(([0-9]*\\.)?([0-9]+)|([0-9]+)(\\.[0-9]*)?)([eE][\\+-]?[0-9]+)?(\\s)*");
}
class Solution {
public:
bool isNumber(const char *s) {
int n=strlen(s);
if(s==NULL)
return false;
if(n==1&&s[0]==' ')//情形为“ ”
return false;
if(n==1&&s[0]=='.')//情形为“.”
return false;
if(n==1&&(s[0]=='e'||s[0]=='E'))//情形为“e”
return false;
bool ee=false;//是否出现过‘e’
bool point=false;//是否出现过.
bool nums=false;//是否出现过数字
bool mark=false;//在e前出现的正负号
bool mark1=false;//在e后出现的正负号
int i=0;
while(s[i]!='\0'){
if(s[i]=='-'||s[i]=='+'||s[i]=='e'||s[i]=='E'||s[i]=='.'||(s[i]>='0'&&s[i]<='9')||s[i]==' '){
if(s[i]=='-'||s[i]=='+'){
if(ee==true){//如果实在e后出现的正负号
if(mark1==false){
mark1=true;
int j=i+1;
if(j>=n||!(s[j]>='0'&&s[j]<='9'))//e+/e-
return false;
}
else
return false;//e后正负号多次出现
}
else{//e前出现的正负号
if(nums==true||point==true)//8+/.+
return false;
else{
if(mark==true)//如果e前正负号出现多次
return false;
else
mark=true;
}
}
}
if(s[i]==' '){
if(nums==false&&ee==false&&point==false&&mark==false);
else{//如果在中间位置出现‘ ’
int j=i+1;
while(j<n){
if(s[j]!=' ')
return false;
j++;
}
}
}
if(s[i]=='.'){
if(ee==false){
if(point==false){
point=true;
}
else//e前出现多个小数点
return false;
}
else//e后出现多个小数点
return false;
}
if(s[i]=='E'||s[i]=='e'){
if(ee==false){
if(i==n-1||(nums==false&&point==false)||(nums==false&&point==true))
return false;//e后出现小数点/e前没有任何信息
else
ee=true;
}
else
return false;
int j=i+1;
while(j<n){
if(s[j]==' ')
j++;
else
break;
}
if(j>=n)//e后没有数字
return false;
}
if(s[i]>='0'&&s[i]<='9')
nums=true;
i++;
}
else
return false;
}
if(nums==false&&point==true)//如果没有数字只有小数点
return false;
return true;
}
};
// 亲测本机上没问题,提交却显示错误,难道是因为我用的是Java8?
public class Solution {
public boolean isNumber(String s) {
if (s.charAt(s.length()-1) > '9' || s.charAt(s.length()-1) < '0') return false;
try {
Double.valueOf(s);
} catch (Exception e) {
return false;
}
return true;
}
}
class Solution {
public:
bool isNumber(const char *s)
{
string str(s);
int index = str.find_first_not_of(' ');
if(str[index] == '+' || str[index] == '-')
index++;
int points = 0,numbers = 0;
for(;str[index]>='0' && str[index]<='9' || str[index]=='.';index++)
s[index] == '.' ? ++points : ++ numbers;
if(points>1 || numbers<1)
return false;
if(str[index] == 'e' || str[index] == 'E')
{
index++;
if(str[index] == '+' || str[index] == '-')
index++;
int afterE =0;
for(;str[index]>='0' && str[index]<='9';index++)
afterE++;
if(afterE<1)
return false;
}
for(;str[index]==' ';index++){}
return str[index]=='\0';
}
};
public class Solution {
public boolean isNumber(String s) {
try {
Double valueOf = Double.valueOf(s);
//排除Double类对特殊的末尾字符为F(f)或D(d)的处理,其他如果不是数字类型,则catch!
if(s.indexOf("f")>-1 || s.indexOf("F")>-1 || s.indexOf("d")>-1 || s.indexOf("D")>-1){
return false;
}
return true;
} catch (Exception e) {
return false;
}
}
}
class Solution {
public:
bool isNumber(const char *s) {
enum InputType {
INVALID, SPACE, SIGN, DOT, E, DIGIT, LEN
};
int trans[][LEN] = {
{-1, 0, 1, 2, -1, 3},
{-1, -1, -1, 2, -1, 3},
{-1, -1, -1, -1, -1, 4},
{-1, 5, -1, 4, 6, 3},
{-1, 5, -1, -1, 6, 4},
{-1, 5, -1, -1, -1, -1},
{-1, -1, 7, -1, -1, 8},
{-1, -1, -1, -1, -1, 8},
{-1, 5, -1, -1, -1, 8}
};
int state = 0;
while (*s) {
InputType input;
if (isspace(*s)) {
input = SPACE;
} else if (*s == '+' || *s == '-') {
input = SIGN;
} else if (*s == '.') {
input = DOT;
} else if (*s == 'e' || *s == 'E') {
input = E;
} else if (isdigit(*s)) {
input = DIGIT;
} else {
input = INVALID;
}
state = trans[state][input];
if (state == -1) {
return false;
}
s++;
}
return state == 3 || state == 4 || state == 5 || state == 8;
}
};
class Solution {
public:
bool isNumber(const char *str) {
int zhuang[9][6]={{-1,0,1,2,-1,3},
{-1,-1,-1,2,-1,3},
{-1,-1,-1,-1,-1,4},
{-1,5,-1,4,6,3},
{-1,5,-1,-1,6,4},
{-1,5,-1,-1,-1,-1},
{-1,-1,7,-1,-1,8},
{-1,-1,-1,-1,-1,8},
{-1,5,-1,-1,-1,8}},i,zhuangtai=0,jieshou;
for(i=0;str[i]!='\0';i++)
{
if(str[i]==' ')
jieshou=1;
else if(str[i]=='.')
jieshou=3;
else if('0'<=str[i]&&str[i]<='9')
jieshou=5;
else if(str[i]=='+'||str[i]=='-')
jieshou=2;
else if(str[i]=='e')
jieshou=4;
else
jieshou=0;
zhuangtai=zhuang[zhuangtai][jieshou];
if(zhuangtai==-1)
return false;
}
if(zhuangtai==3||zhuangtai==4||zhuangtai==5||zhuangtai==8)
return true;
else
return false;
}
};
/*
*
* 发现解答很多都用了一些小技巧,比如正则,或者NumberFormatException
* 实际上这些解法都调用库函数,个人觉得不是出题者的真正意图
*
*
* Runtime: 3 ms.Your runtime beats 83.72 % of java submissions.
* 思路:这道题关键是分析所有会出现的情况。以及设置关键的flag来记录各种情况
* 首先使用trim()函数去除前后空格。
* 设置4个标志,分别是
* boolean pointSeen = false;//是否出现过小数点“.”
* boolean eSeen =alse;//是否出现过指数标志“e”
* boolean numberSeen = false;//是否出现过数字
* booleannumberAfterE = true;//e后面是否有数字
* 进行循环s.charAt(i):
* 1.如果属于[0,9],把numberSeen设为true
* 2.如果是‘.’,必须之前没有遇到'.'和'e'
* 3.如果是'e',必须之前没有遇到过'e'
* 4.如果是'+'或者'-',当前i必须是0,或者i-1上的字符是e
* 5.其他情况返回false
*/
public boolean isNumber(String s) {
s = s.trim();
if (s == null || s.length() == 0)
return false;
// 记录是否出现过数字
boolean numberSeen = false;
// 是否出现过小数点
boolean pointSeen = false;
// 是否出现过指数标志e
boolean eSeen = false;
// e后是否出现过数字
boolean numberAfterE = false;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
// 如果是数字
if (c >= '0' && c <= '9') {
numberSeen = true;
numberAfterE = true;
// 如果是小数点
} else if (c == '.') {
if (pointSeen || eSeen)
return false;
pointSeen = true;
// 如果是e,必须没有出现过且出现过数字
} else if (c == 'e') {
if (eSeen || !numberSeen)
return false;
eSeen = true;
numberAfterE = false;
// 如果出现正负号,必须是首位,或者前一位是e
} else if (c == '+' || c == '-') {
if (i != 0 && s.charAt(i - 1) != 'e')
return false;
} else
return false;
}
return numberSeen && numberAfterE;
}
这道题目有点类似于atoi(将字符串转化为整数),回想一下atoi:如果第一个非空格字符不存在或者不是数字也不是正负号则返回零,否则开始做类型转换,之后检测到非数字(包括结束符 \0) 字符时停止转换,返回整型数。
这道题目里面我们采取以下步骤:
如果是科学计数法,需要符合:
具体的实现方案:
help函数,它会返回三个可能的值,0表示非数字,1表示整数,2表示小数 代码如下:
//
// Created by jt on 2020/9/26.
//
class Solution {
public:
bool isNumber(const char *s) {
// 判断是否含有e
const char *p = s;
while (*p) {
if (*p == 'e') break;
++p;
}
if (*p) {
// 如果含有e,先判断e的前后是否有空格
if (p-1 >= s && *(p-1) != ' ' && *(p+1) && *(p+1) != ' ')
return help(s, p) > 0 && help(p+1, nullptr) == 1;
else
return false;
}
return help(s, nullptr) > 0;
}
int help(const char *s, const char *end) {
// 返回0表示非数字 返回1表示整数 返回2表示小数
if (s == end) return 0;
// 忽略前置空格
while (*s == ' ') ++s;
// 如果只有空格
if (!(*s)) return 0;
// 记录正负号和句点
bool hasSign = false, hasDot = false, hasNum = false;
if (*s == '+' || *s == '-') { hasSign = true; ++s; }
while (*s && *s != ' ' && s != end) {
if (hasSign && (*s == '+' || *s == '-')) return 0;
if (hasDot && *s == '.') return 0;
if (*s == '.') { hasDot = true; ++s; continue; }
if (*s < '0' || *s > '9') return 0;
hasNum = true;
++s;
}
// 忽略后置空格
while (*s && s != end) {
if (*s != ' ') return 0;
++s;
}
if (hasNum && !hasDot) return 1;
if (hasNum && hasDot) return 2;
return 0;
}
};
class Solution {
public:
bool isNumber(const char *s)
{
int i,start=1,a[2]={0,0},loc[2]={0,0},k1=0,k2=0;
vector<int>n;
if(s=="")
return false;
for(i=0;i<strlen(s);i++)
{
if(s[i]!=' ')
{
start=i+1;
break;
}
}
if(s[start-1]=='+'||s[start-1]=='-')
{
start++;
n.push_back(0);
}
for(i=start-1;i<strlen(s);i++)
{
if(s[i]<'0'||s[i]>'9')
{
if(s[i]=='.')
{
if(i!=strlen(s)-1&&(s[i+1]>'9'||s[i+1]<'0')&&s[i+1]!=' ')
if(s[i+1]!='e'&&s[i+1]!='E')
return false;
else if(k2==0)
return false;
a[0]++;
loc[0]=i+1;
n.push_back(0);
}
else if(s[i]=='e'||s[i]=='E')
{
if(i==strlen(s)-1)
return false;
else
if(s[i+1]>'9'||s[i+1]<'0')
if(s[i+1]!='+'&&s[i+1]!='-')
return false;
else
if(i+1==strlen(s))
return false;
else
if(s[i+2]>'9'||s[i+2]<'0')
return false;
a[1]++;
loc[1]=i+1;
n.push_back(0);
}
else if(s[i]=='+'||s[i]=='-')
if(s[i-1]!='e'&&s[i-1]!='E')
return false;
else ;
else
if(s[i]==' ')
n.push_back(1);
else return false;
}
else
{
n.push_back(0);
k2=1;
}
}
if(k2==0)
return false;
if(a[0]>1||a[1]>1)
return false;
if(loc[0]>loc[1]&&loc[1]!=0)
return false;
if(start==loc[1])
return false;
for(i=0;i<n.size();i++)
{
if(n[i]==0)
if(k1==0||k1==1)
k1=1;
else
return false;
else
if(k1==1)
k1=2;
}
if(k1==0)
return false;
return true;
}
}; 太多陷阱了。。。。眼睛快瞎了,用最笨的办法,今天不想改进了
/*
* 目的:判断一个字符是否是数字
* 参考:剑指offer-20
*/
bool scanUInt(const char**str){
const char* before = *str;
while(**str!='\0' && **str>='0' && **str<='9')
++(*str);
return *str>before;
}
bool scanInt(const char**str){
while(**str=='+' || **str=='-')
++(*str);
return scanUInt(str);
}
bool isNumber(const char *s) {
if (s == nullptr)
return false;
while(*s==' ')
s++;
bool numeric = scanInt(&s);
if (*s == '.'){
s++;
numeric=scanUInt(&s)||numeric;
}
if (*s == 'e' || *s=='E'){
s++;
numeric=numeric&&scanInt(&s);
}
while(*s==' ')
s++;
return numeric && *s=='\0';
}
class Solution {
public:
bool isNumber(const char *s) {
bool numberSeen = false;
bool eSeen = false;
bool numberAfterE = false;
bool pointSeen = false;
int start = 0;
int end = strlen(s) - 1;
while (start < strlen(s)) {
if (s[start] != ' ') {
break;
}
start++;
}
while (end >= 0) {
if (s[end] != ' ') {
break;
}
end--;
}
for (int i = start;i <= end;i++) {
char c = s[i];
if (c >= '0' && c <= '9') {
numberSeen = true;
numberAfterE = true;
} else if (c == '.') {
if (pointSeen || eSeen) {
return false;
}
pointSeen = true;
} else if (c == 'e' || c == 'E') {
if (eSeen || !numberSeen) {
return false;
}
eSeen = true;
numberAfterE = false;
} else if (c == '+' || c == '-') {
if (i != start && (s[i - 1] != 'e' && s[i - 1] != 'E')) {
return false;
}
} else {
return false;
}
}
return numberSeen && numberAfterE;
}
}; bool isNumber(const char *s) {
string ss(s);
trim(ss);
bool numsign = 0;
bool pointsign = 0;
bool esign = 0;
bool numafte = 0;
int len = ss.size();
for(int i=0;i<len;++i){
if(ss[i]>='0'&&ss[i]<='9'){
numsign = 1;
numafte = 1;
}else if(ss[i] == '.'){
if(pointsign||esign)return false;
pointsign = 1;
}else if(ss[i]=='e'){
if(esign||!numsign)return false;
esign = 1;
numafte = 0;
}else if(ss[i]=='+'||ss[i]=='-'){
if(i!=0&&ss[i-1]!='e')return false;
}
else return false;
}
return numsign&&numafte;
}
void trim(string &s){
if(!s.empty()){
s.erase(0,s.find_first_not_of(' '));
s.erase(s.find_last_not_of(' ')+1);
}
} bool isNumber(const char *s) {
// 需要考虑情况:
// 非e的字母,是否有e,是否有小数点,
// 是否为负数,e的指数是否为负数
string str(s);
// 先将首尾的空格去掉
while (str.length() > 0 && str[0] == ' ') str = str.substr(1);
while (str.length() > 0 && str[str.length() - 1] == ' ') str = str.substr(0, str.length() - 1);
if (str.length() == 0) return false;
bool hasE = false, isDecimal = false, isSign = false, isESign = false;
for (int i = 0; i < str.length(); i ++) {
char c = str[i];
if (c == '-' || c == '+') {
// 当前数字没有正负号,后面必须为数字或'.'
if (!isSign && i == 0 && i < str.length() - 1 && (str[i + 1] >= '0' && str[i + 1] <= '9') || str[i + 1] == '.') isSign = true;
// 为e或E的符号,必须在e或E的后面,且e或E的后面没有过符号,且+/-不在字符串的最后一个
else if (hasE && i > 0 && (str[i - 1] == 'e' || str[i - 1] == 'E') && !isESign && i != str.length() - 1) isESign = true;
else return false;
} else if (c == '.') {
// 没有过.,且没有过e或者E,'.'的前面或者后面需有数字
if (!hasE && !isDecimal && ((i != 0 && str[i - 1] >= '0' && str[i - 1] <= '9') || (i + 1 <= str.length() - 1 && str[i + 1] >= '0' && str[i + 1] <= '9'))) isDecimal = true;
else return false;
} else if (c == 'e' || c == 'E') {
// 没有过e或者E,前面需要是数字或者'.'
if (!hasE && i != 0 && ((str[i - 1] >= '0' && str[i - 1] <= '9') || str[i - 1] == '.') && i != str.length() - 1) hasE = true;
else return false;
} else if (c < '0' || c > '9') {
return false;
}
}
return true;
}
//数字由三部分组成:整数部分,小数部分,指数部分
//注意数字里面含有空格
//数值的字符串遵循模式A[.[B]][e|EC]或者.B[e|EC]
class Solution {
private:
int pos=0;
public:
bool isNumber(const char *s) {
if(s==nullptr)
return false;
while(s[pos]==' ')
pos++;
//判断整数部分
bool numeric=scanInteger(s);
//判断小数部分
if(s[pos]=='.'){
pos++;
//小数可以没有整数部分:.123
//小数点后面可以没有数字:123.
//小数点前面和后面可以都有数字:123.4
numeric=scanUnsignedInteger(s)||numeric;//注意||符号两边的顺序,必须保证scanUnsignedInteger(s)执行
}
//判断指数部分
if(s[pos]=='e'||s[pos]=='E'){
pos++;
//当e|E前面没有数字时,整个字符串不能表示数字:.e1
//当e|E后面没有整数时,整个字符串不能表示数字:12e、12e+5.4
numeric=numeric&&scanInteger(s);
}
//忽略掉三种情况后字符串后面的空格
while(s[pos]==' ')
pos++;
return numeric&&s[pos]=='\0';//保证三种情况后,字符串位于末尾
}
bool scanUnsignedInteger(string s){
int temp=pos;
while(s[pos]>='0'&&s[pos]<='9')
pos++;
return pos>temp;//如果pos>temp,表示含有数字
}
bool scanInteger(string s){
if(s[pos]=='+'||s[pos]=='-')
pos++;
return scanUnsignedInteger(s);
}
};