
나는 이 문제를.. AtoI응용이라고 생각했다. 그래서 String의 숫자를 int로 바꾸고, 두자리씩 끊어서 계산을 했다.
1. String을 int로 바꾸기
ex) 20:00:00 -> 200000
2. 2자리씩 끊어서 뺄셈
2-1. int로 바꾼 시작시간이 끝나는 시간보다 크거나 같은 경우 끝나는 시간에 240000을 더해준다.
ex) start: 20:00:00, end: 04:00:00 -> intStart: 200000, intEnd: 40000 -> intStart가 intEnd보다 큼 -> intEnd+=240000, intEnd는 280000이 됨
2-2. 초/분/시 순으로 나눠서 뺄셈을 한다. 시작값이 끝나는 값보다 큰 경우, 끝나는 값에 60을 더해주고 flag를 1로 만들
어준다. flag는 앞자리에서 하나 내림했다는 표시이다. (2-1.에서 끝나는 값이 더 작은 경우 240000를 더했기 때문에 시
는 항상 끝나는 값이 더 크다. 그러므로 초와 분에서만 내림이 발생한다.)
2-3. 이렇게 초/분/시 순으로 구한 값을 8자리(혹은7자리)의 정수가 될 수 있도록 자리수에 가중치를 곱해서 더해준다.
3. 만들어진 차이 정수값을 다시 String으로 만들어준다.
+설명이 난해한 것 같아서 패드에 필기한것 추가. 근데 이것도 난해해 보인다.....

import java.util.Scanner;
public class BOJ13223 {
public static int AtoI(String str){ // String을 int로 변환
int i = 0, num = 0;
char ch;
while(i<str.length()){
ch = str.charAt(i);
if(ch>='0'&&ch<='9'){
num = num*10 + (ch - '0');
}
i++;
}
return num;
}
public static int calcTime(int sTime, int eTime){ // 초/분/시 순으로 차이를 계산
int result = 0, s, e, i, flag = 0, comma = 1;
if(eTime <= sTime) // 끝나는 시간이 더 작은경우
eTime += 240000;
for(i=0;i<3;i++){ //
// 두자리씩 비교, for문을 돌면서 초/분/시 를 각각 계산한다.
s = sTime % 100;
sTime = sTime / 100;
e = eTime % 100;
eTime = eTime / 100;
if(flag == 1){
e -= 1;
flag = 0;
}
if(s > e){
e += 60;
flag = 1;
}
result += (e - s) * comma; // 8(혹은7)자리가 되도록 가중치를 곱해서 합해줌
comma *= 100;
}
return result;
}
public static String addZero(String str){ // String 변환시 0더해줌
if(str.length() == 1)
str = "0"+ str;
return str;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String start, end, result, hh, mm, ss;
int sTime, eTime, value;
start = sc.next();
end = sc.next();
sTime = AtoI(start);
eTime = AtoI(end);
value = calcTime(sTime, eTime);
// String으로 바꾸기
ss = (value % 100) + "";
mm = ((value % 10000)/100) + "";
hh = (value/10000) + "";
// String으로 바꾸는 과정에서 한 자리수인 경우, 앞의 0이 사라지므로 더해줘야함
ss = addZero(ss);
mm = addZero(mm);
hh = addZero(hh);
result = hh + ":" + mm + ":" + ss;
System.out.println(result);
}
}
addZero함수는 int를 String으로 만드는 과정에서 사라지는 0을 더해주는 함수이다. 예를 들면 정답이 "04:00:00" 인 경우, 내 코드에서 calcTime으로 반환된 value의 값은 40000이다. 나머지연산과 나누기 연산을 하면 ss = "0", mm = "0", hh = "4"가 될것이다. 이 값을 바로 String으로 만들면 "4:0:0"이 될것이다. 그래서 String이 한 글자인 경우에 앞에 "0"을 더해주는 함수인 addZero를 만들었다. 이렇게하면 "04:00:00" 이라고 나온다. 정답이 "12:34:56"이고 value가 123456인 경우에는 ss = "56", mm = "34", hh = "12" 가 되므로 addZero에서 별 다른 연산없이 바로 리턴될 것이다.
또 다른 방법(1.13 추가)
원리는 같다. 다만 String을 통으로 int로 만들지 않고 시, 분, 초를 나눠서 int로 만들었다. 예를들면 "12:34:56"이면 hh = 24, mm = 34, ss = 56 즉, 두자리 숫자로 만들고 계산했다. 자세한 내용은 코드에 주석으로 적어놓았다.
public static void main(String[] args) {
String start, end;
int sHour, sMinute, sSecond, eHour, eMinute, eSecond;
Scanner sc = new Scanner(System.in);
start = sc.next();
end = sc.next();
// 1. ':'를 기준으로 시간, 분, 초를 쪼개기
// 1-1) 시,분,초가 정해져있으므로 직관적으로 계산
/*sHour = (start.charAt(0) - '0') * 10 + (start.charAt(1) - '0');
sMinute = (start.charAt(3) - '0') * 10 + (start.charAt(4) - '0');
sSecond = (start.charAt(6) - '0') * 10 + (start.charAt(7) - '0');
eHour = (end.charAt(0) - '0') * 10 + (end.charAt(1) - '0');
eMinute = (end.charAt(3) - '0') * 10 + (end.charAt(4) - '0');
eSecond = (end.charAt(6) - '0') * 10 + (end.charAt(7) - '0');*/
// 1-2) substring 이용, 결과가 string이므로 int로 변환해준다.
/*sHour = Integer.parseInt(start.substring(0,2));
sMinute = Integer.parseInt(start.substring(3,5));
sSecond = Integer.parseInt(start.substring(6,8));
eHour = Integer.parseInt(end.substring(0,2));
eMinute = Integer.parseInt(end.substring(3,5));
eSecond = Integer.parseInt(end.substring(6,8));*/
// 1-3) split 이용, 마찬가지로 int로 변환
String[] sTime = start.split(":");
String[] eTime = end.split(":");
sHour = Integer.parseInt(sTime[0]);
sMinute = Integer.parseInt(sTime[1]);
sSecond = Integer.parseInt(sTime[2]);
eHour = Integer.parseInt(eTime[0]);
eMinute = Integer.parseInt(eTime[1]);
eSecond = Integer.parseInt(eTime[2]);
// 2. 시간, 분, 초의 차이를 계산
// 2-1) 각각 뺄셈하고 음수인 경우에 더 큰 단위에서 내림한다.
/*int needSecond, needMinute, needHour;
needSecond = eSecond - sSecond;
needMinute = eMinute - sMinute;
needHour = eHour - sHour;
if(needSecond < 0) {
needSecond += 60;
needMinute--;
}
if(needMinute < 0) {
needMinute += 60;
needHour--;
}
if(needHour <= 0)
needHour += 24;*/
// 2-2) 작은 단위(초)로 바꾸고 한 번에 계산
int sSecondAmount = sHour * 3600 + sMinute * 60 + sSecond;
int eSecondAmount = eHour * 3600 + eMinute * 60 + eSecond;
int needSecondAmount = eSecondAmount - sSecondAmount;
if(needSecondAmount <= 0)
needSecondAmount += 24*3600;
needHour = needSecondAmount / 3600;
needMinute = (needSecondAmount % 3600) / 60;
needSecond = needSecondAmount % 60;
// 3. 출력하기
System.out.printf("%02d:%02d:%02d", needHour, needMinute, needSecond);
}
'코딩가딩가' 카테고리의 다른 글
| [JAVA]배열 (1) | 2024.03.23 |
|---|---|
| [JAVA]BOJ 10158 (1) | 2024.01.16 |
| [JAVA]BOJ 1543 (0) | 2024.01.04 |
| [JAVA]BOJ 1157 (0) | 2024.01.02 |
| [JAVA]BOJ 1919 (0) | 2024.01.01 |