Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- 람다
- 스프링 고급 - 스프링 aop
- 스프링 입문(무료)
- 자바의 정석 기초편 ch4
- 자바의 정석 기초편 ch2
- 스프링 mvc2 - 검증
- 자바의 정석 기초편 ch12
- 자바의 정석 기초편 ch1
- 자바로 계산기 만들기
- 스프링 mvc2 - 로그인 처리
- 자바 중급2편 - 컬렉션 프레임워크
- 자바 고급2편 - io
- 스프링 트랜잭션
- 자바의 정석 기초편 ch9
- 스프링 mvc1 - 스프링 mvc
- 2024 정보처리기사 수제비 실기
- 자바의 정석 기초편 ch6
- 자바 기초
- 2024 정보처리기사 시나공 필기
- 자바의 정석 기초편 ch13
- 데이터 접근 기술
- 자바 중급1편 - 날짜와 시간
- 자바의 정석 기초편 ch11
- 자바 고급2편 - 네트워크 프로그램
- 자바의 정석 기초편 ch7
- 자바의 정석 기초편 ch5
- 자바로 키오스크 만들기
- @Aspect
- 스프링 mvc2 - 타임리프
- 자바의 정석 기초편 ch14
Archives
- Today
- Total
개발공부기록
Java - 양수의 개수와 덧셈, 문자열 내림차순으로 배치하기, 부족한 금액 계산하기, 문자열 다루기 기본 / SQL(MySQL) - 입양 시각 구하기, 자동차 종류별 특정 옵션이 포함된 자동차 수 구하기 본문
기타 개발 공부/온라인 코딩 테스트 회고
Java - 양수의 개수와 덧셈, 문자열 내림차순으로 배치하기, 부족한 금액 계산하기, 문자열 다루기 기본 / SQL(MySQL) - 입양 시각 구하기, 자동차 종류별 특정 옵션이 포함된 자동차 수 구하기
소소한나구리 2025. 3. 10. 13:25728x90
Java
양수의 개수와 덧셈
문제
- 프로그래머스 - https://school.programmers.co.kr/learn/courses/30/lessons/77884
- 두 정수 left와 right가 매개변수로 주어질 때 left 부터 right 까지의 모든 수들 중에서 약수의 개수가 짝수인 수는 더하고, 약수의 개수가 홀수인 수는 뺀 수를 return하는 함수 완성
제한조건
- 1 <= left <= right <= 1,000
입출력 예시
나의 풀이
class Solution {
public int solution(int left, int right) {
int answer = 0;
for (int i = left; i <= right; i++) {
int count = 0;
for (int j = 1; j <= i; j++) {
if (i % j == 0) {
count++;
}
}
answer += count % 2 == 0 ? i : -i;
}
return answer;
}
}
- 수학을 잘 모르기 때문에 단순히 left 부터 right 까지의 수를 차례로 사용해야하므로 for 문을 사용하였다, 이 때 마지막 수인 right도 사용해야 하므로 i <= right로 조건문을 입력하였다.
- 첫 번째 반복문의 i의 값이 약수의 개수를 계산해야할 값이므로 다시한번 반복문을 통해서 i의 값을 1부터 i의 값까지 1씩 증가시키며 나머지 연산을 수행하고 나누어 떨어지면 count++을 통해 개수를 증가시켰다.
- 조건에 약수의 개수가 짝수인 수는 더하고 약수의 개수가 홀수인 수는 빼라는 요구조건에 따라 삼항 연산자로 값을 연산한 후 반환시켜서 문제를 해결했다.
다른 풀이
class Solution {
public int solution(int left, int right) {
int answer = 0;
for (int i=left;i<=right;i++) {
//제곱수인 경우 약수의 개수가 홀수
if (i % Math.sqrt(i) == 0) {
answer -= i;
}
//제곱수가 아닌 경우 약수의 개수가 짝수
else {
answer += i;
}
}
return answer;
}
}
- 접근법은 비슷한 것 같은데, 약수를 구하고자 하는 수의 제곱수를 나누었을 때 나머지가 0이면 약수의 개수가 홀수라는 사실을 처음알게 되었다
- 이러면 반복문을 한번더 강제적으로 사용하지 않기 때문에 성능이 좋아지므로 알아두면 좋은 것 같다.
문자열 내림차순으로 배치하기
문제
- 프로그래머스 - https://school.programmers.co.kr/learn/courses/30/lessons/12917
- 주어진 문자열의 요소를 큰것부터 작은 순으로 정렬해 새로운 문자열을 리턴하는 함수를 완성
- 문자열은 영문 대소문자로만 구성되어 있으며 대문자는 소문자보다 작은 것으로 간주함
제한조건
- 주어진 문자열은 길이가 1이상인 문자열임
입출력 예시
나의 풀이
class Solution {
public String solution(String s) {
char[] charArr = s.toCharArray();
Arrays.sort(charArr);
for (int i = 0; i < charArr.length / 2; i++) {
char temp = charArr[i];
charArr[i] = charArr[charArr.length - i - 1];
charArr[charArr.length - i - 1] = temp;
}
return new String(charArr);
}
}
- 문자열을 문자 배열로 변환해서 정렬 로직이 최적화 되어있는 Arrays.sort()를 사용하여 오름차순으로 정렬한 다음 내림차순으로 정렬을 위해 문자 배열을 반복문으로 뒤집었다.
- 이때 반복문을 문자 배열의 절반만큼만 반복해도 되는데, 그 이유는 한번 반복할 때마다 배열의 맨 처음과 맨 끝에 있는 값을 서로 바꿔주기 때문이다.
- 즉, 배열의 첫 번째 값과 맨 끝에 값을 교환하고 다음 반복문에서는 두 번째 값과 맨 끝에서 두 번째 값을 비교하게 되면서 반복 횟수를 줄일 수 있게 된다.
- 실제로 이렇게 접근할 때 처음에는 반복문을 끝까지 해서 뒤집었지만 이 효율적인 방법은 검색을 통해서 알게 되었다
다른 풀이
class Solution {
public String solution(String s) {
String[] strArr = s.split("");
Arrays.sort(strArr, Collections.reverseOrder());
StringBuilder sb = new StringBuilder();
for (String str : strArr) {
sb.append(str);
}
return sb.toString();
}
}
- 주어진 문자열을 split("")으로 문자열을 한 단어씩 분할하여 문자열 배열로 만들어서, Arrays.sort(문자열 배열, Collections.reverseOrder())를 통해 문자열 배열을 내림차순으로 정렬 한다
- 내림차순으로 정렬된 문자열 배열을 하나의 문자열로 합치기 위해 StringBuilder를 사용하여 append로 각 요소를 하나의 문자열로 합치고 반환 타입이 String이므로 toString()으로 변환한다
- 이때 StringBuilder를 사용하지 않고 String.join("", strArr)을 통해서 문자열 배열을 모두 합칠 수도 있으며 코드가 간결하여 자주 사용한다고 한다
- join()은 첫 번째 인자에 구분자, 두 번째 인자에 합칠 문자열 배열을 입력하여 구분자로 문자열 배열의 요소를 합치는 메서드인데, 지금 처럼 첫 번째 인자에 빈 문자열을 입력해주면 단순히 문자열 배열을 순서대로 하나의 문자열로 합치는 결과를 얻을 수 있다
- join()도 내부적으로 StringBuilder를 사용하기 때문에 성능차이는 없으므로 문자열 배열의 요소를 하나로 합칠 때 유용하게 사용할 수 있을 것 같다
- ai툴에게 문의한 결과 이 방법은 split()을 할 때 오버헤드가 발생할 수 있으므로 나의 풀이의 방법이 해당 방법보다 성능이 더 좋다고 한다.
class Solution3 {
public String solution(String s) {
return s.chars().mapToObj(num -> (char) num)
.sorted(Collections.reverseOrder())
.map(String::valueOf)
.collect(Collectors.joining());
}
}
- Stream API를 활용한 풀이로 문자열을 chars() 메서드를 활용하여 각 문자열의 단어를 아스키코드로 변환한 스트림으로 생성한다.
- 그 이후 mapToObj()를 각 아스키 코드 값을 문자로 변환한 다음 Collections.reverseOrder()를 통해 내림차순으로 정렬하고, .map을 통해 각 요소를 String으로 변환한다.
- 그다음 최종연산인 collect()를 통해서 Collectors.joining()으로 문자열인 각 요소를 합쳐서 반환한다.
- 풀이의 3가지 방식 모두 시간복잡도는 동일하지만 스트림 API를 활용하는 방법이 코드는 간결해보여도 가장 성능이 느리다
- sorted()를 사용하기 위해 객체로 변환하는 과정과 각 요소를 다시 String으로 변환하는 과정, 그리고 그 문자열들을 하나의 문자열로 합치는 과정으로 중간연산의 과정이 위 2가지의 방식보다 더 많기 때문이다.
부족한 금액 계산하기
문제
- 프로그래머스 - https://school.programmers.co.kr/learn/courses/30/lessons/82612
- 시설을 이용할 때마다 이용료인 price가 N배만큼 증가할 때 제시되는 count의 횟수 만큼 이용했을 때 본인이 가지고 있는 금액인 money에서 얼마가 모자라는지 return 하는 함수를 완성
- 금액이 부족하지 않으면 0을 return
- 이용료가 만약 100원이고 3번 이용했다면 100, 200원, 300원으로 이용요금이 올라감
제한조건
- price: 1 ~ 2,500의 자연수
- money: 1 ~ 1,000,000,000의 자연수
- count: 1 ~ 2,500의 자연수
입출력 예시
나의 풀이
class Solution {
public long solution(int price, int money, int count) {
long sumPrice = 0;
for (int i = 1; i <= count; i++) {
sumPrice += (long) price * i;
}
return money - sumPrice >= 0 ? 0 : Math.abs(money - sumPrice);
}
}
- count번 시설을 이용했을 때의 금액을 구하기 위해 반복문을 활용하였다.
- 처음 가격인 price에 반복 횟수만큼 i를 곱한 값을 count번 더해서 count만큼 시설을 이용했을 때 비용을 계산했다.
- 이후 3항연산자를 이용하여 내가 가진돈과 계산된 비용을 뺄쎔 연산하여 내 돈이 남으면 0을 return하고 내돈이 부족하면 얼마나 부족한지 절대값으로 반환하기 위해 Math.abs()함수를 사용하여 값을 반환시켜 문제를 해결했다
- Math.abs를 쓰지 않고 -를 곱해서 반환해도 되고 그냥 명시적으로 sumPrice - money로 반환하는 등 조건을 입력하는 방법은 다양하다
다른 풀이
class Solution {
public long solution(long price, long money, long count) {
return Math.max(price * (count * (count + 1) / 2) - money, 0);
}
}
- 문제에서 메서드의 매개변수가 int이지만 매개변수를 처음부터 long으로 받아버리면 어차피 더 작은 int 타입은 들어올 수 있게 된다.
- 여기서는 등차수열 합 공식을 활용하여 놀이기구를 이용했을 때의 총 비용을 구했다
- price * (count * (count + 1) / 2)
- 그 이후 구해진 금액과 내가 가진 돈인 money를 제외하게 되었을 때 내가가진 돈이 많으면 음수가되고, 금액이 부족하면 부족한 금액이 구해진다
- Math.max()메서드는 주어진 2개의 인자 중 큰 값을 반환하기 때문에 만약 음수인 경우 0이 더 크므로 0이 반환되고, 금액이 부족한 경우 부족한 금액이 0보다 더 크므로 그대로 값이 반환되게 된다.
문자열 다루기 기본
문제
- 프로그래머스 - https://school.programmers.co.kr/learn/courses/30/lessons/12918
- 주어진 문자열의 길이가 4또는 6이고 숫자로만 구성되어있는지 확인해주는 함수를 작성
제한조건
- 문자열의 길이는 1 ~ 8이며 영문 알파벳 대소문자 혹은 0 ~ 9까지의 숫자로 이루어져있음
입출력 예시
나의 풀이
class Solution {
public boolean solution(String s) {
if (s.length() != 4 && s.length() != 6) {
return false;
}
char[] charArr = s.toCharArray();
for (char c : charArr) {
if (c - 48 > 10) {
return false;
}
}
return true;
}
}
- 먼저 첫 번째 예외처리를 하기 위해서 길이가 4, 6이 아닌 문자열인 경우 바로 false를 반환하고, 아스키 코드값을 활용하기 위해 검증을 넘어간 문자열은 toCharArray()를 활용하여 문자 배열로 변환했다.
- 여기서 문자 배열을 순회하여 각 문자에 -48 연산을 한 값이 10보다 크면 숫자인 문자열이 아니므로 바로 더 순회할 필요 없이 바로 return을 반환하도록 하였고, 순회를 정상적으로 돌면 ture를 반환하도록 하여 문제를 해결했다.
다른 풀이
class Solution {
public boolean solution(String s) {
return (s.length() != 4 && s.length() != 6) || (s.split("[0-9]").length > 0) ? false:true;
}
}
- 확실히 문자열은 정규식을 활용하면 매우 간단히 문자열을 다룰 수 있다.
- 3항연산자의 조건으로 문자열의 길이가 4와 6이 아니고 s를 0 ~ 9 사이의 숫자로 나누었을 때 길이가 1 이상이면 숫자값이 아닌 다른 문자열이 들어있는 것이므로 false를 반환하고 그 외의 상황에서는 true를 반환하는 방식으로 해결하는 풀이가 매우 신선했다.
class Solution {
public boolean solution(String s) {
if (s.length() == 4 || s.length() == 6) return s.matches("(^[0-9]*$)");
return false;
}
}
return s.matches("^(\\d{4}|\\d{6})$");
return s.matches("[0-9]{4}|[0-9]{6}");
- 이 풀이 처럼 matches를 활용하여 문자열이 정규식과 일치하는지 여부를 반환할 수도 있다
- 길이 검증조차도 정규식으로 가능하기 때문에 어느정도 기본적인 정규식은 알아두면 유용할 것 같다.
SQL(MySQL)
입양 시각 구하기
문제 및 테이블 예시
- ANIMAL_OUTS 테이블에서 09:00 부터 19:59까지 각 시간대 별로 입양이 몇 건이나 발생했는지 조회하는 SQL문을 작성
- 결과는 시간대 순으로 정렬해야 함
입출력 예시
나의 풀이
SELECT
DATE_FORMAT(DATETIME, "%H") AS HOUR,
COUNT (ANIMAL_ID) AS COUNT
FROM ANIMAL_OUTS
WHERE
HOUR(DATETIME) >= 9 AND HOUR(DATETIME) < 20
GROUP BY
HOUR
ORDER BY
HOUR
- DATE_FORMAT()의 입력 순서가 햇갈려서 한번더 검색을 했다. 처음이 컬럼, 두번째가 조회할 포맷이라는 것을 한번더 상기 시켰다
- 이후 요구 조건에 따라 WHERE절에 HOUR(컬럼)으로 9시00분 부터 20시 미만(19시59분)까지로 작성하고 갯수를 구하기 위해 조회문에서 별칭으로 지정한 HOUR를 기준으로 GROUP BY를 하여 문제를 해결 했다
- 날짜 타입 걸럼에서 각 시간을 조회하는 HOUR() 함수 외에도 MINUTE(), SECOND()함수도 있다
- WHERE 절에 함수 없이 조회할 범위의 날짜를 직접 입력해도 되고 BETWEEN 함수를 사용해도 된다.
자동차 종류 별 특정 옵션이 포한된 자동차 수 구하기
문제 및 테이블 예시
- CAR_RENTAL_COMPANY_CAR 테이블에서 '통풍시트', '열선시트', '가죽시트' 중 하나 이상의 옵션이 포함된 자동차가 종류별로 몇 대 인지 출력하는 SQL문 작성
- 자동차 수에 대한 컬럼명은 CARS로 지정하고 결과는 자동차 종류를 기준은로 오름차순 정렬
입출력 예시
나의 풀이
SELECT
CAR_TYPE,
COUNT(*) AS CARS
FROM
CAR_RENTAL_COMPANY_CAR
WHERE
OPTIONS LIKE '%가죽시트%' OR OPTIONS LIKE '%열선시트%' OR OPTIONS LIKE '%통풍시트%'
GROUP BY
CAR_TYPE
ORDER BY
CAR_TYPE
- 한 컬럼에 여러 조건을 검색하기 위해서 LIKE와 OR 키워드를 사용하여 해당 문자가 포함되어있는지 확인하도록 쿼리를 작성하였음
- 다른 풀이를 찾아보니 WHERE 에서 '시트'관련된 옵션만 찾기 때문에 '%시트%' 로 검색해도 동일한 결과가 나오기 때문에 이렇게 조금더 간단하지만 명확하게 조건문을 작성하는 생각을 한번더 필요해 보임
728x90