注意字符串的特殊性:
1. 前后带空格
2. 空字符串
3. 带有非数字的字符串
带有非数字的字符串
- 可以带正负号例如:+3,-3,不可以+-3,
- 可以有点例如:1.3,.3,3., 不可以.,前后至少一个整数,一个数里面只能有一个点
- 可以有e例如1e3,不可以1e,e3,前后必须有数,前面可以小数,后面必须整数,后面的整数可以带符号,一个数字里面只能有一个e
- 出现其他非数字字符全是不合法字符串
处理思路:
1. 去掉首尾空格
2. 去掉空字符串
3. 去掉整个数的符号
4. 简单过滤一些字符串(根据非纯数字字符串能过滤一部分)
5. 然后根据e和点的组合情况分类讨论
根据e和点分类讨论:
- 没有e和点纯数字,肯定合法
- 有e没点 ,前后都得有数,长度最少为3
- 没e有点,前后至少一个整数,长度最少2
- 有e有点,肯定是点在前e在后,因为e后面是不能带小数的,所以先判断前面的小数是否合法,然后判断e后面有没数字,小数的长度至少为3,e后面的长度至少为1
代码:
class Solution {
public boolean isNumber(String s) {
//处理前后空格
s = s.trim();
//空串处理
if(s.equals("")) return false;
char[] c_s = s.toCharArray();
int i=0;
//先把最前面的符号去掉
if(c_s[0]=='+' || c_s[0]=='-') i++;
//5元组对应 e和dot的次序,e的数量,dot的数量,e的位置,dot的位置
int[] status = new int[] {0,0,0,-1,-1};
//第一次过滤,可以排除掉很多的没用字符串
if(check(c_s,i,status)) {
//分类讨论
//deorder==1说明dot在前
//deorder==2说明e在前
//没有e和. 纯数字
if(status[1]==0&&status[2]==0) {
return true;
}//只有e 前后都必须有数字,说明 e不能在符号位后面||不能字符串末尾
else if(status[1]==1&&status[2]==0) {
//前后都必须有数字,说明 e不能在符号位后面||不能字符串末尾
if(status[3]==i||status[3]==c_s.length-1)
return false;
return true;
}//有.没有e 前可以没有数字后面必须要有数字
else if(status[1]==0&&status[2]==1) {
//leetcode
//原本以为只有前面可以没有数字发现后面也可以
//那么当前后都没有数字肯定是错误的
//c_s.length-i就是小数的长度
//长度为1说明前后没有数字
if(c_s.length - i==1)//长度减去起始位置就是长度
return false;
return true;
}//有.有e
else {
//e在前
if(status[0]==2) {
return false;
}//dot前 //e后面没有数字 || e和dot之间没有数字 || 点前后必须要有数字
else {
//leetcode
//前面小数要合法 e_index-i就是小数的长度
//e后面要有数字
if(status[3]-i==1||status[3]==c_s.length-1)
return false;
else
return true;
}
}
}else {
return false;
}
}
// public boolean check(char[] c_s,int start,MyInt deorder,
// MyInt ee_count,MyInt dd_count,
// MyInt ee_index,MyInt dd_index) {
public boolean check(char[] c_s,int start,int[] status) {
// System.out.println(c_s);
int e_count = 0; //e的数量 最多1个
int dot_count = 0; //dot的数量 最多1个
int dot_first = 0;//dot出现的时候
int e_first = 0;//e出现的时候
int e_index = -1;//e出现的位置
int dot_index = -1;//dot出现的位置
int order = 0;//次序
int sign_count = 0;//e后面符号的个数
// int sign = -1;//符号类型 貌似没啥用
for(int i=start;i<c_s.length;i++) {
if(c_s[i]=='e') {//遇到e了
if(e_count<1) {//如果没出现过
e_index = i;
e_first = ++order;
e_count++;
}
else {//两个e 不合法
// System.out.println("1j");
return false;
}
}else if(c_s[i]=='.') {
if(dot_count<1) {//如果没出现过
dot_index = i;
dot_first = ++order;
dot_count++;
}
else {//两个. 不合法
// System.out.println("2j");
return false;
}
}else if(c_s[i]>='0'&&c_s[i]<='9') {//数字不作处理
}else if(c_s[i]=='+') {
//对e后面的符号做一次判断其实可以和负号的判断写一起
//符号是在e的后面 符号不在末尾 符号还没有出现过
if(c_s[i-1]=='e'&&c_s.length-1!=i&&sign_count<1) {
sign_count++;
// sign = 0;
}else {//前面不是e,符号在字符串末尾,符号不止一个
return false;
}
}else if(c_s[i]=='-') {
if(c_s[i-1]=='e'&&c_s.length-1!=i&&sign_count<1) {
sign_count++;
// sign = 1;
}else {
return false;
}
}
else {//除了符号,e,.,数字的字符
// System.out.println("3j");
return false;
}
}
//处理一下次序,和数量
if(dot_first==1)
status[0] = 1;
if(e_first==1)
status[0] = 2;
status[1] = e_count;
status[2] = dot_count;
status[3] = e_index;
status[4] = dot_index;
// status[5] = sign;
return true;
}
}