이틀동안 chapter1을 풀고, 오늘 오전에 첫 시험을 봤다
시험 문제는 2018년 카카오 블라인드 채용 코딩 테스트에서 나온 '방금 그 곡'이 출제 되었다
오전 9시부터 12시까지 풀어야 한다
https://programmers.co.kr/learn/courses/30/lessons/17683?language=java
문제를 읽고, 이 정도는 감이 잡혔다
배열에 들어있는 하나의 문자열을 가져와,
콤마 기준으로 시작시간, 끝난 시간, 노래제목, 악보에 대한 문자열을 가져온다
시작시간과 끝난시간을 빼서 현재 노래가 몇 분정도 실행되었는 지 알아내고
악보의 길이만큼 나눠 악보가 몇 번 반복되었는 지 알아낸다
그 결과값만큼 악보 문자열을 반복시켜 입력값 m이 반복시킨 문자열 안에 포함되어 있는 지 찾아야한다
큰 흐름은 생각해낼 수 있었다
처음으로 막혔던 부분은 샾은 어떻게 구분해야하는지 였다
C# D# 등 알파벳 + # 을 어떻게 하나로 알아보냐가 문제였다
결국 힌트를 참고했다
힌트를 읽어보니 치환을 했다는 것이다..!
샾에 대한 음정을 replace를 이용해 각각 치환했다("C#" -> "c", "D#" -> "d", ...)
입력값 m도 모두 치환해줬다
그 다음 막혔던 부분은, 시간을 계산할 때 DateTime을 사용해서 계산했지만,
프로그래머스에서 코드를 실행할 때 에러가 났다
로컬에서 실행할 때는 정상적으로 실행되었다
// SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm");
// long startTime = dateFormat.parse(s.split(",")[0]).getTime();
// long endTime = dateFormat.parse(s.split(",")[1]).getTime();
// long minute = (endTime - startTime) / 60000;
이 방법 말고, 시작시간과 끝난시간을 ":"기준으로 잘라와 시/분 따로 얻어내고,
'끝난시간 시'에서 '시작시간 시'를 뺀 다음 60을 곱했다
또한 '끝난시간 분'에서 '시작시간 분'을 뺀 다음, 계산한 결과값 두 개를 더해줬다
또 막혔던 부분은..!
예를 들어 음계가 8개인데, 실행된 시간은 7분일 경우 어떻게 해야되는 지 막혔었다
악보가 "ABBDBAEF"이고, 실행 시간은 7분이면, 실행된 음정은 "ABBDBAE"인 것이다
이걸 어떻게 해야되는 지 모르겠어서 결국 풀이를 봐버렸다
https://youngest-programming.tistory.com/588
풀이를 보니, 어렵지 않았다
실행된 시간만큼 반복문을 돌리는데
charAt을 사용해서 루프변수를 악보의 길이만큼 나눈 나머지의 값을 매개변수로 넣어
악보의 문자를 하나하나 가져와 이어붙인다
StringBuilder sb = new StringBuilder();
for(int i=0; i<time; i++) {
sb.append(replaceAllSheet.charAt(i % replaceAllSheet.length()));
}
String allSheet = sb.toString();
코드를 작성하고 제출을 했는데, 30개의 테스트 케이스 중 4개의 테스트 케이스를 통과하지 못했다
어떤 것이 문제인지 전혀 모르겠어서, 그냥 제출했다
시험이 끝난 뒤 팀원분께 내 코드의 문제점을 여쭤봤다
팀원분도 여기저기 짚어주시면서 수정하고 재실행을 해봐도 모든 테스트케이스를 통과하지 못하고 있었다
결국 찾아냈다 이 부분이 문제였다
if(allSheet.contains(mReplace)) {
if(max < allSheet.length()) {
max = allSheet.length();
answer = name;
}
}
if(answer.equals("")) {
answer = "(None)";
}
특히 allSheet.length() 이 부분이 문제였다
이 부분을 time으로 바꾸니까 모든 테스트 케이스를 통과했다
왜 다른건지 모르겠다
time은 시작시간과 끝난시간을 계산한 결과이다
String[] start = s.split(",")[0].split(":"); // 시작시간
String[] end = s.split(",")[1].split(":"); // 종료시간
int hour = (Integer.parseInt(end[0]) - Integer.parseInt(start[0])) * 60;
int minute = Integer.parseInt(end[1]) - Integer.parseInt(start[1]);
int time = hour + minute;
이해가 안 가는 이유는
allSheet는 time만큼 반복문을 돌려 만든 악보이기 때문에
time과 allSheet의 길이값이 같을 것이라고 생각하기 때문이다
그래서 나는 통과 못한 테스트케이스의 값을 너무 알고 싶다...
그것만 알면 해결될텐데..ㅠ
오늘은 너무 하기 싫어서 집중이 안 됐다
이틀동안 여덟문제를 푸는 동안 좀 힘들었다
더 어려울 것 같아 막막했기 때문인 것 같다
그래도 괄호 문제는 이전에 풀었던 것이라서
나름 금방 풀 줄 알았지만
하루종일 풀었다
로컬에서 실행할 때는 잘 실행되었지만
코드를 제출했을 때 계속 틀렸다고 떴다
도저히 어느 부분이 문제인지 모르겠어서 팀원분한테 도와달라고 했다
첨에 나는 이렇게 짰었다
맨 첫번째에 있는 문자를 스택에 넣는데
닫는 괄호(')')일 때 바로 "NO"를 리턴시키고
닫는 괄호가 아닐 때 스택에 push한다
첫번째 문자부터 문자열의 길이만큼 로직을 반복하는데
열린 괄호('(')일 때는 push하고
아니면
닫는 괄호이면서 스택이 비어있을 때 "NO"를 리턴시킨다
위의 경우가 아닐 때 push를 한다
로직 반복을 마친 뒤
스택이 비어있으면 "YES"를 리턴하고
스택이 비어있지 않으면 "NO"를 리턴한다
여기서 문제되는 곳이 반복문 안의 로직이다
닫는 괄호이면서 스택이 비어있을 때 "NO"를 리턴시킨다
위의 경우가 아닐 때 push를 한다
if(c == ')' && stack.empty()) return "NO"
else stack.push(c)
이렇게 짰었다
else에서도 더 세부적으로 나눴어야 했던 것 같다
결국 아래 코드처럼 바꿨다
Chapter2 : 자료구조
- A) 괄호