오늘의 키워드
•
문자열 처리
•
단계별 구현
•
정규 표현식
문제 파악 및 풀이
•
문제는 총 7단계로 이루어진 문자열 처리 문제다.
•
단순 구현으로 접근했지만, 조건을 놓친 부분이 많아 여러 테스트케이스에서 실패했고, 하나하나 조건을 추가해가며 수정하느라 시간이 오래 걸렸다.
•
특히 마침표 연속 처리, 시작/끝 마침표 제거, 문자열 길이 조건 등에서 헷갈리는 부분이 많았다.
나의 풀이 코드
import java.util.*;
class Solution {
public String solution(String new_id) {
String answer = "";
// 1단계
new_id = new_id.toLowerCase();
// 2, 3단계
int len = new_id.length();
boolean isDot = false;
for (int i = 0; i < len; i++) {
char c = new_id.charAt(i);
if (isDot && c == '.') {
continue;
}
if (c == '.') {
isDot = true;
answer += c;
}
if (c == '-' || c == '_' || Character.isDigit(c) || Character.isLowerCase(c)) {
isDot = false;
answer += c;
}
}
// 4단계
len = answer.length();
String temp = "";
for (int i = 0; i < len; i++) {
char c = answer.charAt(i);
if (c == '.') temp += '.';
else break;
}
answer = answer.replaceFirst(temp, "");
len = answer.length();
for (int i = len - 1; i >= 0; i--) {
char c = answer.charAt(i);
if (c != '.') {
answer = answer.substring(0, i + 1);
break;
}
}
// 5단계
if (answer.length() == 0) {
answer = "a";
}
// 6단계
if (answer.length() >= 16) {
answer = answer.substring(0, 15);
}
// 4단계 재확인 (끝 마침표)
len = answer.length();
for (int i = len - 1; i >= 0; i--) {
char c = answer.charAt(i);
if (c != '.') {
answer = answer.substring(0, i + 1);
break;
}
}
// 7단계
len = answer.length();
if (len <= 2) {
char c = answer.charAt(len - 1);
while (len++ < 3) {
answer += c;
}
}
return answer;
}
}
Java
복사
시간 복잡도
•
O(N)
◦
문자열 길이 N에 대해 한 번씩 순회하며 조건을 확인하므로 O(N)
오늘의 회고
어려웠던 점
•
조건이 많은 문자열 문제는 구현 시 실수가 자주 발생했고, 작은 누락이 전체 실패로 이어졌다.
•
테스트케이스 기반 디버깅이 오래 걸려 비효율적이었다.
개선점
•
다음에는 정규 표현식 기반으로 더 간결하게 구현해보고 싶다.
•
문자열 문제는 반드시 조건을 정리한 뒤, 단계별로 확실하게 구현하는 습관이 필요하다.
참고할 만한 코드 (가독성 우수)
class Solution {
public String solution(String new_id) {
String s = new KAKAOID(new_id)
.replaceToLowerCase()
.filter()
.toSingleDot()
.noStartEndDot()
.noBlank()
.noGreaterThan16()
.noLessThan2()
.getResult();
return s;
}
private static class KAKAOID {
private String s;
KAKAOID(String s) {
this.s = s;
}
private KAKAOID replaceToLowerCase() {
s = s.toLowerCase();
return this;
}
private KAKAOID filter() {
s = s.replaceAll("[^a-z0-9._-]", "");
return this;
}
private KAKAOID toSingleDot() {
s = s.replaceAll("[.]{2,}", ".");
return this;
}
private KAKAOID noStartEndDot() {
s = s.replaceAll("^[.]|[.]$", "");
return this;
}
private KAKAOID noBlank() {
s = s.isEmpty() ? "a" : s;
return this;
}
private KAKAOID noGreaterThan16() {
if (s.length() >= 16) {
s = s.substring(0, 15);
}
s = s.replaceAll("[.]$", "");
return this;
}
private KAKAOID noLessThan2() {
StringBuilder sBuilder = new StringBuilder(s);
while (sBuilder.length() <= 2) {
sBuilder.append(sBuilder.charAt(sBuilder.length() - 1));
}
s = sBuilder.toString();
return this;
}
private String getResult() {
return s;
}
}
}
Java
복사