지금 문자열을 int로 변환하는 myAtoi 함수를 직접 짜고 있는데,
잘못된 부분이 몇 개 있어서 정확하게 짚어줄게. 👏
❗ 문제점 1 — 부호(+, -) 체크가 잘못됨
if s[i] not in valid:
break
if s[i] not in op:
break
이렇게 되면 숫자도 아니고, 부호도 아니면 끊어야 하는데,
네 코드에서는 숫자가 아니기만 해도 바로 break 되어버려.
즉, -42 같은 걸 만나면,
- -는 숫자가 아니니까 첫 줄에서 바로 break 됨 ❗
- 실제로는 부호는 받아야 하는데.
✅ 고쳐야 해:
- 첫 번째 글자는 부호일 수도 있고, 숫자일 수도 있음
- 그 이후부터는 숫자만 와야 함
❗ 문제점 2 — if s[i] not in valid와 if s[i] not in op가 독립적으로 있음
지금 두 개를 따로따로 체크하는데, 논리가 이상해져.
- 숫자가 아닌데도 부호가 아니면 끊어야 하는데,
- 각각 따로 체크하다 보니까 이상하게 동작해.
❗ 문제점 3 — 부호(-)를 숫자 앞에 매번 붙임
if s[i] == "-":
integer = f"-{integer}"
- 근데 이러면 숫자 중간에 -가 나오면 계속 붙어버려 ❗
- 실제로는 부호는 첫 번째만 체크하면 되고, 그 다음은 무시해야 해.
✅ 제대로 정리하면 로직은 이렇게 돼야 해
- 공백을 제거한다 (s.strip()).
- 부호를 하나 체크한다 (+ 또는 -).
- 숫자를 읽는다 (숫자 아닌 거 나오면 멈춘다).
- 숫자가 없으면 0을 리턴한다.
- 결과를 int로 변환해서 부호 적용 후 리턴한다.
✨ 제대로 고친 버전
class Solution:
def myAtoi(self, s: str) -> int:
s = s.strip() # 1. 문자열 앞뒤 공백 제거
if not s:
return 0 # 2. 공백만 있는 경우 0 반환
sign = 1 # 3. 기본 부호는 양수(+)
idx = 0 # 4. 문자열을 탐색할 인덱스
# 5. 첫 글자가 부호일 경우 처리
if s[0] == "-":
sign = -1 # 음수 부호
idx = 1 # 다음 문자부터 읽기
elif s[0] == "+":
idx = 1 # 양수 부호 (기본값 유지) → 다음 문자부터 읽기
integer = "" # 6. 숫자 부분만 저장할 문자열
# 7. 숫자(0~9)만 읽기
while idx < len(s) and s[idx].isdigit():
integer += s[idx] # 숫자이면 integer 문자열에 추가
idx += 1 # 다음 문자로 이동
# 8. 숫자가 하나도 없으면 0 반환
if integer == "":
return 0
num = sign * int(integer) # 9. 부호를 적용해서 정수 변환
# 10. 32비트 정수 범위 초과/이하 처리
INT_MAX = 2**31 - 1 # 2147483647
INT_MIN = -2**31 # -2147483648
if num < INT_MIN:
return INT_MIN
if num > INT_MAX:
return INT_MAX
# 11. 최종 변환 결과 반환
return num
🎯 한 문장 요약
"myAtoi는 공백 제거 → 부호 체크 → 숫자만 읽기 → int로 변환 → 32비트 범위로 클램프하는 순서로 짠다."
두 번째 내 코드
class Solution:
def myAtoi(self, s: str) -> int:
# 첫번째 부호있을수 있음
l = 0
sign = 1
res = ""
while l<len(s):
if l==0 and (s[l] == "+" or s[l] == "-"):
if s[l] == "+":
sign = 1
if s[l] == "-":
sign = -1
l+=1
if s[l] == " " or s[l].isdigit():
if s[l].isdigit():
res += s[l]
l+=1
else:
break
if res == "":
return 0
res = int(res)*sign
if res < -2**31:
res =-2**31
elif res > 2**31-1:
res = 2**31-1
return res
조금만 수정하면 완벽해질 것 같아.
지금 네 코드 문제점은 2가지야:
1. if 문 들여쓰기 오류
if l==0 and (s[l] == "+" or s[l] == "-"):
...
if s[l] == " " or s[l].isdigit():
여기 두 번째 if가 첫 번째 if 안으로 잘못 들어가 있어.
elif로 연결해야 해.
안 그러면 문법 오류 나.
2. 공백 처리 순서 문제
문자열 맨 앞에 " " (공백)이 여러 개 있을 수 있는데,
지금은 l==0일 때만 부호를 보고, 바로 숫자/공백 검사하는데, 공백을 먼저 다 무시한 다음에 부호랑 숫자를 봐야 해.
✨ 깔끔하게 고친 버전(내 버전)
class Solution:
def myAtoi(self, s: str) -> int:
# 첫번째 부호있을수 있음
l = 0
sign = 1
res = ""
s =s.strip() # 우선 공백 제거
while l<len(s):
if l==0 and (s[l] == "+" or s[l] == "-"):
if s[l] == "+":
sign = 1
if s[l] == "-":
sign = -1
l+=1
elif s[l].isdigit():
if s[l].isdigit():
res += s[l]
l+=1
else:
break
if res == "":
return 0
res = int(res)*sign
if res < -2**31:
res =-2**31
elif res > 2**31-1:
res = 2**31-1
return res
좀 더 최적화
class Solution:
def myAtoi(self, s: str) -> int:
# 첫번째 부호있을수 있음
l = 0
sign = 1
res = ""
s =s.strip() # 우선 공백 제거
# 제일 처음에만 + - 부호가 있을 수 있으므로
# if len(s) >0 and (s[l] == "+" or s[l] == "-"):
if l< len(s) and (s[l] == "+" or s[l] == "-"):
if s[l] == "+":
sign = 1
if s[l] == "-":
sign = -1
l+=1
"""
while l<len(s):
if s[l].isdigit():
res += s[l]
l+=1
else:
break
이 코드를 더 최적화 하면, 아래 코드가 됨!!
"""
while l<len(s) and s[l].isdigit():
res += s[l]
l+=1
if res == "":
return 0
res = int(res)*sign
if res < -2**31:
res =-2**31
elif res > 2**31-1:
res = 2**31-1
return res
✨ 깔끔하게 고친 버전(GPT 버전)
class Solution:
def myAtoi(self, s: str) -> int:
l = 0
sign = 1
res = ""
# 1. 공백 먼저 무시
while l < len(s) and s[l] == " ":
l += 1
# 2. 부호 처리
if l < len(s) and (s[l] == "+" or s[l] == "-"):
if s[l] == "-":
sign = -1
l += 1
# 3. 숫자 처리
while l < len(s) and s[l].isdigit():
res += s[l]
l += 1
# 4. 숫자 없으면 0 리턴
if res == "":
return 0
# 5. 최종 결과 계산
res = int(res) * sign
if res < -2**31:
res = -2**31
elif res > 2**31-1:
res = 2**31-1
return res
✅ 요약
- 공백 무시 → 부호 확인 → 숫자 저장 순서로!
- if-elif-else 구조 깨지지 않게 깔끔하게!
- 숫자 없으면 0 리턴하는 것도 잊지 말기!
class Solution:
def myAtoi(self, s: str) -> int:
# 첫번째 부호있을수 있음
l = 0
sign = 1
res = ""
s =s.strip() # 우선 공백 제거
while l<len(s):
if l==0 and (s[l] == "+" or s[l] == "-"):
if s[l] == "+":
sign = 1
if s[l] == "-":
sign = -1
l+=1
elif s[l].isdigit():
if s[l].isdigit():
res += s[l]
l+=1
else:
break
if res == "":
return 0
res = int(res)*sign
if res < -2**31:
res =-2**31
elif res > 2**31-1:
res = 2**31-1
return res
최종 코드
class Solution:
def myAtoi(self, s: str) -> int:
# 일단 공백 지우고
s = s.strip()
"""
s가 빈 문자열이면 s[0]이 없으므로 IndexError가 발생
→ s.strip() 후에는 반드시 빈 문자열인지 체크해야 !!
"""
if not s:
return 0
# 첫번째 부호 기호인지, 숫자인지 등 체크
sign = 1
i=0
if s[i] == "-":
sign = -1
i+=1
elif s[i] == "+":
sign = 1
i+=1
res = ""
while i< len(s) and s[i].isdigit():
res += s[i]
i+=1
final_number = int(res)*sign if res != "" else 0
INT_MAX = 2**31-1
INT_MIN = -2**31
if final_number > INT_MAX:
final_number = INT_MAX
elif final_number < INT_MIN:
final_number = INT_MIN
return final_number'LeetCode > Grind169' 카테고리의 다른 글
| 5. Longest Palindromic Substring ☆★★ (잘 풀리면, DP도 이해하자!) (0) | 2025.04.27 |
|---|---|
| 199. Binary Tree Right Side View ☆★(BFS 확실히 숙지, DFS도 !) (0) | 2025.04.27 |
| 416. Partition Equal Subset Sum: DP로 꼭 풀어야! ☆☆★★★ (0) | 2025.04.26 |
| 15. 3Sum ☆☆☆★ (0) | 2025.04.23 |
| 53. Maximum Subarray ☆☆★ (0) | 2025.04.23 |