[10일 차] 알고리즘 (Basic2)

2025. 2. 7. 11:46·LG 유플러스 유레카/알고리즘

25/02/07 (금)

금요일입니다!

일주일 중 가장 활력이 넘치는 날입니다!

주짓수 스파링하는 날이기도 하고, 곧 주말이라 놀기 제일 좋은 날이기도 합니다.

직장인들이 왜 불금 불금 하는지 이해가 갑니다.

내일은 여자친구와 1주년 기념 코엑스에서 서일페를 가기로 했습니다. 너무 기대되는군요.

저녁으로 미슐랭 빕구르망을 받은 딤섬을 예약했는데 이것도 기대됩니다!

일요일에는 CS공부한것 정리와 알고리즘 공부, 기사 공부를 해야하는데.. 할 수 있을까요..?


1.  WorkShop 발표

1) 요세푸스 문제

큐

FIFO 자료구조

Front에서 dequeue, Rear에서 enqueue

 

2.  강의

2.1.  Basic

1) delta2

package basic.delta;

import java.util.Arrays;

// 특정 위치에서 4방 탐색을 진행하는 경우, if-else if -else if - ... <= 코드의 길이가 길어지고, 가독성이 떨어지고 나누어서 생각하고
//  => 실수하기 쉽다.
// 한 방향으로 탐색할 수 있을 때까지 계속 탐색
public class DeltaTest2 {
    static char[][] map = new char[5][5];

    public static void main(String[] args) {
        char ch = 'A';

        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                map[i][j] = ch++;
            }
        }

        // 출력
        for (int i = 0; i < 5; i++) {
            System.out.println(Arrays.toString(map[i]));
        }

        // 4방 탐색 - 상-하-좌-우
        print4x(2, 2);

    }

    static int[] dy = { -1, 1,  0, 0 };
    static int[] dx = {  0, 0, -1, 1 };

    static void print4x(int y, int x) {

        for (int d = 0; d < 4; d++) {

            int ny = y;
            int nx = x;

            while(true) {
                ny = ny + dy[d];
                nx = nx + dx[d];

                if( ny < 0 || nx < 0 || ny >= 5 || nx >= 5 ) break;  // while 문 종료

                System.out.println(map[ny][nx]);
            }
        }
    }
}

 

2) recursive

package basic.recursive;

public class Test {
    public static void main(String[] args) {
//        m1();
//        m1_param(0);
//        m2();
        m3();
    }

    //변수
    static int m1_i = 0;

    static void m1() {
        //local 변수 <= 재귀호출마다 stack에 새로 만들어지고 초기화 됨
//        int i = 0;

        //static 변수 <= 재귀호출마다 공유
//        System.out.println("m1() : " + m1_i++);
//        m1();
//        m2();
//        m3();
        m4(5);
    }

    static void m1_param(int i){
        //파라미터 변수
        System.out.println("m1_param() : " + i++);
        m1_param(i);
    }

    //기저 조건
    static int m2_cnt = 5;
    static void m2() {
        System.out.println("앞 m2() : "+ m2_cnt);
        //기저조건
        if(m2_cnt > 0) {
            m2_cnt--;
            m2();
        }
        System.out.println("뒤 m2() : "+ m2_cnt);
    }

    //Static 변수 이용
    static int m3_cnt = 5;
    static void m3() {
        if(m3_cnt == 0) return;

        System.out.println("앞 m3() : "+ m3_cnt);

        m3_cnt--;
        m3();
        m3_cnt++; //없으면 0으로 감소 한 후 계속 0 유지, 원복 필요

        System.out.println("뒤 m3() : "+ m3_cnt);
    }

    //파라미터 이용
    static void m4(int m4_cnt) {
        if(m4_cnt == 0) return;

        System.out.println("앞 m4() : "+ m4_cnt);

        m4(m4_cnt - 1); //호출 시 전달받은 m4_cnt는 변화X

        System.out.println("뒤 m4() : "+ m4_cnt);
    }
}

factorial

package basic.recursive;

public class Test2 {

    // factorial 계산을 재귀호출을 이용해서 처리, 결과값 처리 다양하게
    public static void main(String[] args) {
        factorial(5);

        int result = factorial2(5);
        System.out.println(result);

        factorial3(5, 1); // 두 번째 파라미터 값에 누적 곱으로 처리
    }

    // #1. 결과값을 static 변수
    static int result = 1;
    static void factorial(int n) {
        // 기저조건
        if( n == 1 ) {
            System.out.println(result); // 원하는 결과가 완성된 시점
            return;
        }

        // 계산
        result = result * n;

        // 재귀호출
        factorial(n - 1);
    }

    // #2. 결과값을 재귀호출의 return 값으로
    // 바닥부터 계산되어서 bottom up 으로 처리
    static int factorial2(int n) {
        // 기저조건
        if( n == 1 ) return 1;

        // n == 3 일 때,
        // 2 x 1 의 의 결과에 자신 3 을 곱해서 4 에게 리턴
        return n*factorial2(n - 1);
    }

    // #3. 결과값을 재귀호출의 parameter 값으로
    static void factorial3(int n, int result) {
        // 기저조건
        if( n == 1 ) {
            // result 에 이전 계산값이 존재
            System.out.println(result);
            return;
        }
        factorial3(n - 1, result * n); // 넘어온 이전 계산 값에 자신을 곱한다.
    }
}

 

3) ArraySort

배열 정렬

package basic.Ch06_sort;

import java.util.Arrays;
import java.util.Comparator;

public class ArraySortTest {
    public static void main(String[] args) {
//        //배열 정렬
//        int[] intArray = {3, 5, 2 ,7, 9, 4};
//
//        //int
//        System.out.println(Arrays.toString(intArray));
//        Arrays.sort(intArray);
//        System.out.println(Arrays.toString(intArray));
//
//        //String
//        String[] strArray = {"Hello", "UPlus", "URECA", "World"};
//        System.out.println(Arrays.toString(strArray));
//        Arrays.sort(strArray);
//        System.out.println(Arrays.toString(strArray));
//        Arrays.sort(strArray, Collections.reverseOrder()); //역정렬
//        System.out.println(Arrays.toString(strArray));

        //사용자 정의 클래스
        Item[] itemArray = {new Item(3, "66"), new Item(3, "77"), new Item(5, "44"), new Item(8, "11")};

        //#1 클래스에 정의
//        Arrays.sort(itemArray);
//        System.out.println(Arrays.toString(itemArray));

        //#2 Comparator 인터페이스 이용 - anonymous 객체
        //정렬 대상 클래스에 comparable 인터페이스 구현하지 않아도, 정렬 시점에 정렬 기준을 구현한 객체를 전달
//        Arrays.sort(itemArray, new Comparator<Item>() {
//            @Override
//            public int compare(Item o1, Item o2) {
//                return o1.itemId - o2.itemId; //natural ordering
//            }
//        });
//        System.out.println(Arrays.toString(itemArray));


        //#3 Comparator 인터페이스 이용 - lambda
        //정렬 대상 클래스에 comparable 인터페이스 구현하지 않아도, 정렬 시점에 정렬 기준을 구현한 객체를 전달
        Arrays.sort(itemArray, (o1, o2) -> o1.itemId == o2.itemId ? o1.itemName.compareTo(o2.itemName) : o1.itemId - o2.itemId);
        System.out.println(Arrays.toString(itemArray));
    }

    //객체들을 정렬할 때 기준이 필요
    //#1 클래스에 정의
//    static class Item implements Comparable<Item>{
//        int itemId;
//        String itemName;
//
//        Item(int itemId, String itemName) {
//            this.itemId = itemId;
//            this.itemName = itemName;
//        }
//
//        @Override
//        public String toString() {
//            return "Item [itemId=" + itemId + ", itemName=" + itemName + "]";
//        }
//
//        @Override
//        public int compareTo(Item o) { //정렬 기준 제공
////            return this.itemId - o.itemId; //natural ordering
////            return o.itemId - this.itemId; //natural ordering
////            return this.itemName.compareTo(o.itemName);
//            //itemId 우성 비교하는데 같은 값이면 itemName 비교
//            return this.itemId == o.itemId ? this.itemName.compareTo(o.itemName) : this.itemId - o.itemId;
//        }
//    }

    //#2 Comparator 인터페이스 이용
    static class Item{
        int itemId;
        String itemName;

        Item(int itemId, String itemName) {
            this.itemId = itemId;
            this.itemName = itemName;
        }

        @Override
        public String toString() {
            return "Item [itemId=" + itemId + ", itemName=" + itemName + "]";
        }

    }
}

컬렉션 배열 정렬

package basic.Ch06_sort;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class CollectionSortTest {
    public static void main(String[] args) {
        //ArrayList를 이용한 정렬
        List<Item> list = new ArrayList<>();
        list.add(new Item(3,"66"));
        list.add(new Item(2,"77"));
        list.add(new Item(5,"33"));
        list.add(new Item(8,"44"));

        System.out.println(list);

        //#1. Comparable
//        Collections.sort(list); //implements Comparable한 객체가 아닌 경우 컴파일 에러 발생
//        System.out.println(list);

        //#2. Comparator 인터페이스 구현 - lambda
        Collections.sort(list, (o1, o2) -> o1.itemId - o2.itemId);
        System.out.println(list);
    }

    //#1. Comparable
        static class Item implements Comparable<Item> {
        int itemId;
        String itemName;

        Item(int itemId, String itemName) {
            this.itemId = itemId;
            this.itemName = itemName;
        }

        @Override
        public String toString() {
            return "Item [itemId=" + itemId + ", itemName=" + itemName + "]";
        }

        @Override
        public int compareTo(Item o) { //정렬 기준 제공
//            return this.itemId - o.itemId; //natural ordering
//            return o.itemId - this.itemId; //natural ordering
//            return this.itemName.compareTo(o.itemName);
            //itemId 우성 비교하는데 같은 값이면 itemName 비교
            return this.itemId == o.itemId ? this.itemName.compareTo(o.itemName) : this.itemId - o.itemId;
        }
    }
}

 

4) 순열, 조합, 부분집합

자주 쓰니 외워두어야 합니다

순열(permutation)

package basic.Ch07_perm;

import java.util.Arrays;

public class BasicPerm {

    //기본 순열
    static int[] src = {1, 2, 3, 4, 5};
    static int[] tgt = new int[3]; //__ __ __ <= 현재 자리를 채우기 위해 src 전체를 고려하되, 현재 자리 이전 자리에 사용된 수 제외
    //현재 자리 이전 자리에 사용된 수
    static boolean[] select = new boolean[src.length]; // _f_ _t_ _f_ _t_ _f_

    public static void main(String[] args) {
        perm(0); //tgt의 맨 앞자리부터 시작
    }

    static void perm(int tgtIdx) { //tgtIdx => __ __ __
        //기저조건
        //이 조건 이전의 재귀호출로 이미 tgt 배열이 완성
        if(tgtIdx == tgt.length){
            System.out.println(Arrays.toString(tgt));
            return;
        }
        //현재 파라미터로 넘어온 tgtIdx 자리에 src로부터 채울 수를 선택, 고려
        //src 전체를 대상으로 하되, select 배열에 사용중인 것은 제외
        for (int i = 0; i < src.length; i++) {
            //앞자리에 사용된 수이면 skip
            if(select[i]) continue;

            tgt[tgtIdx] = src[i]; //선택

            select[i] = true; //선택 표시
            perm(tgtIdx+1); //다음 자리를 위한 재귀 호출
            select[i] = false; //선택 원복
        }
    }
}

조합(combination)

package basic.Ch08_comb;

import java.util.Arrays;

public class BasicComb {

    //기본 조합
    static int[] src = {1, 2, 3, 4, 5};
    static int[] tgt = new int[3]; //__ __ __ <= 현재 자리를 채우기 위해, src의 맨 앞에서부터 수를 선택/비선택 해가면서 tgt 개수를 채운다.
    //이전에 사용된 수 고려 X <= select 배열 X

    public static void main(String[] args) {
        comb(0, 0);
    }

    //조합
    //src의 srcIdx 자리의 수를 tgtIdx 자리에 선택? 비선택?
    static void comb(int srcIdx, int tgtIdx) {
        //기저조건
        if(tgtIdx == tgt.length) {
            System.out.println(Arrays.toString(tgt));
            return;
        }
        if(srcIdx == src.length) return; //기저조건 1개 더

        tgt[tgtIdx] = src[srcIdx]; //선택
        comb(srcIdx + 1, tgtIdx + 1); //위 선택을 받아들이고 다음 자리로 재귀호출
        comb(srcIdx + 1, tgtIdx); //위 선택을 받아들이지 않고 srcIdx만 증가시키는 효과
    }
}

부분집합

package basic.Ch09_subset;

public class BasicSubset {

    //기본 부분집합
    //부분집합의 경우의 수는 모든 가능한 조합의 수의 합

    static int[] src = {1, 2, 3, 4, 5};
    //tgt 배열 X <= 가능한 모든 경우를 선택하기 때문
    //조합은 src, tgt 맨 앞부터 선택/비선택을 해 가면서 tgt를 채우면 끝이지만
    //부분집합은 src의 맨 앞부터 선택/비선택을 끝까지 계속 한다

    static boolean[] select = new boolean[src.length]; //선택, 비선택 상태를 저장하는 자료 구조

    public static void main(String[] args) {
        subset(0); //맨 앞자리부터
    }

    static void subset(int srcIdx) {
        //기저조건
        if(srcIdx == src.length) {
            //부분집합 경우가 완성
            printSubset();
            return;
        }

        //현 srcIdx를 선택, 비선택
        select[srcIdx] = true;
        subset(srcIdx + 1);

        select[srcIdx] = false;
        subset(srcIdx + 1);
    }

    //부분집합이 완성되면 select 배열을 기준으로 src의 선택된 수 출력
    static void printSubset() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < select.length; i++) {
            if(select[i]) sb.append(src[i]).append(" ");
        }
        System.out.println(sb);
    }
}

 

추가) 디버그

인텔리제이(다른 IDE도 가능)에서 디버그가 가능합니다..! (처음 알음)

 

3.  마무리

1) WorkShop

  • 점심시간 : ArraySort에서 만약 내가 ItemID 우선 비교하는데 같은 값이면 itemName 비교
  • 만들어 보기 : 컬렉션 배열 정렬에서 Comparable 클래스 만들어보기
  • WorkShop : 생활속에서 찾을 수 있는 순열, 조합, 부분 집합 찾기

오늘의 추천 문제

https://www.acmicpc.net/problem/15649
https://www.acmicpc.net/problem/1010
https://www.acmicpc.net/problem/2961

 

2) 더 공부할 것

  • Override
  • Overload
  • this
  • super
  • Array sort
  • toString
  • StringBuilder
  • BufferreadReader
  • Tokenizer

(그냥 다 해야될것같은데)

'LG 유플러스 유레카 > 알고리즘' 카테고리의 다른 글

[12일 차] 알고리즘 (Basic4)  (0) 2025.02.11
[11일 차] 알고리즘 (Basic3)  (0) 2025.02.10
[9일 차] 알고리즘 (Basic)  (0) 2025.02.06
'LG 유플러스 유레카/알고리즘' 카테고리의 다른 글
  • [13일 차] 알고리즘 (Basic5)
  • [12일 차] 알고리즘 (Basic4)
  • [11일 차] 알고리즘 (Basic3)
  • [9일 차] 알고리즘 (Basic)
문태신
문태신
꾸준함은 모든 것을 이긴다.
  • 문태신
    별 될 시간
    문태신

  • 전체
    오늘
    어제
    • 전체 글 (158)
      • LG 유플러스 유레카 (137)
        • 강의 정리 (1)
        • 소프트웨어 엔지니어링 (8)
        • 알고리즘 (13)
        • 데이터베이스 활용 (5)
        • 미니 프로젝트 1 (3)
        • 데이터베이스 심화 (5)
        • 프론트엔드 이해 (3)
        • 깃허브 특강 (2)
        • 취업 특강 (2)
        • 스프링 프레임워크 (17)
        • REST API (10)
        • 미니 프로젝트 2 (7)
        • 프로젝트 기획 분석 설계 (5)
        • 애자일 방법론 (5)
        • 종합 프로젝트 (15)
        • 클라우드 특강 (3)
        • 최종 융합 프로젝트 (32)
        • 회고 (1)
      • 자바 공부 (3)
      • 알고리즘 공부 (5)
      • CS 공부 (2)
      • 토이 프로젝트 : 별 될 시간 (5)
        • 개요 (1)
        • 서버 구축 (4)
        • CI CD 세팅 (0)
      • 취업 (1)
      • 자격증 (2)
      • 디자인 (2)
      • 감상문 (1)
        • 책 (0)
        • 영화 (1)
  • 인기 글

  • 최근 글

  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.3
문태신
[10일 차] 알고리즘 (Basic2)
상단으로

티스토리툴바