• 【Java】 剑指offer(20) 表示数值的字符串


    本文参考自《剑指offer》一书,代码采用Java语言。

    更多:《剑指Offer》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 Number

    测试算例 

      1.功能测试(正负数;含整数与不含整数部分;含与不含小数部分;含与不含指数部分;不匹配情况)

      2.特殊测试(null,空字符串)

    完整Java代码

    (含测试代码)

    /**
     * 
     * @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变量)

      代码38行,别忘记了最后对index是否到达结尾进行判断。

      注意:第31行isNumeric = isUnsignedInteger(str, index) || isNumeric; 的顺序不能反了,不能写成isNumeric = isNumeric || isUnsignedInteger(str, index) ;  否则当isNumeric为True时,不会判断后半部分,index就不会走向'e',从而导致错误。

    更多:《剑指Offer》Java实现合集  

  • 相关阅读:
    C语言实现快排
    C语言实现双向循环链表
    mysql插入数据后返回自增ID的方法
    golang flag包简单例子
    练习题 (六)
    练习题 (五)
    练习题 (四)
    练习题 (三)
    练习题 (二)
    练习题 (一)
  • 原文地址:https://www.cnblogs.com/yongh/p/9765589.html
Copyright © 2020-2023  润新知