[Swift]LeetCode65. 有效數字 | Valid Number
阿新 • • 發佈:2018-11-07
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 }