詳解Java如何實(shí)現(xiàn)數(shù)值校驗(yàn)的算法
給定一個(gè)字符串如何判斷它是否為數(shù)值類(lèi)型?例如:字符串+100、5e2、-123、3.1416以及-1E-16都表示數(shù)值,為數(shù)值類(lèi)型,但12e、1a3.14、1.2.3、+-5以及12e+5.4都不是。
本文將帶著大家實(shí)現(xiàn)這個(gè)判斷算法,歡迎各位感興趣的開(kāi)發(fā)者閱讀本文。
實(shí)現(xiàn)思路
我們先來(lái)看一下數(shù)值的定義規(guī)則:表示數(shù)值的字符串遵循模式A[.[B]][e|EC]或者.B[e|EC],其中:
- A為數(shù)值的整數(shù)部分
- B緊跟著小數(shù)點(diǎn)為數(shù)值的小數(shù)部分
- C緊跟著e或者E為數(shù)值的指數(shù)部分
在小數(shù)里可能沒(méi)有數(shù)值的整數(shù)部分,例如:小數(shù).123等于0.123。因此A部分不是必須的,如果一個(gè)數(shù)沒(méi)有整數(shù)部分,那么它的小數(shù)部分不能為空。
上述A和C都是可能以+或者-開(kāi)頭的0~9的數(shù)位串;B也是0~9的數(shù)位串,但前面不能有正負(fù)號(hào)。我們以字符串123.45e+6為例,其中:
- 123是它的整數(shù)部分A
- 45是它的小數(shù)部分B
- +6是它的指數(shù)部分C
判斷一個(gè)字符串是否符合上述模式時(shí),首先盡可能多地掃描0~9的數(shù)位(有可能起始處有+或者-),也就是前面模式中表示數(shù)值整數(shù)的A部分。如果遇到小數(shù)點(diǎn).,則開(kāi)始掃描表述數(shù)值小數(shù)部分的B部分。如果遇到e或者E,則開(kāi)始掃描表示數(shù)值指數(shù)的C部分。
我們將上面所述整理下,就能列出實(shí)現(xiàn)思路了,如下所示:
(1) 在字符串后添加結(jié)束標(biāo)志;
(2) 使用全局索引遍歷字符串;
(3) 設(shè)計(jì)一個(gè)函數(shù)用來(lái)掃描無(wú)符號(hào)整數(shù)(字符串中0~9的數(shù)位),用來(lái)判斷數(shù)值模式中的B部分;
(4) 設(shè)計(jì)一個(gè)函數(shù)用來(lái)掃描可以表示正負(fù)的+或者-為起始的0~9的數(shù)位(類(lèi)似于一個(gè)可能帶正負(fù)符號(hào)的整數(shù)),用來(lái)判斷數(shù)值模式中的A和C部分;
(5) 從頭開(kāi)始掃描字符串,跳過(guò)首部空格,掃一次全局索引自增一次:
- 調(diào)用掃描有符號(hào)整數(shù)函數(shù)來(lái)掃描A部分
- 如果字符串中包含小數(shù)點(diǎn).,則調(diào)用掃描無(wú)符號(hào)整數(shù)函數(shù)來(lái)掃描B部分
- 如果字符串中包含E或者e,則調(diào)用掃描有符號(hào)整數(shù)函數(shù)來(lái)掃描C部分
(6) 跳過(guò)尾部空格;
(7) 判斷校驗(yàn)結(jié)果是否為true以及全局索引自增到了結(jié)束標(biāo)識(shí)處。
接下來(lái),我們以123.45e+6為例,畫(huà)一下上述流程的執(zhí)行過(guò)程,如下所示:
實(shí)現(xiàn)代碼
萬(wàn)事俱備,接下來(lái),我們來(lái)看下代碼實(shí)現(xiàn)。
掃描無(wú)符號(hào)整數(shù)函數(shù)的代碼如下所示:
export class NumericalCheck { // 指針?biāo)饕? private index = 0; // 掃描無(wú)符號(hào)整數(shù) private scanUnsignedInteger(str: string): boolean { const before = this.index; while (str.charAt(this.index) >= "0" && str.charAt(this.index) <= "9") { this.index++; } return this.index > before; } }
掃描有符號(hào)整數(shù)函數(shù)是在無(wú)符號(hào)的基礎(chǔ)上添加符號(hào)的判斷,其如下所示:
// 掃描有符號(hào)整數(shù) private scanInteger(str: string): boolean { // 判斷其是否包含正負(fù)號(hào) if (str.charAt(this.index) == "+" || str.charAt(this.index) == "-") { this.index++; } // 掃描無(wú)符號(hào)整數(shù) return this.scanUnsignedInteger(str); }
最后,從頭到尾遍歷字符串,結(jié)合上述兩個(gè)函數(shù),判斷字符串是否為數(shù)值,其代碼如下所示:
public isNumber(numStr: string): boolean { if (numStr == null || numStr.length == 0) { return false; } // 添加結(jié)束標(biāo)志 numStr = numStr + "|"; // 跳過(guò)首部的空格 while (numStr.charAt(this.index) == " ") { this.index++; } // 掃描整數(shù)部分 let numeric = this.scanInteger(numStr); // 有小數(shù)點(diǎn),處理小數(shù)部分 if (numStr.charAt(this.index) == ".") { this.index++; // 小數(shù)兩邊只要有一邊有數(shù)字即可,所以用|| numeric = this.scanUnsignedInteger(numStr) || numeric; } // 有e||E,處理指數(shù)部分 if (numStr.charAt(this.index) == "E" || numStr.charAt(this.index) == "e") { this.index++; // e || E兩邊都要有數(shù)字,所以用&& numeric = numeric && this.scanInteger(numStr); } // 跳過(guò)尾部空格 while (numStr.charAt(this.index) == " ") { this.index++; } const checkResult = numeric && numStr.charAt(this.index) == "|"; // 重置指針?biāo)饕? this.index = 0; return checkResult; }
完整代碼請(qǐng)移步:? ?NumericalCheck.ts? ?。
測(cè)試用例
接下來(lái),我們舉幾個(gè)例子,將其帶入上述代碼中,看下它能否正確執(zhí)行,如下所示:
let str = "123.45e+6"; const numericalCheck = new NumericalCheck(); let checkResult = numericalCheck.isNumber(str); printCheckResult(); str = " .12e1 "; checkResult = numericalCheck.isNumber(str); printCheckResult(); str = "12e"; checkResult = numericalCheck.isNumber(str); printCheckResult(); str = "1.2.3"; checkResult = numericalCheck.isNumber(str); printCheckResult(); function printCheckResult() { console.log(`字符串 ${str}是否為數(shù)值校驗(yàn)結(jié)果為:${checkResult}`); }
執(zhí)行結(jié)果如下所示:
示例代碼文中所舉代碼的完整版請(qǐng)移步:
到此這篇關(guān)于詳解Java如何實(shí)現(xiàn)數(shù)值校驗(yàn)的算法的文章就介紹到這了,更多相關(guān)Java數(shù)值校驗(yàn)算法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
如何使用JDBC連接數(shù)據(jù)庫(kù)并執(zhí)行SQL語(yǔ)句
JDBC是Java數(shù)據(jù)庫(kù)連接的縮寫(xiě),是Java程序與數(shù)據(jù)庫(kù)進(jìn)行交互的標(biāo)準(zhǔn)API。JDBC主要包括Java.sql和javax.sql兩個(gè)包,通過(guò)DriverManager獲取數(shù)據(jù)庫(kù)連接對(duì)象Connection,并通過(guò)Statement或PreparedStatement執(zhí)行SQL語(yǔ)句2023-04-04全面了解OAuth?2.0四種授權(quán)方式金三銀四無(wú)懼面試
這篇文章主要介紹了全面了解OAuth?2.0四種授權(quán)方式金三銀四無(wú)懼面試,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02基于Spring定時(shí)任務(wù)的fixedRate和fixedDelay的區(qū)別
這篇文章主要介紹了基于Spring定時(shí)任務(wù)的fixedRate和fixedDelay的區(qū)別,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10RocketMQ消息存儲(chǔ)文件的加載與恢復(fù)機(jī)制源碼分析
這篇文章主要介紹了RocketMQ源碼分析之消息存儲(chǔ)文件的加載與恢復(fù)機(jī)制詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05集群環(huán)境中使用ehcache_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了集群環(huán)境中使用ehcache的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08java 分轉(zhuǎn)元與元轉(zhuǎn)分實(shí)現(xiàn)操作
這篇文章主要介紹了java 分轉(zhuǎn)元與元轉(zhuǎn)分實(shí)現(xiàn)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-02-02