1. 程式人生 > 其它 >力扣 每日一題 65. 有效數字

力扣 每日一題 65. 有效數字

今天的是個困難題,但是不帶怕的,因為前一百道我都做過了,時間久了,不記得當時是怎麼做的了。

有效數字(按順序)可以分成以下幾個部分:

一個 小數 或者 整數
(可選)一個 'e' 或 'E' ,後面跟著一個 整數
小數(按順序)可以分成以下幾個部分:

(可選)一個符號字元('+' 或 '-')
下述格式之一:
至少一位數字,後面跟著一個點 '.'
至少一位數字,後面跟著一個點 '.' ,後面再跟著至少一位數字
一個點 '.' ,後面跟著至少一位數字
整數(按順序)可以分成以下幾個部分:

(可選)一個符號字元('+' 或 '-')
至少一位數字
部分有效數字列舉如下:

["2", "0089", "-0.1", "+3.14", "4.", "-.9", "2e10", "-90E3", "3e+7", "+6e-1", "53.5e93", "-123.456e789"]


部分無效數字列舉如下:

["abc", "1a", "1e", "e3", "99e2.5", "--6", "-+3", "95a54e53"]
給你一個字串 s ,如果 s 是一個 有效數字 ,請返回 true 。

經過分析,字串總共可能的字元有以下幾種,依次分析他們的特徵。

1 點 (.),根據描述,點必須滿足前面或後面有數字,並且e|E後不可以有點;

2.e|E,前面後面必須有數字,前後數字可以帶+|-符號;

3.0~9,這個不需要特殊處理,如遇到數字,繼續遍歷即可;

4.+|-,只能在數字前,e|E之後的數字可以帶正負號。

基於上述分析,我們可以設定幾個變數,分別代表是否可以為該符號,如果不滿足條件,直接返回false,若滿足條件,一直遍歷到最後,然後返回true。

 1  public boolean isNumber(String s) {
 2         boolean plus = true;
 3         boolean minor = true;
 4         boolean dot = true;
 5         boolean eValue = true;
 6         char[] cs = s.toCharArray();
 7         int n =cs.length;
 8         for (int i = 0; i < cs.length; i++) {
 9             if
(((cs[i] == '+' && plus)||(cs[i] == '-' && minor))&&i<n-1&&(cs[i+1]>='0'&&cs[i+1]<='9'||cs[i+1]=='.')) { 10 plus = false; 11 minor=false; 12 } else if ((cs[i] == 'e' || cs[i] == 'E') && eValue&&i!=cs.length-1&&i!=0) { 13 eValue = false; 14 plus = true; 15 minor = true; 16 dot=false; 17 } else if (cs[i] == '.' && dot&&((i<n-1&&cs[i+1]>='0'&&cs[i+1]<='9')||(i>0&&cs[i-1]>='0'&&cs[i-1]<='9'))) { 18 dot = false; 19 } else if (cs[i] >= '0' && cs[i] <= '9') { 20 plus = false; 21 minor=false; 22 23 continue; 24 } else { 25 return false; 26 } 27 } 28 29 return true; 30 }

程式碼有點亂,我記得《劍指offer》上有類似的題,第20題,借鑑一下,寫了個Java版本,還是比較清晰的。

 1 int curr = 0;
 2   public boolean isNumber(String s) {
 3     s = s.trim();
 4     if (s.length() == 0) {
 5       return false;
 6     }
 7 
 8     boolean isNumber = scanInteger(s);
 9     if(curr<s.length()&&s.charAt(curr)=='.'){
10       curr++;
11       isNumber = scanUnsignedInteger(s)||isNumber;
12     }
13 
14     if(curr<s.length()&&(s.charAt(curr)=='E'||s.charAt(curr)=='e')){
15       curr++;
16       isNumber = scanInteger(s)&&isNumber;
17     }
18     return isNumber&&curr==s.length();
19 
20   }
21 
22 
23   private boolean scanInteger(String s) {
24     if (curr < s.length() && (s.charAt(curr) == '+' || s.charAt(curr) == '-')) {
25       curr++;
26     }
27     return scanUnsignedInteger(s);
28   }
29 
30   private boolean scanUnsignedInteger(String s) {
31     int tmp = curr;
32     while (curr < s.length() && s.charAt(curr) >= '0' && s.charAt(curr) <= '9') {
33       curr++;
34     }
35     return curr > tmp;
36   }