면접 중 간단하지만 구현 디테일을 보기 좋은 문제 중 하나가 문자열을 실수(float)로 직접 파싱하는 문제입니다.
예를 들어 "-12.34"를 입력받아 -12.34를 반환해야 합니다. 이번 글에서는 parseInt, parseFloat 같은 내장 변환 함수 없이 직접 구현하는 아이디어를 정리합니다.
문제
- 입력: 부호(
-), 소수점(.), 숫자로 이루어진 문자열 - 출력: 해당 문자열을
float값으로 변환한 결과
예시
"1.23"->1.23"-12.34"->-12.34
아이디어
핵심은 두 가지입니다.
-부호를 먼저 확인해서 음수 여부를 저장- 숫자만 따로 모은 뒤, 소수점 이하 자릿수를 이용해 자리값을 계산
기존 메모처럼 스택을 사용하면, 뒤에서부터 꺼내면서 10의 거듭제곱을 곱해 합산할 수 있습니다.
- 예:
"12.34"- 숫자 스택:
1, 2, 3, 4 - 소수 자릿수 카운트:
2 - 계산:
4 * 10^-2 = 0.043 * 10^-1 = 0.32 * 10^0 = 21 * 10^1 = 10
- 합:
12.34
- 숫자 스택:
Java 예시 코드
import java.util.Stack;
public class AtofParser {
private static final char SIGN = '-';
private static final char POINT = '.';
public static float atof(final String str) {
boolean isMinus = false;
boolean countDecimal = false;
int decimalCount = 0;
Stack<Integer> stack = new Stack<>();
if (str.length() > 0 && str.charAt(0) == SIGN) {
isMinus = true;
}
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if (countDecimal) {
decimalCount++;
}
if (ch == SIGN) {
continue;
} else if (ch == POINT) {
countDecimal = true;
decimalCount--; // 소수점 자체는 숫자가 아니므로 보정
} else {
stack.push(ch - '0');
}
}
float sum = 0f;
int size = stack.size();
for (int i = 0; i < size; i++) {
int number = stack.pop();
sum += (float) (number * Math.pow(10, -1 * decimalCount));
decimalCount--;
}
return isMinus ? -sum : sum;
}
}복잡도
- 스택에 push:
O(n) - 스택에서 pop하며 계산:
O(n) - 전체:
O(n)
마무리
이 문제의 포인트는 “문자열 파싱을 단계별로 분리하는 능력”입니다.
- 부호 처리
- 소수점 위치 처리
- 자리값 계산
실무에서는 내장 함수를 쓰는 것이 일반적이지만, 면접에서는 이런 구현을 통해 기본기와 사고 과정을 확인할 수 있습니다.