프로그래머스 - 교점에 별 만들기 (Level 2)

2023. 12. 21. 20:26코딩테스트 정리(자바)

728x90

1. long 타입의 범위 중 최소,최대값 반환
: Long.MIN_VALUE
 Long.MAX_VALUE

2. a,b 중 최대값 반환
: Math.max(a,b)

3. 동적 배열 생성
:

List <Point> points = new ArrayList<>();


List 타입으로 생성하는 것과 ArrayList타입으로 생성하는 것의 차이점
->
List`는 인터페이스이다. 

따라서 `points`는 `ArrayList` 인스턴스를 참조할 수 있지만, 

필요에 따라 다른 `List` 인터페이스를 구현하는 다른 객체를 참조할 수 있다. 

예를 들어, 나중에 `LinkedList` 인스턴스로 변경하려면 `points = new LinkedList<>();`라고만 입력하면 된다. 

이는 코드의 유연성을 높이고, 클래스 간의 결합도를 낮추는 데 도움이 된다.

반면에 `ArrayList<Point> points = new ArrayList<>();`에서 `points`는 `ArrayList` 인스턴스만 참조할 수 있다. 

다른 `List` 구현체를 참조하려면 코드를 변경해야 한다.

따라서, 일반적으로는 가능한 한 구현체 클래스보다 인터페이스를 사용하는 것이 좋다.

이렇게 하면 코드가 더 유연해지고, 테스트와 유지 관리가 더 쉬워진다.
하지만 특정 `ArrayList` 메소드를 사용해야 하는 경우에는 `ArrayList`를 사용해야 한다.

4. 정적 배열 생성

:

char[][] result=new char[height][width];


정적배열은 new 키워드를 사용하여 배열의 크기를 지정해서 생성해줘야한다.

5. 2차원 배열 같은 값으로 초기화하기
:

for(char[] row:result){
    Arrays.fill(row,'.');
}


6. row길이 구하기
: 2차원 배열의 경우 result.length; 로 구할 수 있다
첫번째 column의 길이는 result[0].length;로 구할 수 있다.

7. 형변환
int height=(int) max.y-min.y+1; 이렇게 하면 max.y만 형변환이 발생
int height=(int) (max.y-min.y+1); 이렇게 해줘야 전체 값에 형변환 가능

* 정수를 0으로 나누면 ArithmeticException이 발생한다.
그러나 실수를 0으로 나누면 오류가 발생하지 않고 Infinity 또는 NaN을 반환한다.
따라서 double x=(double)(b*f-e*d)/(a*d-b*c); 

요 식은 분자가 실수이므로 분모가 0이라도 오류가 발생하지 않지만 

double x=(double)( (b*f-e*d)/(a*d-b*c) ); 

요 식은 분자가 정수이므로 분모가 0이 되면 오류가 발생한다. 

8. char을 String 타입으로 변환
: 1.

String[] answer=String.valueOf(result[i]);


2.

String[] answer=new String(result[i]);



9. 이제 answer을 리턴하면 ["..*..", "..."]  이렇게 리턴됨.

 

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class 교점에_별_만들기 {

        //좌표를 저장할 class 만들기
        private static class Point{ //외부에서 접근하지 못하도록 private으로 클래스와 메소드 정의
            public final long x,y; // final인 이유는 데이터이므로 불변성을 갖게하기 위해,
            // 외부에서 접근가능하게 하기 위해 public으로 생성-> 다른 메소드에서 사용하기 위함
            //private으로 생성하면 get메소드를 생성해서 접근해야함.
            private Point(long x,long y){
                this.x=x;
                this.y=y;
            }
        }
        //정수인 교점을 반환하는 메소드
        private Point intersection(long a,long b,long e,long c,long d,long f){
            double x=(double)  (b*f-e*d)/(a*d-b*c) ;
            double y=(double) (e*c-a*f)/(a*d-b*c) ;

            if(x%1==0&&y%1==0) //x,y값이 정수인지 체크
                return new Point((long)x,(long)y);
            else
                return null; //정수가 아니라면 null 반환
        }
        //x,y값의 최댓값을 반환하는 메소드
        private Point maximum(List<Point> points){
            long max_x=Long.MIN_VALUE;
            long max_y=Long.MIN_VALUE;
            for(Point point:points){
                max_x=Math.max(point.x,max_x);
                max_y=Math.max(point.y,max_y);
            }
            return new Point(max_x,max_y);
        }

        //x,y값의 최소값을 반환하는 메소드
        private Point minimum(List<Point> points){
            long min_x=Long.MAX_VALUE;
            long min_y=Long.MAX_VALUE;
            for(Point point:points){
                min_x=Math.min(point.x,min_x);
                min_y=Math.min(point.y,min_y);
            }
            return new Point(min_x,min_y); //이렇게 new로 생성후 바로 반환할 수 있음
        }

        public String[] solution(int[][] line) {
            List<Point> points=new ArrayList<>(); //교점 담을 동적배열 생성
            //교점의 좌표 담기
            for(int i=0;i<line.length;i++){
                for(int j=i+1;j<line.length;j++){
                    Point point=intersection(line[i][0],line[i][1],line[i][2],
                            line[j][0],line[j][1],line[j][2]);
                    if(point!=null) //null이 아니면 추가, 이 조건문이 없으면 null이 list에 추가되어 NullPointerException이 발생할 수 있음
                        points.add(point);
                }
            }
            //점찍을 좌표의 높이와 너비 구하기
            Point max=maximum(points);
            Point min=minimum(points);
            int height=(int) (max.y-min.y +1);
            int width=(int) (max.x-min.x +1);

            //그림 그릴 배열 생성
            char[][] result=new char[height][width];
            //모든 행을 .으로 초기화
            for(char[] row:result){ //2차원 배열의 초기화 방법
                Arrays.fill(row,'.');
            }
            //x값은 x-최소값을 빼고, y값은 최대값-y로 그림그릴 배열 좌표조정
            for(Point p:points){
                int x=(int) (p.x-min.x); //long타입이므로 int형으로 형변환
                int y=(int) (max.y-p.y);
                result[y][x]='*'; //해당 좌표에 별찍기
            }
            //char->string으로 변환하기
            String[] answer = new String[result.length];
            for(int i=0;i<result.length;i++){
               answer[i]=String.valueOf(result[i]);//혹은 new String(result[i]);
            }
            return answer;
        }
    }
728x90