昨天在刷力扣编程算法题,在做完“字符串转换整数”后,系统推荐“有效数字”,于是便进行尝试。题目描述如下:
题目上说“有意将问题陈述地比较模糊,在实现代码之前,你应当事先思考所有可能的情况”,于是推测的信息大致如下:
1、字符串必须是合法有效数字;
2、在数字前后可以有多个空格,但中间不能有空格;
3、可以是小数;
4、可以支持16进制(根据2e10)推测来的;
于是便根据这个需求来写,写完后,执行代码,顺利通过,但提交代码出错,经过多次修改,多次提交,总是出错。
记得几个比较奇葩的错误:
1、e,预期结果是false
2、e9,预期结果是false;
3、b912,预期结果是false;
这时候就纳闷了,此时就想看官方解题,但官方比没有给出解题。于是,便查看评论,打开评论一看,真的是怨声满天,大家都是按照十六进制去做,自然是各种过不了。
在评论中,有人贴出来原版的题目:
这一看就明白多了,原来e是指数幂,不是十六进制。
今天一大早,按照最新的题目理解,进行编码,在经过一番斗争后,终于出了第一版,但在提交过程中,也总会遇到各种错误,主要集中在以下:
1、“1.”预期结果是true;
2、“ -.1”预期结果是true;
2、“ -.1e+13”预期结果是true;
大致的问题点在于小数点、正负号、e指数幂等的存在和位置的关系逻辑处理。
经过多次修改和提交,终于顺利通过该题。如下:
开心之余,便贴出实现代码,应该还有优化空间,不过实在懒得再进行优化了。
bool isNumber(char* s) {
int digitNum = 0;
int pointExist = 0;
int eExist = 0;
int spaceLast = 0;
int eValue = 0;
int sigExist = 0;
if (!s) {
return false;
}
while (*s != NULL) {
if (*s == ' ') {
if (sigExist) {
return false;
}
s++;
}
else if ((*s == '-') || (*s == '+')) {
if (!sigExist) {
sigExist = 1;
s++;
}
else {
return false;
}
}
else if (*s == '.') {
s++;
pointExist = 1;
break;
}
else if ((*s >= '0') && (*s <= '9')) {
break;
}
else {
return false;
}
}
if (*s == NULL) {
return false;
}
if ((*s < '0') || (*s > '9')) {
return false;
}
while (*s != NULL) {
if ((*s >= '0') && (*s <= '9')) {
s++;
digitNum++;
}
else if (*s == '.') {
if (!pointExist) {
pointExist = 1;
s++;
}
else {
return false;
}
}
else if (*s == 'e') {
eExist = 1;
digitNum = 0;
s++;
if ((*s == '-') || (*s == '+')) {
s++;
if (*s == NULL) {
return false;
}
break;
}
else if ((*s >= '0') && (*s <= '9')) {
break;
}
else {
return false;
}
}
else if (*s == ' ') {
while (*s != NULL) {
if (*s != ' ')
{
return false;
}
s++;
}
return true;
}
else {
return false;
}
}
if (*s == NULL) {
if ((pointExist == 1) && (digitNum == 0)) {
return false;
}
else {
return true;
}
}
printf("c:%c\n", *s);
if ((*s < '0') || (*s > '9')) {
return false;
}
while (*s != NULL) {
if ((*s >= '0') && (*s <= '9')) {
s++;
}
else if (*s == ' ') {
while (*s != NULL) {
if (*s != ' ')
{
return false;
}
s++;
}
return true;
}
else {
return false;
}
}
return true;
}