생각정리/항해99
[프로그래밍 기초2] Java알고리즘 5일차
생각중임
2023. 8. 24. 21:44
Java알고리즘 시험
2번 문제) Triangular Output
설명) 첫째 줄에 정수 n이 주어진다. (0≤n≤100)
입력 | 결과 |
3 | ***** *** * *** ***** |
5 | ******* ***** *** * *** ***** ******* |
나의 풀이
public class Main {
public void solution(int star) {
// 모래시계 모양의 크기 만큼 반복 (꼭지점은 1개이므로 -1)
for (int i = 0; i < star*2-1; i++) {
if (i < star) { // star가 중간 지점
// i보다 하나 적게 1씩증가시켜 공백 생성
for (int j = 0; j < i ; j++) {
System.out.print(" ");
}
// 총반복 크기에서 2개씩 줄이면서 역피라미드 생성
for (int j = 0; j < star*2-1-i*2; j++) {
System.out.print("*");
}
} else {
// 중간 지점에서 부터 1씩 감소시켜 공백 생성
// 전체 크기에서 star번째가 중간 지점에서 -1한 부분 부터 1씩 감소
for (int j = 0; j < star*2-2-i; j++) {
System.out.print(" ");
}
// 중간 지점 이후에는 무조건 3부터 2씩 증가한다.
// 중간 지점 바로 이후는 딱 i가 star의 크기와 같다.
for (int j = 0; j < i*2+3-star*2; j++) {
System.out.print("*");
}
}
System.out.println();
}
}
public static void main(String[] args) {
Main method = new Main();
int star = 7;
method.solution(star);
}
}
- 모래시계형태의 모양은 피라미드와 역피라미드를 합친 것에 꼭짓점을 하나 버린다고 생각을 하면 모래시계의 크기는 별의 개수 * 2 - 1이라고 할 수 있다.
- 그렇게 크기 만큼 반복하는 for-loop를 만들고 반복을 한다.
- 먼저 역피라미드를 만들고 그 밑에 피라미드 모양으로 만들다고 생각을 하고 역피라미드 모양이 완성되는 star의 크기까지 와 이후로 나누는 if문을 추가한다.
- 역피라미드 모양을 만드는데는 첫 번째 줄에는 모래시계의 크기와 같은 개수의 별이 들어가고 공백은 앞에 하나씩 늘어나고 별은 2개씩 줄어든다.
- 공백을 만드는 for-loop로 i만큼 증가시키고 별을 만드는 for-loop로 전체크기에서 i*2만큼 감소시켜 반복을 하게 되면 역피라미드 모양이 출력된다.
- 이제 피라미드 모양을 만들어주면 되는데 꼭짓점을 제외한 부분부터 출력을 하게 되면 인덱스의 크기가 딱 star의 수와 동일한 위치가 된다. 이때 전체 크기에서 star의 수를 빼면 꼭지점 부분의 공백과 같아 여기서 -1을 더 해주면 피라미드 모양으로 공백을 출력한다.
- 피라미드 모양의 별의 경우 역피라미드 이후에는 무조건 3개부터 시작을 해서 2개씩 늘어나므로, 동일한 i와 star에 *2를 해주면 0이 되고 +3을 해주면 3개부터 시작해서 2개씩 늘어나는 모래시계를 만들 수 있다.
3번 문제) 같은 단어는 싫어!
설명) 배열 arr와 정수 n이 주어집니다. 배열 arr의 각 원소는 문자열로 이루어져 있습니다. 이때, 배열 arr에서 중복되는 단어는 전부 제거하려고 합니다. 단, 제거된 후 남은 단어들을 반환할 때는 각 문자열의 인덱스 n번째 글자를 기준으로 오름차순 정렬하려 합니다.
예를 들어 strings가 ["brush", "sun", "brush", "bed", "car"]이고 n이 1이면 중복을 제거한 배열인 ["sun", "bed", "car"]에서 각 단어의 인덱스 1의 문자 "u", "e", "a"로 strings를 정렬합니다.
제한 조건
- strings는 길이 1 이상, 50이하인 배열입니다.
- strings의 원소는 소문자 알파벳으로 이루어져 있습니다.
- strings의 원소는 길이 1 이상, 100이하인 문자열입니다.
- 모든 strings의 원소의 길이는 n보다 큽니다.
- 인덱스 1의 문자가 같은 문자열이 여럿 일 경우, 사전순으로 앞선 문자열이 앞쪽에 위치합니다.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class Main {
public String[] solution(String[] arr, int n) {
List<String> list = new ArrayList<>();
List<String> del = new ArrayList<>();
// 정렬할 n번째 문자 앞에 붙여서 리스트에 추가
for (int i = 0; i < arr.length; i++) {
list.add(arr[i].substring(n, n + 1) + arr[i]);
}
// 리스트 정렬
Collections.sort(list);
// 문자열의 첫번째 인덱스와 마지막 인덱스를 확인하여 다를 경우 중복된 문자열이 있으므로 del리스트에 추가 해준다.
for (int i = 0; i < list.size(); i++) {
if (list.indexOf(list.get(i)) != list.lastIndexOf(list.get(i))) {
del.add(list.get(i));
}
}
// del리스트에 들어있는 요소들을 list에서 전부 삭제해준다.
list.removeAll(del);
// answer을 list의 크기로 초기화하고 리스트의 요소 앞자리를 제외한 문자열을 answer에 넣어준다.
String[] answer = new String[list.size()];
for (int i = 0; i < list.size(); i++) {
answer[i] = list.get(i).substring(1);
}
return answer;
}
public static void main(String[] args) {
Main method = new Main();
// String[] arr = {"brush", "sun", "brush", "bed", "car"}; int n = 1;
// String[] arr = {"banana", "cat", "car", "apple", "banana", "banana"}; int n = 0;
String[] arr = {"coke", "water", "glass", "dog", "dog", "yogurt", "vitamin"}; int n = 2;
System.out.println(Arrays.toString(method.solution(arr, n)));
}
}
- 문자열을 담을 list와 중복 문자열을 담을 list(del)를 선언하는 방법으로 문제를 풀었다.
- 먼저 정렬해야 되는 n번째 위치의 문자를 해당 문자열 앞에 붙여 하나의 문자열로 list에 담았다.
- 이후 list를 정렬하게 되면 n번째 위치의 문자에 정렬이 되면서 동시에 제한 조건에서의 정렬 규칙도 성립하게 된다.
- list에 담긴 문자열을 하나씩 indexOf()를 이용해 문자열의 첫 번째 위치와 마지막 위치의 인덱스를 찾아서 다를 경우 동일한 문자열이 중복되어 존재하니 del에 넣어준다.
- 중복 문자열을 del에 모두 추가한 뒤 removeAll()을 사용하여 del에 들어있는 요소들을 list에서 모두 삭제해 준다.
- answer배열을 list의 크기만큼 초기화하고 list의 크기만큼 for-loop를 반복하면서 anwer배열에 첫 번째 글자를 제외한 문자열만 추가해 준다.
알고리즘 시험을 치는데 생각보다 중 문제가 어렵게 나온 느낌이라 당황을 했다. 별 찍기 문제를 예전에 풀어본 기억이 있는데, 그때는 그냥 피라미드, 역피라미드, 다이아몬드 모양까지는 만들어 본 기억은 있었는데 코드 구성이 하나도 생각이 나지 않아 그림을 그려 가면 풀었다. 3번째 문제는 최근에 비슷한 문제를 프로그래머스에서 풀어보면서 배웠던 점을 바로 써먹을 수 있어 생각보다 더 쉽게 풀었다. 개인적으로는 느낌상 하 상 중의 느낌?? 그래도 알고리즘 공부를 하면서 배웠던 것들을 확인해볼 수 있어 재미있었다.