input: 문자열 s
output: s가 유효한 숫자인지 T/F 리턴
A valid number can be split up into these components (in order):
'e'
or 'E'
, followed by an integer.A decimal number can be split up into these components (in order):
'+'
or '-'
).'.'
.'.'
, followed by one or more digits.'.'
, followed by one or more digits.An integer can be split up into these components (in order):
'+'
or '-'
).1 <= s.length <= 20
s
consists of only English letters (both uppercase and lowercase), digits (0-9
), plus '+'
, minus '-'
, or dot '.'
.코틀린 내장 함수를 사용하는 방법도 있지만, 내장 함수를 못 쓰게하는 경우가 많아서 구현으로 풀었다.
결국 “숫자”, “.”, “e/E” 각 경우에 대해 분기처리를 실 수 없이 하는 것이 핵심 → Sol1
구현
각 문자에 대한 필수 조건
“숫자”
“e/E”
부호
“.”
class Solution {
fun isNumber(s: String): Boolean {
var idx = 0
var digitExist = false
var eExist = false
var dotExist = false
while (idx < s.length) {
when (s[idx]) {
in "0123456789" -> {
digitExist = true
}
in "eE" -> {
if (idx > 0 && (!s[idx - 1].isDigit() && s[idx - 1] != '.')) return false // e 앞은 숫자나 .
if (idx + 1 < s.length && (s[idx + 1] !in listOf('-', '+') && !s[idx + 1].isDigit())) return false // e 뒤는 숫자나 부호
if (idx == 0 || idx == s.length -1) return false // e로 시작하거나 끝날 수 없음
if (!digitExist || eExist) return false // 숫자가 한번도 안나왔거나 e 두개 존재 X
eExist = true
}
in "-+" -> {
if (idx > 0 && s[idx - 1] !in listOf('e', 'E')) return false // 부호 앞은 e
if (idx + 1 < s.length && (s[idx + 1] != '.' && !s[idx + 1].isDigit())) return false // 부호 뒤는 숫자나 .
if (idx == s.length -1) return false // 부호로 끝날 수 없음
}
'.' -> {
if (dotExist) return false // . 두개 존재X
if (idx == 0 && idx + 1 < s.length && !s[idx + 1].isDigit()) return false // .으로 시작한다면 뒤는 무조건 숫자
if (idx + 1 < s.length && (s[idx + 1] !in listOf('e', 'E') && !s[idx + 1].isDigit())) return false // . 뒤는 숫자나 e
if (s.length == 1 && s[idx] == '.') return false // .만 존재 X
if (eExist || dotExist) return false // e/E 뒤에 . 존재X , . 두개 존재X
dotExist = true
}
else -> {
return false
}
}
idx++
}
return digitExist
}
}
시간 복잡도: 문자열 순회 = n