2020年9月2日表示数值的字符串 isNumber
class Solution {
public boolean isNumber(String s) {
}
}
解题思路:
首先,这道题必定会有很多的坑,从这20%的提交成功率上就能看出来,遇到坑没法避免的时候最好的办法就是踩一遍所有坑,踩完就可以顺利通过了。
所以现在我只是针对所有例题中的情况作出通配的计算,其他类型的暂且不管。
进过分析,第一次尝试时将这个字符串表示为
(正负号)数字(小数点)数字(E/e)(正负号)(数字)
先去学习一下正则表达式的用法。
正则表达式学回来了发现,使用正则表达式貌似没有办法解决本题中的问题,或许是我还不知道怎么使用的原因吧。我不知道如何表达,如果存在数字E,那么E后面必须有数字这种情况。
所以还是使用普通的逻辑判断来解决这道问题。
使用普通的逻辑也非常难实现,其中的逻辑非常复杂,很难使用位置来判断是否是合法数字。
在从答案中获得到了灵感,使用这一种新的实现方式。
台阶模型。
把读取这个字符串的过程理解为一个走楼梯的过程,每一层台阶有不同的前进规则。这样解释,当你站在第一层楼梯的时候,你需要读取的字符是“+”,“-”,如果读取到了,或者没有读取到,都走上下一层的台阶。
第二层台阶开始读取数字,规则是只读取数字,如果出现了“.”,则前进一级台阶,如果遇到的是“E”或者是“e”,则前进3个台阶。
当走到楼顶时,如果能够顺利结束最后一个台阶,那么返回true,只要过程中在任何一个台阶上出现了问题,都直接返回false。
???
看了半天没看出哪里有问题,结果发现在尾部插入了一个空格,我人晕了,看来还现需要把空格清零掉,再添加一个台阶来清零空格吧。
char[] step;
int index=0;
public boolean isNumber(String s) {
step = s.toCharArray();
if (step.length==0)
return false;
return step0();
}
//台阶1,判断是否是符号位
public boolean step0(){
if (step[index]=='+'||step[index]=='-')
index++;
return step1();
}
//台阶2,读取数字
public boolean step1(){
//读取数字的长度
int len=0;
while (step[index]<=57&&step[index]>=48){
len++;
index++;
//如果台阶2已经到达末尾,返回true
if (index==step.length)
return true;
}
//如果没有一个数字,存在问题,返回false
if (len==0)
return false;
//如果是小数点,进入台阶3
if (step[index]=='.')
return step3();
//如果是E,进入阶段5
if (step[index]=='E'||step[index]=='e')
return step5();
//如果不是.或者E,那么存在错误,返回false
return false;
}
//台阶3,这个阶段只有一个.
public boolean step3(){
//是否已经到达末尾,如果到达末尾返回false,不能以小数点结尾
if (index+1==step.length)
return false;
index++;
//小数点后必须是数字,进入台阶4
if (step[index]<=57&&step[index]>=48)
return step4();
else
return false;
}
//台阶4,小数点后的数字串
public boolean step4(){
//已经测试过存在数字,所以不需要判断没数字的情况
while (step[index]<=57&&step[index]>=48){
index++;
//如果台阶2已经到达末尾,返回true
if (index==step.length)
return true;
}
//如果是E,进入阶段5,台阶4中的数字结束后必须是E,否则结束
if (step[index]=='E'||step[index]=='e')
return step5();
else
return false;
}
//台阶5,是一个E
public boolean step5(){
if (index+1==step.length)
return false;
index++;
//如果是符号,进入台阶6
if (step[index]=='+'||step[index]=='-')
return step6();
//是数字进入台阶7
else if (step[index]<=57&&step[index]>=48)
return step7();
else
return false;
}
//台阶6,是一个符号
public boolean step6(){
if (index+1==step.length)
return false;
index++;
if (step[index]<=57&&step[index]>=48)
return step7();
else
return false;
}
//台阶顶部,最后一串数字串
public boolean step7(){
while (step[index]<=57&&step[index]>=48){
index++;
//如果台阶2已经到达末尾,返回true
if (index==step.length)
return true;
}
return false;
}
修改2.0版本,增加了空格处理台阶。
啊这。原来还有这种方式表示0.1的吗?长知识了。
这代码太长了,中间修改的版本就不贴了,就贴最后完成的版本吧。
我是傻逼
算你厉害,我继续改。
最终版本:
class Solution {
char[] step;
int index=0;
public boolean isNumber(String s) {
step = s.toCharArray();
if (step.length==0)
return false;
return step0();
}
//台阶1,判断是否是符号位
public boolean step0(){
while (step[index]==' '){
index++;
if (index==step.length)
return false;
}
if (step[index]=='+'||step[index]=='-')
index++;
return step1();
}
//台阶2,读取数字
public boolean step1(){
//读取数字的长度
int len=0;
while (step[index]<=57&&step[index]>=48){
len++;
index++;
//如果台阶2已经到达末尾,返回true
if (index==step.length)
return true;
}
//如果没有一个数字,存在问题,返回false
if (len==0){
if (step[index]=='.')
return step3();
else
return false;
}
//如果是小数点,进入台阶3
if (step[index]=='.')
return step3();
//如果是E,进入阶段5
if (step[index]=='E'||step[index]=='e')
return step5();
//如果不是进入空格清理
return step8();
}
//台阶3,这个阶段只有一个.
public boolean step3(){
//是否已经到达末尾,如果到达末尾返回false,不能以小数点结尾
if (index+1==step.length){
//点的前后必须都有数字
if (index-1>=0&&step[index-1]<=57&&step[index-1]>=48)
return true;
else
return step8();
}
index++;
//小数点后必须是数字,进入台阶4
if (step[index]<=57&&step[index]>=48)
return step4();
//小数点后必须是数字,进入台阶4
if (step[index]<=57&&step[index]>=48)
return step4();
else if (step[index]=='e'||step[index]=='E')
{
if (index-2>=0&&step[index-2]<=57&&step[index-2]>=48)
return step5();
else
return false;
}
//如果小数点后不是数字,那么小数点前必须是数字
else if (index-2>=0&&step[index-2]<=57&&step[index-2]>=48)
return step8();
else return false;
}
//台阶4,小数点后的数字串
public boolean step4(){
//已经测试过存在数字,所以不需要判断没数字的情况
while (step[index]<=57&&step[index]>=48){
index++;
//如果台阶2已经到达末尾,返回true
if (index==step.length)
return true;
}
//如果是E,进入阶段5,台阶4中的数字结束后必须是E,否则结束
if (step[index]=='E'||step[index]=='e')
return step5();
else
return step8();
}
//台阶5,是一个E
public boolean step5(){
if (index+1==step.length)
return false;
index++;
//如果是符号,进入台阶6
if (step[index]=='+'||step[index]=='-')
return step6();
//是数字进入台阶7
else if (step[index]<=57&&step[index]>=48)
return step7();
else
return false;
}
//台阶6,是一个符号
public boolean step6(){
if (index+1==step.length)
return false;
index++;
if (step[index]<=57&&step[index]>=48)
return step7();
else
return false;
}
//台阶顶部,最后一串数字串
public boolean step7(){
while (step[index]<=57&&step[index]>=48){
index++;
//如果台阶2已经到达末尾,返回true
if (index==step.length)
return true;
}
return step8();
}
//清理空格的台阶
public boolean step8(){
while (step[index]==' '){
index++;
if (index==step.length)
return true;
}
return false;
}
}
后话:
今天的算法题感觉很无聊,一开始的时候看到评论说这道题是垃圾题,我还非常不屑,直到我自己因为莫名其妙的原因错了有错之后,我真的觉得这道题没有什么必要,你为什么要在字符串后加空格呢?一共花了我3个小时,其中大多数时间都在测试,修改。一共提交了16次,前面15次都是因为各种原因出错,题目中也没有给出错误样例和正确的样例,以至于测试到后面我都不想贴截图了注释也懒得写。这道题做完之后我肯定能牢牢记住,double类型的字符串输入的正确格式。