1. 程式人生 > >[Swift]LeetCode65. 有效數字 | Valid Number

[Swift]LeetCode65. 有效數字 | Valid Number

Validate if a given string is numeric.

Some examples:
"0" => true
" 0.1 " => true
"abc" => false
"1 a" => false
"2e10" => true

Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one.

Update (2015-02-10):
The signature of the C++ function had been updated. If you still see your function signature accepts a const char * argument, please click the reload button to reset your code definition.


驗證給定的字串是否為數字。

例如:
"0" => true
" 0.1 " => true
"abc"

 => false
"1 a" => false
"2e10" => true

說明: 我們有意將問題陳述地比較模糊。在實現程式碼之前,你應當事先思考所有可能的情況。

更新於 2015-02-10:
C++函式的形式已經更新了。如果你仍然看見你的函式接收 const char * 型別的引數,請點選過載按鈕重置你的程式碼。


20ms

 1 class Solution {
 2     func isNumber(_ s: String) -> Bool {
 3         let s = s.trimmingCharacters(in
: .whitespaces) 4 var pointSeen = false 5 var eSeen = false 6 var numSeen = false 7 var numAfterE = true 8 9 for i in 0..<s.count { 10 if "0" <= s[i] && s[i] <= "9" { 11 numSeen = true 12 numAfterE = true 13 } else if s[i] == "." { 14 if eSeen || pointSeen { 15 return false 16 } 17 pointSeen = true 18 } else if s[i] == "e" { 19 if eSeen || !numSeen { 20 return false 21 } 22 numAfterE = false 23 eSeen = true 24 } else if s[i] == "-" || s[i] == "+" { 25 if i != 0 && s[i - 1] != "e" { 26 return false 27 } 28 } else { 29 return false 30 } 31 } 32 33 return numSeen && numAfterE 34 } 35 } 36 37 extension String { 38 subscript (i: Int) -> Character { 39 return self[index(startIndex, offsetBy: i)] 40 } 41 42 subscript(_ range: CountableRange<Int>) -> String { 43 let idx1 = index(startIndex, offsetBy: max(0, range.lowerBound)) 44 let idx2 = index(startIndex, offsetBy: min(self.count, range.upperBound)) 45 return String(self[idx1..<idx2]) 46 } 47 }

24ms

 1 class Solution {
 2     func isNumber(_ s: String) -> Bool {
 3         var num = Array(s.trimmingCharacters(in: .whitespacesAndNewlines))
 4         guard let first = num.first else {
 5             return false
 6         }
 7         
 8         if let e = num.index(of: "e") {
 9             if e > 0 && e < num.count - 1 {
10                 return isRealNumber(Array(num[0..<e])) && isInteger(Array(num[(e+1)...]))
11             } else {
12                 return false
13             }
14         } else {
15             return isRealNumber(num)
16         }
17     }
18     
19     func isDigitOnly(_ num: [Character]) -> Bool {
20         return num.count > 0 && !num.contains { $0 < "0" || $0 > "9" }
21     }
22     
23     func isInteger(_ num: [Character]) -> Bool {
24         guard let first = num.first else {
25             return false
26         }
27         
28         if first == "+" || first == "-" {
29             return isDigitOnly(Array(num[1...]))
30         } else {
31             return isDigitOnly(num)
32         }
33     }
34     
35     func isFloat(_ num: [Character]) -> Bool {
36         guard num.count > 1 else {
37             return false 
38         }
39         
40         if let dot = num.index(of: ".") {
41             if dot == 1 && (num[0] == "+" || num[0] == "-") {
42                 return isDigitOnly(Array(num[(dot + 1)...]))
43             }
44             
45             return (dot == 0 || isInteger(Array(num[0 ..< dot]))) 
46                 && (dot == num.count - 1 || isDigitOnly(Array(num[(dot + 1)...])))
47         } else {
48             return false
49         }
50     }
51     
52     func isRealNumber(_ num: [Character]) -> Bool {
53         return isInteger(num) || isFloat(num)
54     }
55 }

28ms

 1 class Solution {
 2     enum State : Int {
 3         case Started
 4         case Integer
 5         case Decimal
 6         case Exponential
 7         case Invalid
 8     }
 9 
10     var hasSeenExpSign = false
11     var hasSeenDigit = false
12     
13     func isDigit(_ char: Character) -> Bool {
14         if let _ = Int(String(char)) {
15             hasSeenDigit = true
16             return true
17         }
18         return false
19     }
20     
21     func getNextState (_ state: State, char: Character) -> State {
22         var nextState:State = .Invalid
23         switch state {
24         case .Started, .Integer:
25             if isDigit(char) {
26                 return .Integer
27             } else if char == "." {
28                 return .Decimal
29             } else if char == "e" && hasSeenDigit {
30                 return .Exponential
31             }
32         case .Decimal:
33             if isDigit(char)  {
34                 return state
35             } else if char == "e" && hasSeenDigit {
36                 return .Exponential
37             }
38         case .Exponential:
39             if isDigit(char)  {
40                 return state
41             } else if (char == "-" || char == "+") && !hasSeenExpSign  {
42                 hasSeenExpSign = true
43                 return state
44             }
45         default:
46             return .Invalid
47         }
48         return .Invalid
49     }
50 
51     func isNumber(_ s: String) -> Bool {
52         var state:State = State.Started
53         var array = Array(s.trimmingCharacters(in: CharacterSet.whitespaces))        
54         var i = 0
55         if array.first == "+" || array.first == "-" {
56             i += 1
57         }
58         while i < array.count {
59             state = getNextState(state, char: array[i])
60             if state == State.Invalid {
61                 return false
62             }
63             i += 1
64         }
65         if state == State.Exponential {
66             return isDigit(array.last!)
67         }
68         return hasSeenDigit
69     }
70 }

32ms

 1 class Solution {
 2     func isNumber(_ s: String) -> Bool {
 3         //initialize
 4         var s = s.map{ String($0) }
 5         var i = 0
 6         var n = s.count
 7         var isValid = false
 8         //analyze
 9         //" " in front
10         while i < n && s[i] == " " {
11             i += 1
12         }
13         //"+/-"
14         while i < n && (s[i] == "+" || s[i] == "-") {
15             i += 1
16         }
17         //valid number
18         while i < n && Int(s[i]) != nil {
19             isValid = true
20             i += 1
21         }
22         //"."
23         if i < n && s[i] == "." {
24             i += 1
25             //check for valid number
26             while i < n && Int(s[i]) != nil {
27                 isValid = true
28                 i += 1
29             }
30         }
31         //"e"
32         if i < n && isValid && s[i] == "e" {
33             isValid = false
34             i += 1
35             //"+/-"
36             while i < n && (s[i] == "+" || s[i] == "-") {
37                 i += 1
38             }
39             //check for valid numbers
40             while i < n && Int(s[i]) != nil {
41                 isValid = true
42                 i += 1
43             }
44         }
45         //check for " " in end
46         while i < n && s[i] == " " {
47             i += 1
48         }
49         return isValid && i == n
50     }
51 }

36ms

 1 class Solution {
 2   
 3     func isNumber(_ s: String) -> Bool {
 4       let trimmed = s.trimmingCharacters(in: .whitespaces)
 5       guard trimmed.count > 0 else { return false }
 6       if let index = Array(trimmed).index(of: "e"), (index == 0 || index == trimmed.count-1) {
 7         return false
 8       }
 9       let c = trimmed.trimmingCharacters(in: .whitespaces).components(separatedBy: "e")
10       if let index = c.index(of: "e"), (index == 0 || index == c.count-1) {
11         return false
12       }
13       switch c.count {
14         case 1 : return isValidFloating(c[0])
15         case 2 : return isValidFloating(c[0]) && isValidInteger(c[1])
16         default: return false
17       }
18     }
19   
20   func isValidInteger(_ s: String) -> Bool {
21     guard s.count > 0 else { return true }
22     let s = Array(s).map{String($0)}
23     guard s.count > 1 else { return Int(s[0]) != nil && s[0] != "-" && s[0] != "+" }
24     if Int(s[0]) == nil && s[0] != "-" && s[0] != "+" {
25       return false
26     }
27     for i in 1..<s.count {
28       if Int(s[i]) == nil { return false }
29     }
30     return true
31   }
32   
33   func isValidFloating(_ s: String) -> Bool {
34     guard s.count > 0 else { return false }
35     let s = Array(s).map{String($0)}
36     guard s.count > 1 else { return Int(s[0]) != nil && s[0] != "-" && s[0] != "+" && s[0] != "." }
37     if Int(s[0]) == nil && s[0] != "-" && s[0] != "+" && s[0] != "." {
38       return false
39     }
40     var foundPoint = s[0] == "."
41     var foundDigit = Int(s[0]) != nil
42     for i in 1..<s.count {
43       if s[i] == "." {
44         if foundPoint { return false }
45         foundPoint = true
46       } else if Int(s[i]) == nil { 
47         return false 
48       } else {
49         foundDigit = true
50       }
51     }
52     return foundDigit
53   }
54 }

40ms

 1 class Solution {
 2     func isNumber(_ s: String) -> Bool {
 3         var decimal = s
 4     
 5     decimal = decimal.trimmingCharacters(in: CharacterSet(charactersIn: " "))
 6     
 7     if decimal.contains("e"), decimal.components(separatedBy: CharacterSet(charactersIn: "e")).count == 2{
 8         if decimal.split(separator: "e").count == 2{
 9             let lhs = decimal.split(separator: "e")[0]
10             let rhs = decimal.split(separator: "e")[1]
11             if !rhs.contains("."){
12                 if let newLHS = Double(lhs){
13                     if let newRHS = Int(rhs){
14                         return true
15                     }
16                 }
17             }
18         }
19     }else{
20         if let number = Double(decimal){
21             return true
22         }
23     }
24     return false
25     }
26 }

44ms

 1 class Solution {
 2     
 3     let digits = Set("0123456789")
 4     
 5     func isNumber(_ s: String) -> Bool {
 6         var sTrimmed = s.trimmingCharacters(in: .whitespacesAndNewlines)
 7         guard sTrimmed.first ?? " " != "e" && sTrimmed.last ?? " " != "e" else {
 8             return false
 9         }
10         var eAppeared = false
11         for char in sTrimmed {
12             if char == "e" {
13                 guard !eAppeared else {
14                     return false
15                 }
16                 eAppeared = true
17             }
18         }
19         var parts = sTrimmed.split(separator: "e").map{ Array($0) }
20         print(parts)
21         guard parts.count > 0 && parts.count <= 2 else {
22             return false
23         }
24         for i in 0..<parts.count {
25             var pointAppeared = false
26             var digitsAppeared = false
27             for j in 0..<parts[i].count {
28                 let char = parts[i][j]
29                 if !digits.contains(char) {
30                     if char == "-" || char == "+" {
31                         guard j == 0 else {
32                             return false
33                         }
34                     } else if char == "." {
35                         guard i == 0 && !pointAppeared else {
36                             return false
37                         }
38                         pointAppeared = true
39                     } else {
40                         return false
41                     }
42                 } else {
43                     digitsAppeared = true
44                 }
45             }
46             guard digitsAppeared else {
47                 return false
48             }
49         }
50         return true
51     }
52 }

56ms

 1 class Solution {
 2     func isNumber(_ s: String) -> Bool {
 3         let str = s.trimmingCharacters(in: CharacterSet(charactersIn: " "))
 4         
 5         guard str.count > 0 && str != "." else {
 6             return false
 7         }
 8         
 9         if let _ = Double(str) {
10             return true
11         }
12         
13         let vals = str.components(separatedBy: "e")
14         if vals.count > 2 {
15             return false
16         }
17         
18         let invalids = [".", "-.", "+.", "-", "+"]
19         if invalids.contains(vals.first!) {
20             return false
21         }
22         
23         func isMyDigit(_ ss: String, _ sign: Bool, _ single: Bool) -> Bool {
24             
25             if !sign && (ss.contains("-") || ss.contains("+")) {
26                 return false
27             }
28             
29             if !single && (ss == "+" || ss == "-") {
30                 return false
31             }
32             
33             for (i, v) in ss.enumerated() {
34                 if (v >= "0" && v <= "9") || (i == 0 && (v == "-" || v == "+")) {
35                     continue
36                 }
37                 return false
38             }
39             return true
40         }
41         
42         if vals.count == 2 {
43             if vals.first!.count == 0 || vals.last!.count == 0 || !isMyDigit(vals.last!, true, false) {
44                 return false
45             }
46         }
47         
48         let dots = vals.first!.components(separatedBy: ".")
49         if dots.count > 2 {
50             return false
51         }
52         
53         if !isMyDigit(dots.first!, true, true) {
54             return false
55         }
56         
57         if dots.count == 2 && !isMyDigit(dots.last!, false, false) {
58             return false
59         }
60         
61         return true
62     }
63 }