溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++怎么實現驗證數字

發(fā)布時間:2022-03-28 10:27:18 來源:億速云 閱讀:224 作者:iii 欄目:大數據

本篇內容介紹了“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:

  • Numbers 0-9

  • Exponent - "e"

  • Positive/negative sign - "+"/"-"

  • Decimal point - "."

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;
    }
};

上面的寫法略為復雜,我們嘗試著來優(yōu)化一下,根據上面的分析,所有的字符可以分為六大類,空格,符號,數字,小數點,自然底數和其他字符,我們需要五個標志變量,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"; // True
string s2 = " 0.1 "; // True
string s3 = "abc"; // False
string s4 = "1 a"; // False
string s5 = "2e10"; // True

string s6 = "-e10"; // False
string s7 = " 2e-9 "; // True
string s8 = "+e1"; // False
string s9 = "1+e"; // False
string s10 = " "; // False

string s11 = "e9"; // False
string s12 = "4e+"; // False
string s13 = " -."; // False
string s14 = "+.8"; // True
string s15 = " 005047e+6"; // True

string s16 = ".e1"; // False
string s17 = "3.e"; // False
string s18 = "3.e1"; // True
string s19 = "+1.e+5"; // True
string s20 = " -54.53061"; // True

string s21 = ". 1"; // False

“C++怎么實現驗證數字”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

c++
AI