劍指Offer面試題54:表示數值的字符串

題目:表示數值的字符串
        請實現一個函數用來判斷字符串是否表示數值(包括整數和小數)。例如,字符串“+100”,“5e2”,"-123","3.1416",  "-1e-16"都表示數值,但“12e",  "1a3.14"  ,"1.2.3", "+-5"都不是。
算法分析:
 在數值之前可能有一個表示正負的’-‘或者’+’。接下來是若干個0到9的數位表示數值的整數部分(在某些小數裏可能沒有數值的整數部分)。如果數值是一個小數,那麼在小數點後面可能會有若干個0到9的數位表示數值的小數部分。如果數值用科學計數法表示,接下來是一個’e’或者‘E’,以及緊跟着的一個整數(可以有正負號)表示指數。
  判斷一個字符串是否符合上述模式時,首先看第一個字符是不是正負號。如果是,在字符串上移動一個字符,繼續掃描剩餘的字符串中0到9的數位。如果是一個小數,則將遇到小數點。另外,如果是用科學計數法表示的數值,在整數或者小數的後面還有可能遇到’e’或者’E’。

算法源程序:
/**************************************************************      
* Copyright (c) 2016, 
* All rights reserved.                   
* 版 本 號:v1.0                   
* 題目描述:表示數值的字符串
 *		        請實現一個函數用來判斷字符串是否表示數值(包括整數和小數)。例如,字符串“+100”,“5e2”,"-123","3.1416",  "-1e-16"
 *			都表示數值,但“12e",  "1a3.14"  ,"1.2.3", "+-5"都不是。
* 輸入描述: 請輸入一個要判斷的字符串:
*			-12E-16
* 程序輸出:算法1的判斷的結果是:true
*			算法2的判斷結果是:true
* 問題分析: 1.整個字符串不需要從頭循環到尾,只需要一次次向後移動所指向的字符即可
* 算法描述:在數值之前可能有一個表示正負的’-‘或者’+’。接下來是若干個0到9的數位表示數值的整數部分(在某些小數裏可能沒有數值的整數部分)。
* 			如果數值是一個小數,那麼在小數點後面可能會有若干個0到9的數位表示數值的小數部分。
* 			如果數值用科學計數法表示,接下來是一個’e’或者‘E’,以及緊跟着的一個整數(可以有正負號)表示指數。
*		  判斷一個字符串是否符合上述模式時,首先看第一個字符是不是正負號。如果是,在字符串上移動一個字符,
*			繼續掃描剩餘的字符串中0到9的數位。如果是一個小數,則將遇到小數點。
*			另外,如果是用科學計數法表示的數值,在整數或者小數的後面還有可能遇到’e’或者’E’。
* 完成日期:2016-10-12
***************************************************************/

package org.marsguo.offerproject54;

import java.util.Scanner;

class SolutionMethod1{
	public boolean isNumberFunction(String input){
		if(input == null || input.length() < 1){
			return false;
		}
		
		int i = 0;			//用於指向字符串中的每一個字符
		int len = input.length();			//用於判斷字符串的長度
		//判斷字符串的第一位是不是正負號	
		if(input.charAt(i)== '+'||input.charAt(i) == '-'){
			i++;							//後移一位
		}
		
		//已經到達了字符串的結尾,每次i後移後都需要判斷是否超出了字符串的長度
		if(i >= len )			
			return false;
		
		boolean index = true;
		i = scanDigits(input, i);
		//還沒有到達字符串的末尾
		if(i <len){	
			//如果是小數點
			if(input.charAt(i) == '.'){
				i++;
				i = scanDigits(input, i);
				
				//已經到達了字符串的末尾了
				if(i >= len){		
					return true;
				}
				
				else if(input.charAt(i) == 'e' || input.charAt(i) == 'E'){
					index = isExponential(input,i);
				}
				else{
					index =  false;
				}
				
			}
			//如果是指數
			else if(input.charAt(i) == 'e' || input.charAt(i) == 'E'){
				index = isExponential(input,i);
			}
			else {
				index = false;
			}
			return index;
		}
		//已經到達了字符串的末尾,說明其沒有指數,整個字符串都循環完
		else{
			return true;
		}
	}
	
	public int scanDigits(String input,int i){
		//循環掃描,直到所指的字符不是數字爲止
		while(i <input.length() && input.charAt(i) >= '0'&& input.charAt(i) <= '9'){
			i++;
		}
		return i;
	}
	
	public boolean isExponential(String input,int i){
		if(input.charAt(i) != 'e' && input.charAt(i) != 'E')
			return false;
		
		i++;
		
		if(i >= input.length())		//每一次i++後,都要判斷下是否已經到達了字符串的結尾
			return false;
		
		if(input.charAt(i) == '+'  || input.charAt(i) == '-')
			i++;
		
		if(i >= input.length())
			return false;
		
		i = scanDigits(input, i);
		
		return (i >= input.length())? true:false;
	}
}

class SolutionMethod2{
	public boolean isNumeric(String input){
		//如果只輸入一個+-的話,會判斷爲true,是個bug
		return input.matches("[\\+-]?[0-9]*(\\.[0-9]*)?([eE][\\+-]?[0-9]+)?");
	}
}
public class IsNumber {
	public static void main(String[] args){
		Scanner scanner = new Scanner(System.in);
		System.out.println("請輸入一個要判斷的字符串:");
		String str = scanner.nextLine();
		scanner.close();
		
		SolutionMethod1 solution1 = new SolutionMethod1();
		System.out.println("算法1的判斷的結果是:" + solution1.isNumberFunction(str));
		
		SolutionMethod2 solution2 = new SolutionMethod2();
		System.out.println("算法2的判斷結果是:" + solution2.isNumeric(str));
	}
}


程序運行結果:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章