本文參考自《劍指offer》一書,代碼採用Java語言。html
更多:《劍指Offer》Java實現合集 java
請實現一個函數用來判斷字符串是否表示數值(包括整數和小數)。例如,字符串「+100」、「5e2」、「-123」、「3.1416」及「-1E-16」都表示數值,但「12e」、「1a3.14」、「1.2.3」、「+-5」及「12e+5.4」都不是。面試
剛開始的思路是從頭至尾遍歷,對遇到的不一樣狀況進行分析,但很容易出錯。所以採用《劍指OFFER》一書的方法:將數字的形式總結爲:(A.B E/e A) ,按順序進行判斷(A表明帶符號整數,B表明不帶符號整數)。數組
另外一種思路:藉助幾個flag從頭至尾遍歷,具體代碼見:【LeetCode】65. Valid Numberide
測試算例 函數
1.功能測試(正負數;含整數與不含整數部分;含與不含小數部分;含與不含指數部分;不匹配狀況)post
2.特殊測試(null,空字符串)測試
(含測試代碼)url
/** * * @Description 面試題20:表示數值的字符串 * * @author yongh * @date 2018年9月22日 上午11:15:13 */ // 題目:請實現一個函數用來判斷字符串是否表示數值(包括整數和小數)。例如, // 字符串「+100」、「5e2」、「-123」、「3.1416」及「-1E-16」都表示數值,但「12e」、 // 「1a3.14」、「1.2.3」、「+-5」及「12e+5.4」都不是 public class NumericStrings { /* * 數字的基本格式爲:(A.B E/e A) ,按順序進行判斷 * //A表明帶符號整數,B表明不帶符號整數 * 當心:時刻要注意數組越界問題! */ public boolean isNumeric(char[] str) { if (str == null || str.length == 0) return false; int[] index = new int[1]; index[0] = 0; // 用於記錄當前字符位置 // 先判斷A boolean isNumeric; //用於記錄是否知足條件 isNumeric = isInteger(str, index); // 判斷B if (index[0] < str.length && (str[index[0]] == '.')) { index[0]++; isNumeric = isUnsignedInteger(str, index) || isNumeric; // .B和A.和A.B形式都可以 } // 判斷e後面的A if (index[0] < str.length && (str[index[0]] == 'e' || str[index[0]] == 'E')) { index[0]++; isNumeric = isInteger(str, index) && isNumeric; } if (isNumeric && index[0] == str.length) return true; else return false; } private boolean isInteger(char[] str, int[] index) { // 用int[]才能傳值,int的話須要定義index爲全局變量 if (index[0] < str.length && (str[index[0]] == '+' || str[index[0]] == '-')) index[0]++; return isUnsignedInteger(str, index); } private boolean isUnsignedInteger(char[] str, int[] index) { int start = index[0]; while (index[0] < str.length && (str[index[0]] - '0' <= 9 && str[index[0]] - '0' >= 0)) index[0]++; if (index[0] > start) return true; else return false; } // =======測試代碼========= void test(String testName, char[] str, boolean expected) { System.out.print(testName + ":"); if (isNumeric(str) == expected) System.out.println(" passed!"); else System.out.println(" failed!"); } void test1() { char[] str = null; test("test1", str, false); } void test2() { char[] str = {}; test("test2", str, false); } void test3() { String string ="e3"; char[] str=string.toCharArray(); test("test3", str, false); } void test4() { String string ="3e1.2"; char[] str=string.toCharArray(); test("test4", str, false); } void test5() { String string ="e3"; char[] str=string.toCharArray(); test("test5", str, false); } void test6() { String string ="1.2e3"; char[] str=string.toCharArray(); test("test6", str, true); } void test7() { String string ="-.2e3"; char[] str=string.toCharArray(); test("test7", str, true); } void test8() { String string ="-.2e-3"; char[] str=string.toCharArray(); test("test8", str, true); } void test9() { String string ="1.e-3"; char[] str=string.toCharArray(); test("test9", str, true); } void test10() { String string ="1."; char[] str=string.toCharArray(); test("test10", str, true); } void test11() { String string =".2"; char[] str=string.toCharArray(); test("test11", str, true); } void test12() { String string ="12e3"; char[] str=string.toCharArray(); test("test12", str, true); } public static void main(String[] args) { NumericStrings demo = new NumericStrings(); demo.test1(); demo.test2(); demo.test3(); demo.test4(); demo.test5(); demo.test6(); demo.test7(); demo.test8(); demo.test9(); demo.test10(); demo.test11(); demo.test12(); } }
test1: passed! test2: passed! test3: passed! test4: passed! test5: passed! test6: passed! test7: passed! test8: passed! test9: passed! test10: passed! test11: passed! test12: passed!
對字符串進行依次判斷時,定義一個Boolean變量,每判斷一部分進行更新,最終該變量即爲判斷結果,不須要進行循環判斷。(即本例中的isNumeric變量)spa
代碼38行,別忘記了最後對index是否到達結尾進行判斷。
注意:第31行isNumeric = isUnsignedInteger(str, index) || isNumeric;
的順序不能反了,不能寫成isNumeric = isNumeric || isUnsignedInteger(str, index) ; 不然當isNumeric爲True時,不會判斷後半部分,index就不會走向'e',從而致使錯誤。