RT,面试题,给定一个字符串判断是否为科学计数法的有效数字。此题各种繁琐考虑。今天终于学会了用有限状态机来处理。理解之后简洁易懂。在此分享我的理解推导思路,大有收获啊

网上有解法说先记录每个状态代表的意思,然后根据状态的可能转移写出转移矩阵。但是,你肯定是一头雾水,状态数一多,就混乱不堪,根本很难有耐心或者细心把状态数清楚并记录正确。

现在我带你怎么较好的理解,最后发现我们最后可以根本不用知道每个状态时什么意思,只是按照填写规范写完即可。

首先我们要知道,每次的输入有六种可能,分别是 无效字符invalid,空格space,正负号sign,数字digit,点dot,指数e或者E暂且记作eE

那么第一次当然就是从状态0开始,状态0中之后的各种转移记录如下:

状态0:

如果来一个invalid,那么下次转移-1;(-1就是没有这个状态,那么就返回false)

如果来一个space,那么还是和当前状态0一样的状态,所以转移至0;

如果来一个sign,那么就要转移出去了,但是我们现在不知道有什么状态可以供它转移,先放着

如果来一个digit,那么也要继续转移,但是还是不知道可以转到哪里,又放着

如果来一个dot,同样要转移,因为(.0)也是合法数字,但是还是不知道有什么状态可以转,放着

如果来一个eE,一开始就是eE,就是不合法了,因为eE前面一定要有数字,所以这个时候确定转移至-1,也就是要false了。

我们用图来标记如下:

状态0:

invalid -> -1

space -> 0

sign -> ?    ----->   之后考虑状态1后就变为    sign -> 1

digit -> ?   ----->   之后考虑状态2后就变为    digit -> 2

dot -> ?    ------>  之后考虑状态3后就变为     dot -> 3

eE -> -1

因为上面有问号存在,所以我们要创建新的状态让问号有归处,直至所有的状态都有归处了就完成了。所以我们先给sign->?这个问号一个状态1,那么状态1就是指它是从+-号过来的所以有:

状态1:(之前是正负符号)

invalid -> -1 // 无效字符肯定就是-1

space -> -1 // 正负号接空格肯定也不符合了,果断-1

sign -> -1 // 符号后不能有符号,-1

digit -> ? // 正负号加一个数字是可以继续转移的

dot -> ? // 正负号加点也是可以继续转移的

eE -> -1 // 正负号直接加指数eE是非法的,-1

到此,虽然状态1也还有问号,但是我们在状态0中的sign的问号就可以用红色部分代替了。

同理,现在我们要考虑状态1中digit->?的问号,给它一个状态2,那么状态2就是指之前是一个普通数字转过来的,普通是指之前没有点,没有eE。那么状态2可以表示为:

状态2:(之前是普通数字)

invalid -> -1 // 无效字符肯定就是-1

space -> ? // 之前是数字,因为以空格结尾是合法的所以要跳转,但是我们还没有这个状态,先放着

sign -> -1 // 数字后不能有符号,-1

digit -> 2 // 数字之后还是数字,那么这个还是普通数字,所以转移到本身,记录为2,如果此处终止,那肯定是合法的

dot -> ? // 数字之后是点,那么可以继续转移

eE -> ? // 数字之后加eE要继续转移,因为可能合法。

到此我们知道如果最后状态停留在2,那就是合法的。因为能跳到2的只有之前是合法的普通数字。并且状态0中的问号也可以更新了,见状态0中紫色部分的更新。

我们根据一个状态一个状态完成问号的顺序来进行,那么接下去就是给状态0的dot -> 3,那么状态3是

状态3:(之前是点跳过来的)

invalid -> -1 // 无效字符肯定就是-1

space -> -1 // 点之后空格则无效

sign -> -1 // 点之后符号也无效

digit -> ? // 点之后数字,那么要跳转

dot -> -1 // 点之后点无效

eE -> -1 // 只有一个点之后指数无效,如果是数字加点再加指数才有效,但这里只有点所以无效。

现在,状态0就大功告成啦。

状态0:

invalid -> -1

space -> 0

sign -> 1

digit -> 2

dot -> 3

eE -> -1

亲,到这里,你应该会类推从状态1的问号开始解决了吧。拿张纸出来画一画。

上传一张我画的:

中间在状态2的时候跳转错了一个,调试代码之后才改的,所以你的状态可能会和我的不一样,但是只要能AC就对了。打勾的说明如果在那个状态结束那么就是合法的数字。否则就非法。

代码如下:

class Solution {
public:
bool isNumber(const char*s)
{
enum InputType
{
invalid, space, sign, digit, dot, eE, len
};
int trans[][len] =
{
-, , , , ,-,
-,-,-, , ,-,
-, ,-, , , ,
-,-,-, ,-,-,
-, ,-,-,-,-,
-,-, , ,-,-,
-, ,-, ,-, ,
-,-,-, ,-,-,
-, ,-, ,-,-,
};
int state = ;
while(*s!='\0')
{
InputType inputType = invalid;
if(*s == ' ')
inputType = space;
else if(*s == '+' || *s == '-')
inputType = sign;
else if(isdigit(*s))
inputType = digit;
else if(*s == '.')
inputType = dot;
else if(*s == 'e' || *s == 'E')
inputType = eE;
state = trans[state][inputType];
if (state == -)
return false;
s++;
}
return state== || state== || state== || state==;
}
};

写完之后还找了另一种方法,是正则表达式的,有兴趣的可以去看看

valid number 判断字符串是否为有效数字的更多相关文章

  1. 65. Valid Number 判断字符串是不是数字

    [抄题]: Validate if a given string is numeric. Some examples:"0" => true" 0.1 " ...

  2. Valid Number,判断是否为合法数字

    问题描述: Validate if a given string is numeric. Some examples:"0" => true" 0.1 " ...

  3. [Swift]LeetCode65. 有效数字 | Valid Number

    Validate if a given string is numeric. Some examples:"0" => true" 0.1 " => ...

  4. leetCode 65.Valid Number (有效数字)

    Valid Number  Validate if a given string is numeric. Some examples: "0" => true " ...

  5. Leetcode 65 Valid Number 字符串处理

    由于老是更新简单题,我已经醉了,所以今天直接上一道通过率最低的题. 题意:判断字符串是否是一个合法的数字 定义有符号的数字是(n),无符号的数字是(un),有符号的兼容无符号的 合法的数字只有下列几种 ...

  6. SQL判断字符串里不包含字母

    Oracle: 方法一:通过To_Number 函数异常来判断,因为这个函数在转换不成功的时候是报错,所以只能用存储过程包装起来. CREATE OR REPLACE FUNCTION Is_Numb ...

  7. shell 判断字符串是否为数字

    本篇文章主要介绍了"shell 判断字符串是否为数字",主要涉及到shell 判断字符串是否为数字方面的内容,对于shell 判断字符串是否为数字感兴趣的同学可以参考一下. #!/ ...

  8. Oracle中如何判断字符串是否全为数字,以及从任意字符串中提取数字

    本文介绍了判断字符串是否全为数字的4种办法,另外还介绍了一个translate函数的小技巧,从任意字符串中提取数字(调用2次translate函数).这个办法是一个公司同事发现的,用起来很方便,但理解 ...

  9. js判断字符串是否全为空(使用trim函数/正则表达式)

    我们需要判断用户输入的是否全是空格,可以使用以下方法: 方法一: 使用trim() /* 使用String.trim()函数,来判断字符串是否全为空*/ function kongge1(test) ...

随机推荐

  1. Maven构建Hadoop

    Maven构建Hadoop工程 阅读目录 序 Maven 安装 构建 示例下载 系列索引 序 上一篇,我们编写了第一个MapReduce,并且成功的运行了Job,Hadoop1.x是通过ant来管理工 ...

  2. USACO maze1 BFS

    不写了很长的时间bfs该,很长一段时间的中间失误,当延期一次延伸成功的新节点的节点应该被标记为参观.否则,在某些情况下无限期延长队列. 输入一个小坑爹处理称号,能够进来当字符串被读取.然后用周围的墙上 ...

  3. 观察者模式(observer行为)c#简单的例子

    观察者模式(observer行为)c#简单的例子 几点:模式使观察目标和实现松耦合之间的依赖关系.通知会传播自己主动 样本:玩家击中后发生一系列变化的敌人:后发爆炸.敌人少1一个.... namesp ...

  4. eclipse 中 Android sdk 无法更新的问题

    诶,真是麻烦,想下个东西都下不了. 我也好久没折腾过这个了,在家的电脑是早就下载好了的,然后如今又须要下载一份.下不到.网上搜到了资料,记录下来: 第一种方法:       sdk manager - ...

  5. 获得span里面价值(在特殊情况下 )

    如何获得A? <div class="warpper"> <span class="content"> A <span>12 ...

  6. Redis源代码分析(二十)--- ae事件驱动

    事件驱动的术语出现更频繁.听起来非常大的,今天我把Redis内部驱动器模型来研究它,奖励的感觉啊.一个ae.c主程序,加4文件的事件类型,让你彻底弄清楚,Redis是怎样处理这些事件的. 在Redis ...

  7. NSIS:使用nsWindows.nsh头文件调整窗体大小

    原文 NSIS:使用nsWindows.nsh头文件调整窗体大小 此方法只能简单实现调整窗体大小,但不完美,调整后窗体上其他的控件都需要调整大小或位置,比较麻烦,轻狂不建议使用呵! ;加头文件!inc ...

  8. UVALive - 3263 That Nice Euler Circuit (几何)

    UVALive - 3263 That Nice Euler Circuit (几何) ACM 题目地址:  UVALive - 3263 That Nice Euler Circuit 题意:  给 ...

  9. Android清除缓存功能来实现

    我们都知道在Android的设置->应用程序中能够查看应用程序的相关信息,当中有一个功能是清除缓存. 如图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZ ...

  10. Linux内核分析(六)----字符设备控制方法实现|揭秘系统调用本质

    原文:Linux内核分析(六)----字符设备控制方法实现|揭秘系统调用本质 Linux内核分析(六) 昨天我们对字符设备进行了初步的了解,并且实现了简单的字符设备驱动,今天我们继续对字符设备的某些方 ...