【Java】 劍指offer(20) 表示數值的字符串

 

本文參考自《劍指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,空字符串)測試

完整Java代碼

(含測試代碼)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!
NumericStrings

 

收穫

  對字符串進行依次判斷時,定義一個Boolean變量,每判斷一部分進行更新,最終該變量即爲判斷結果,不須要進行循環判斷。(即本例中的isNumeric變量)spa

  代碼38行,別忘記了最後對index是否到達結尾進行判斷。

  注意:第31行isNumeric = isUnsignedInteger(str, index) || isNumeric; 的順序不能反了,不能寫成isNumeric = isNumeric || isUnsignedInteger(str, index) ;  不然當isNumeric爲True時,不會判斷後半部分,index就不會走向'e',從而致使錯誤。

 

更多:《劍指Offer》Java實現合集 

相關文章
相關標籤/搜索