文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

C++怎么实现验证数字

2023-06-19 13:18

关注

本篇内容介绍了“C++怎么实现验证数字”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

Valid Number 验证数字

Validate if a given string can be interpreted as a decimal number.

Some examples:
"0" => true
" 0.1 " => true
"abc" => false
"1 a" => false
"2e10" => true
" -90e3   " => true
" 1e" => false
"e3" => false
" 6e-1" => true
" 99e2.5 " => false
"53.5e93" => true
" --6 " => false
"-+3" => false
"95a54e53" => false

Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one. However, here is a list of characters that can be in a valid decimal number:

Of course, the context of these characters also matters in the input.

Update (2015-02-10):
The signature of the C++ function had been updated. If you still see your function signature accepts a const char * argument, please click the reload button to reset your code definition.

首先,从题目中给的一些例子可以分析出来,我们所需要关注的除了数字以外的特殊字符有空格 ‘ ", 小数点 ".", 自然数 "e/E", 还要加上正负号 "+/-", 除了这些字符需要考虑意外,出现了任何其他的字符,可以马上判定不是数字。下面我们来一一分析这些出现了也可能是数字的特殊字符:

1. 空格 ‘ ": 空格分为两种情况需要考虑,一种是出现在开头和末尾的空格,一种是出现在中间的字符。出现在开头和末尾的空格不影响数字,而一旦中间出现了空格,则立马不是数字。解决方法:预处理时去掉字符的首位空格,中间再检测到空格,则判定不是数字。

2. 小数点 ".":小数点需要分的情况较多,首先的是小数点只能出现一次,但是小数点可以出现在任何位置,开头(".3"), 中间("1.e2"), 以及结尾("1." ), 而且需要注意的是,小数点不能出现在自然数 "e/E" 之后,如 "1e.1" false, "1e1.1" false。还有,当小数点位于末尾时,前面必须是数字,如 "1."  true," -." false。解决方法:开头中间结尾三个位置分开讨论情况。

3. 自然数 "e/E":自然数的前后必须有数字,即自然数不能出现在开头和结尾,如 "e" false,  ".e1" false, "3.e" false, "3.e1" true。而且小数点只能出现在自然数之前,还有就是自然数前面不能是符号,如 "+e1" false, "1+e" false. 解决方法:开头中间结尾三个位置分开讨论情况。

4. 正负号 "+/-",正负号可以再开头出现,可以再自然数e之后出现,但不能是最后一个字符,后面得有数字,如  "+1.e+5" true。解决方法:开头中间结尾三个位置分开讨论情况。

下面我们开始正式分开头中间结尾三个位置来讨论情况:

1. 在讨论三个位置之前做预处理,去掉字符串首尾的空格,可以采用两个指针分别指向开头和结尾,遇到空格则跳过,分别指向开头结尾非空格的字符。

2. 对首字符处理,首字符只能为数字或者正负号 "+/-",我们需要定义三个flag在标示我们是否之前检测到过小数点,自然数和正负号。首字符如为数字或正负号,则标记对应的flag,若不是,直接返回false。

3. 对中间字符的处理,中间字符会出现五种情况,数字,小数点,自然数,正负号和其他字符。

若是数字,标记flag并通过。

若是自然数,则必须是第一次出现自然数,并且前一个字符不能是正负号,而且之前一定要出现过数字,才能标记flag通过。

若是正负号,则之前的字符必须是自然数e,才能标记flag通过。

若是小数点,则必须是第一次出现小数点并且自然数没有出现过,才能标记flag通过。

若是其他,返回false。

4. 对尾字符处理,最后一个字符只能是数字或小数点,其他字符都返回false。

若是数字,返回true。

若是小数点,则必须是第一次出现小数点并且自然数没有出现过,还有前面必须是数字,才能返回true。

解法一:

class Solution {public:    bool isNumber(string s) {        int len = s.size();        int left = 0, right = len - 1;        bool eExisted = false;        bool dotExisted = false;        bool digitExisited = false;        // Delete spaces in the front and end of string        while (s[left] == " ") ++left;        while (s[right] == " ") --right;        // If only have one char and not digit, return false        if (left >= right && (s[left] < "0" || s[left] > "9")) return false;        //Process the first char        if (s[left] == ".") dotExisted = true;        else if (s[left] >= "0" && s[left] <= "9") digitExisited = true;        else if (s[left] != "+" && s[left] != "-") return false;        // Process the middle chars        for (int i = left + 1; i <= right - 1; ++i) {            if (s[i] >= "0" && s[i] <= "9") digitExisited = true;            else if (s[i] == "e" || s[i] == "E") { // e/E cannot follow +/-, must follow a digit                if (!eExisted && s[i - 1] != "+" && s[i - 1] != "-" && digitExisited) eExisted = true;                else return false;            } else if (s[i] == "+" || s[i] == "-") { // +/- can only follow e/E                if (s[i - 1] != "e" && s[i - 1] != "E") return false;                            } else if (s[i] == ".") { // dot can only occur once and cannot occur after e/E                if (!dotExisted && !eExisted) dotExisted = true;                else return false;            } else return false;        }        // Process the last char, it can only be digit or dot, when is dot, there should be no dot and e/E before and must follow a digit        if (s[right] >= "0" && s[right] <= "9") return true;        else if (s[right] == "." && !dotExisted && !eExisted && digitExisited) return true;        else return false;    }};

上面的写法略为复杂,我们尝试着来优化一下,根据上面的分析,所有的字符可以分为六大类,空格,符号,数字,小数点,自然底数和其他字符,我们需要五个标志变量,num, dot, exp, sign分别表示数字,小数点,自然底数和符号是否出现,numAfterE表示自然底数后面是否有数字,那么我们分别来看各种情况:

- 空格: 我们需要排除的情况是,当前位置是空格而后面一位不为空格,但是之前有数字,小数点,自然底数或者符号出现时返回false。

- 符号:符号前面如果有字符的话必须是空格或者是自然底数,标记sign为true。

- 数字:标记num和numAfterE为true。

- 小数点:如果之前出现过小数点或者自然底数,返回false,否则标记dot为true。

- 自然底数:如果之前出现过自然底数或者之前从未出现过数字,返回false,否则标记exp为true,numAfterE为false。

- 其他字符:返回false。

最后返回num && numAfterE即可。

解法二:

class Solution {public:    bool isNumber(string s) {        bool num = false, numAfterE = true, dot = false, exp = false, sign = false;        int n = s.size();        for (int i = 0; i < n; ++i) {            if (s[i] == " ") {                if (i < n - 1 && s[i + 1] != " " && (num || dot || exp || sign)) return false;            } else if (s[i] == "+" || s[i] == "-") {                if (i > 0 && s[i - 1] != "e" && s[i - 1] != " ") return false;                sign = true;            } else if (s[i] >= "0" && s[i] <= "9") {                num = true;                numAfterE = true;            } else if (s[i] == ".") {                if (dot || exp) return false;                dot = true;            } else if (s[i] == "e") {                if (exp || !num) return false;                exp = true;                numAfterE = false;            } else return false;        }        return num && numAfterE;    }};

这道题给了例子不够用,下面这些例子都是我在调试的过程中出现过的例子,用来参考:

string s1 = "0"; // Truestring s2 = " 0.1 "; // Truestring s3 = "abc"; // Falsestring s4 = "1 a"; // Falsestring s5 = "2e10"; // Truestring s6 = "-e10"; // Falsestring s7 = " 2e-9 "; // Truestring s8 = "+e1"; // Falsestring s9 = "1+e"; // Falsestring s10 = " "; // Falsestring s11 = "e9"; // Falsestring s12 = "4e+"; // Falsestring s13 = " -."; // Falsestring s14 = "+.8"; // Truestring s15 = " 005047e+6"; // Truestring s16 = ".e1"; // Falsestring s17 = "3.e"; // Falsestring s18 = "3.e1"; // Truestring s19 = "+1.e+5"; // Truestring s20 = " -54.53061"; // Truestring s21 = ". 1"; // False

“C++怎么实现验证数字”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯