Day 23 배열, 정렬, 문자열
Day23 23단계 2023-11-13
1. 특이한 정렬
- 내 풀이 : Arrays.sort(T[] t, Comparator)를 사용하고 싶어서 Integer 배열로 변환 후 다시 int 배열로 변경했다.
- 생각해보니 어차피 타입 변환할 때 Stream을 사용하는데, 그냥 Stream에서 정렬을 했으면 번거롭지 않았을 듯 하다.
- 덕분에 처리 시간이 오래 걸린다...
import java.util.Arrays;
class Solution {
public int[] solution(int[] numlist, int n) {
Integer[] boxlist = Arrays.streamnew;
Arrays.sort(boxlist, (a, b)-> {
int diff1 = Math.abs(a-n);
int diff2 = Math.abs(b-n);
if(diff1==diff2) return b - a;
return diff1-diff2;
});
return Arrays.stream(boxlist).mapToInt(x->x).toArray();
}
}
- 다른 사람 풀이 : 위 과정을 int 배열의 요소 비교로 구현했다.
- 다른 사람 풀이 원본 : https://school.programmers.co.kr/learn/courses/30/lessons/120880/solution_groups?language=java
- 위의 내 풀이를 다른 사람의 풀이 메커니즘을 보고 다시 코드를 수정한 후 두 코드의 속도를 비교했다.
import java.util.Arrays;
class Solution {
public int[] solution(int[] numlist, int n) {
for (int i = 0; i < numlist.length - 1; i++) {
for (int j = 0; j < numlist.length - 1 - i; j++) {
int a = Math.abs(numlist[j]-n);
int b = Math.abs(numlist[j+1]-n);
if (a > b || (a == b && numlist[j] < numlist[j+1])) {
int temp = numlist[j+1];
numlist[j+1] = numlist[j];
numlist[j] = temp;
}
}
}
return numlist;
}
}

2. 등수 매기기
- 내 풀이 : score 2차 배열 요소의 합을 넣을 int 배열과 순위를 저장할 int 배열을 만든다.
- 먼저 순위 배열인 answer에 1을 채워 넣어 1부터 숫자가 올라가도록 한다.
- 평균을 넣을 배열에 score 2차 배열 요소의 합을 넣는다.(원래 평균을 넣었다가 2로 나눈 과정을 뺐다.)
- 평균 배열의 각 요소에 대해 다른 요소들과 비교해서 해당 요소가 작다면 그 요소와 동일한 index의 answer 배열 요소를 1 추가했다.
import java.util.Arrays;
class Solution {
public int[] solution(int[][] score) {
int[] avg = new int[score.length];
int[] answer = new int[score.length];
Arrays.fill(answer, 1);
for (int i = 0; i < score.length; i++) {
avg[i] = score[i][0] + score[i][1];
}
for (int i = 0; i < avg.length; i++) {
for (int j = 0; j < avg.length; j++) {
if (avg[i] < avg[j]) {
answer[i]++;
}
}
}
return answer;
}
}
- 다른 사람 풀이 : List에 score 2차 배열 요소의 합을 넣은 뒤 내림차순 정렬을 진행했다.
- 그 후 int 배열 answer에서 list의 배열 요소를 indexOf()로 가져온다.
- indexOf()는 중복으로 뜨는 숫자가 존재하더라도 배열에서 처음 등장한 index를 반환하므로 중복 제거가 쉽다.
List<Integer> list = new ArrayList<>();
for(int[] i : score) {
list.add(i[0]+i[1]);
}
list.sort(Comparator.reverseOrder());
int[] answer = new int[score.length];
for (int i = 0; i < score.length; i++) {
answer[i] = list.indexOf(score[i][0]+score[i][1]) + 1;
}
return answer;
- 문득 이중 for문을 사용한 경우와 List를 사용한 경우 중 누가 더 빠른지 궁금해서 비교해봤다.
- 비교를 위해 다른 사람이 쓴 코드의 원본을 첨부했다.
- int 배열 2개와 이중 for문을 사용한 결과가 더 빠르게 나왔다.
- 이중 for문때문에 List보다 속도가 느리지 않을까 생각했는데, int와 Integer의 각 저장 및 참조 위치(?)로 인해 시간 차이가 발생하는 것 같다.
- 다만 코드의 길이는 이중 for문을 사용한 내 코드가 더 길었다.
- 상황에 따라 두 코드 중에 선택해서 사용하면 될 것 같다.
3. 옹알이 (1)
- 내 풀이 : 발음으로 주어진 단어들을 " "(white space)로 변환하고, 만약 그 결과가 비어있거나 공백만 포함한다면 answer를 +1 해준다.
class Solution {
public int solution(String[] babbling) {
String[] pron = {"aya", "ye", "woo", "ma"};
int answer = 0;
String temp = "";
for (int i = 0; i < babbling.length; i++) {
temp = babbling[i].replaceAll(pron[0], " ")
.replaceAll(pron[1], " ")
.replaceAll(pron[2], " ")
.replaceAll(pron[3], " ");
if (temp.isBlank()) {
answer++;
}
else continue;
}
return answer;
}
}
- 다른 사람 풀이 : 정규식 표현을 사용해서 발음 조건에 맞는 경우에만 answer를 +1 해준다.
- String 클래스#4. 생성자와 메소드에서 matches() 메소드, 정규 표현식 사용
int answer = 0;
for (int i = 0; i < babbling.length; i++) {
if (babbling[i].matches("^(aya(?!aya)|ye(?!ye)|woo(?!woo)|ma(?!ma))+$"))
answer++;
}
return answer;
- 정규식 풀이 (챗 gpt)
- 문제의 조건 : babbling의 각 문자열에서 "aya", "ye", "woo", "ma" 는 각각 최대 한 번씩만 등장한다.
- 즉 각 발음이 똑같이 2번 반복되어 나오는 경우는 없다(ex> ayaye 는 나오지만 ayaaya는 안 나온다)
^(aya(?!aya)|ye(?!ye)|woo(?!woo)|ma(?!ma))+$
^ : 문자열의 시작
( : 그룹 시작
aya(?!aya) : 'aya'라는 문자열 다음에 'aya'가 오지 않음
| : 또는
ye(?!ye) : 'ye'라는 문자열 다음에 'ye'가 오지 않음
| : 또는
woo(?!woo) : 'woo'라는 문자열 다음에 'woo'가 오지 않음
| : 또는
ma(?!ma) : 'ma'라는 문자열 다음에 'ma'가 오지 않음
) : 그룹 끝
+ : 그룹이 최소 한 번 이상 반복
$ : 문자열의 끝