6137번: 문자열 생성

첫 번째 줄에 문자열 S의 길이 N이 주어진다. (N <= 2,000) 이후 N개의 줄에 S를 이루는 문자들이 주어진다.

www.acmicpc.net

 

풀이 방법

  • 문자열 S의 가장 앞의 문자 하나를 문자열 T의 마지막에 추가
  • 문자열 S의 가장 뒤의 문자 하나를 문자열 T의 마지막에 추가

문자열 T들 중 사전으로 가장 빠른 문자열을 출력하는 문제였습니다.

 

 

코드

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
 
public class Main_BJ_6137_문자열생성 {
 
    public static void main(String[] args) throws NumberFormatException, IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        ArrayList<Character> result = new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        
        int N = Integer.parseInt(br.readLine());
        
        char [] alpabet = new char[N];
        
        for(int i=0;i<N;i++) {
            String word = br.readLine();
            alpabet[i] = word.charAt(0);
        }
        
        int start=0, end=N-1;
        while(start<=end) {
            if((int)alpabet[start]<(int)alpabet[end]) {
                result.add(alpabet[start++]);
            }else if((int)alpabet[start]==(int)alpabet[end]) {
                int front = start, back=end;
                boolean check = true;
                
                while(alpabet[front]==alpabet[back]) {
                    if(back>0) back--;
                    if(front<N-1) front++;
                    
                    if((int)alpabet[front]<(int)alpabet[back]) check=true;
                    else if((int)alpabet[front]>(int)alpabet[back]) check=false;
                }
                
                if(check) result.add(alpabet[start++]);
                else result.add(alpabet[end--]);
                
                
            }else  {
                result.add(alpabet[end--]);
            }
        }
        
        for(int i=0;i<result.size();i++) {
            if(i!=0 && i%80==0) sb.append("\n");
            sb.append(result.get(i));
        }
        System.out.println(sb.toString());
    }
}
cs

 

 

'문제 > 백준' 카테고리의 다른 글

백준 23056번 참가자 명단 [JAVA]  (0) 2021.10.17
백준 8911번 거북이 [JAVA]  (0) 2021.10.13
백준 16562 친구비 [JAVA]  (0) 2021.09.21
백준 2531번 회전 초밥 [JAVA]  (0) 2021.09.17
백준 1520 내리막길 [JAVA]  (0) 2021.09.10

Dependency 의존관계란?


'A가 B를 의존한다.' 라는 표현은 어떤 의미일까? 토비의 스프링에서는 다음과 같이 정의한다.

 

의존대상 B가 변하면, 그것이 A에 영향을 미친다.

 

즉, B의 기능이 수정된다면 A에게까지 영향을 미친다.

 

다음 예시를 보며 이해해보자.

"햄버거 가게 요리사는 햄버거 레시피에 의존한다." 는 말은 햄버거 레시피가 변경되었을 때, 변경된 레시피에 따라서 요리사는 햄버거 만드는 방법을 바꿔야한다. 레시피의 변화가 요리사의 행위에 영향을 미쳤기 때문에 "요리사는 레시피에 의존한다"고 말할 수 있다.

 

코드로 표현해보면 다음과 같다.

class BurgerChef {
    private HamBurgerRecipe hamBurgerRecipe;

    public BurgerChef() {
        hamBurgerRecipe = new HamBurgerRecipe();        
    }
}

여기에서 HamBurgerRecipe만을 의존할 수 있는 구조로 되어있다. 만약 더 다양한 햄버거 레시피를 의존 받을 수 있게 구현하려면 인터페이스로 추상화해야한다.

 

이를 코드로 표현해보면 다음과 같다.

class BurgerChef {
    private BurgerRecipe burgerRecipe;

    public BurgerChef() {
        burgerRecipe = new HamBurgerRecipe();
        //burgerRecipe = new CheeseBurgerRecipe();
        //burgerRecipe = new ChickenBurgerRecipe();
    }
}

interface BugerRecipe {
    newBurger();
    // 이외의 다양한 메소드
} 

class HamBurgerRecipe implements BurgerRecipe {
    public Burger newBurger() {
        return new HamBerger();
    }
    // ...
}

class CheeseBurgerRecipe implements BurgerRecipe {
	public Buerger newBurger() {
    	return new CheeseBurger();
    }
    // ...
}

의존관계를 인터페이스로 추상화하게 되면, 더 다양한 의존 관계를 맺을 수 있고 실제 구현 클래스와의 관계가 느슨해지고, 결합도가 낮아진다.

 

그럼 DI(Dependency Injection)은 뭔가?


위에 코드를 보면 BurgerChef 내부적으로 의존관계인 BurgerRecipe가 어떤 값을 가질지 직접 정하고 있다. 만약 어떤 BurgerRecipe를 만들지를 버거 가게 사장님이 정하는 상황을 가정해보자. 즉, BurgerChef가 의존하고 있는 BurgerRecipe를 외부(사장님)에서 결정하고 주입하는 것이다.

 

이처럼 의존관계를 외부에서 결정하고 주입하는 것이 DI(의존관계 주입)이다.

DI를 통해서 모듈 간의 결합도가 낮아지고 유연성이 높아진다.

 

DI 구현 방법


DI는 의존관계를 외부에서 결정하는 것이기 때문에, 클래스 변수를 결정하는 방법들이 곧 DI를 구현하는 방법이다. 런타임 시점의 의존관계를 외부에서 주입해 DI 구현이 완성된다.

 

"Burger 레스토랑 주인이 어떤 레시피를 주입하는지 결정하는 예시로 설명하고자 한다."

 

[생성자 이용]

class BurgerChef {
    private BurgerRecipe burgerRecipe;

    public BurgerChef(BurgerRecipe burgerRecipe) {
        this.burgerRecipe = burgerRecipe;
    }
}

class BurgerRestaurantOwner {
    private BurgerChef burgerChef = new BurgerChef(new HamburgerRecipe());

    public void changeMenu() {
        burgerChef = new BurgerChef(new CheeseBurgerRecipe());
    }
}

 

[메소드 이용]

class BurgerChef {
    private BurgerRecipe burgerRecipe = new HamburgerRecipe();

    public void setBurgerRecipe(BurgerRecipe burgerRecipe) {
        this.burgerRecipe = burgerRecipe;
    }
}

class BurgerRestaurantOwner {
    private BurgerChef burgerChef = new BurgerChef();

    public void changeMenu() {
        burgerChef.setBurgerRecipe(new CheeseBurgerRecipe());
    }
}

 

 

DI의 장점은 뭘까?


1. 의존성이 줄어든다.

의존성이 높을 수록 대상이 변화했을 때, 이에 맞게 다른 것도 수정해야한다. DI로 구현했을 경우, 주입받는 대상이 변하더라도 그 구현 자체를 수정할 일이 없거나 줄어들게 된다.

 

2. 재사용성이 높은 코드가 된다.

기존에 BurgerChef 내부에서만 사용되었던 BurgerRecipe를 별도로 구분하여 구현한다면, 다른 클래스에서 재사용할 수 있다.

 

3. 가독성이 높아진다.

기능들을 별도로 분리하게 되어 자연스럽게 가독성이 높아진다.

 

 

관점 지향 프로그래밍 (AOP)란 뭘까?


AOP는 OOP를 돕는 보조적인 기술로, 관심사의 분리의 문제를 해결하기 위해 만들어진 프로그래밍 패러다임이다.

여러 객체에 공통으로 적용할 수 있는 기능을 분리함으로써 재사용성을 높일 수 있다.

 

만약 메서드를 실행할 때마다 공통적으로 확인하고 싶은 정보가 있는데, 모든 메서드에 해당 로그 코드를 작성하면 코드가 길어질 뿐만아니라 가독성이 떨어질 것이다.

 

이를 AOP로 분리시킨다면..

 

@Aspect
@Component
public class ParameterAop {

    //com/example/aop/controller 패키지 하위 클래스들 전부 적용하겠다고 지점 설정
    @Pointcut("execution(* com.example.aop.controller..*.*(..))")
    private void cut() {}

    //cut() 메서드가 실행 되는 지점 이전에 before() 메서드 실행
    @Before("cut()")
    public void before(JoinPoint joinPoint) {
		
        //실행되는 함수 이름을 가져오고 출력
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        System.out.println(method.getName() + "메서드 실행");

        //메서드에 들어가는 매개변수 배열을 읽어옴
        Object[] args = joinPoint.getArgs();
		
        //매개변수 배열의 종류와 값을 출력
        for(Object obj : args) {
            System.out.println("type : "+obj.getClass().getSimpleName());
            System.out.println("value : "+obj);
        }
    }

    //cut() 메서드가 종료되는 시점에 afterReturn() 메서드 실행
    //@AfterReturning 어노테이션의 returning 값과 afterReturn 매개변수 obj의 이름이 같아야 함
    @AfterReturning(value = "cut()", returning = "obj")
    public void afterReturn(JoinPoint joinPoint, Object obj) {
        System.out.println("return obj");
        System.out.println(obj);
    }
}

AOP 클래스를 구현함으로써 이전보다 코드가 훨씬 간결해지고 가독성이 높아지는 것을 확인할 수 있다.

 

'정리 > Spring' 카테고리의 다른 글

Spring Security _ 2탄 ( 이제 JWT를 곁들인.. )  (0) 2024.12.11
Spring Security 란?  (0) 2024.12.10
[Spring] REST API  (0) 2021.09.09
[Spring] Spring MVC  (0) 2021.09.09
[Spring] Spring이란?  (0) 2021.09.09
 

16562번: 친구비

첫 줄에 학생 수 N (1 ≤ N ≤ 10,000)과 친구관계 수 M (0 ≤ M ≤ 10,000), 가지고 있는 돈 k (1 ≤ k ≤ 10,000,000)가 주어진다. 두번째 줄에 N개의 각각의 학생이 원하는 친구비 Ai가 주어진다. (

www.acmicpc.net

 

 

풀이 방법

이 문제는 가장 적은 비용으로 모든 사람과 친구가 되는 방법을 구하는 문제였습니다.

 

1) 친구가 아닌 경우 친구 사귀기

    이때! 친구비가 더 적은걸로 친구비 변경해주기

2) M번의 친구 사귀기가 끝나면 한명씩 확인하면서 친구비 계산

3) 준석이가 가진 돈으로 친구를 다 사귈 수 있는지 확인

 

 

코드

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class Main_BJ_16562_친구비 {
    
    static int N,M,K;
    static int [] parents, friendFee;
    static boolean [] check;
 
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;
        
        st = new StringTokenizer(br.readLine());
        
        N = Integer.parseInt(st.nextToken()); //학생수
        M = Integer.parseInt(st.nextToken()); //친구관계수 
        K = Integer.parseInt(st.nextToken()); //가지고 있는 돈
        
        friendFee = new int[N+1];
        parents = new int[N+1];
        check = new boolean[N+1];
        
        for(int i=1;i<parents.length;i++) parents[i] = i;
        
        st = new StringTokenizer(br.readLine());
        for(int i=1;i<friendFee.length;i++) friendFee[i] = Integer.parseInt(st.nextToken());
        
        for(int i=0;i<M;i++) {
            st = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());
            union(a,b);
        }
        
        int friend=0, answer=0;
        for(int i=1;i<parents.length;i++) {
            int temp = find(i);
            if(check[temp]) {
                friend++;
                continue;
            }
            if(K-friendFee[i]>=0) {
                friend++;
                answer+=friendFee[i];
                K-=friendFee[i];
                check[temp] = true;
            }
            
        }
        System.out.println(friend==N?answer:"Oh no");
 
    }
    
    public static void union(int a, int b) {
        int aRoot = find(a);
        int bRoot = find(b);
        
        if(aRoot<bRoot) parents[bRoot] = aRoot;
        else parents[aRoot]= bRoot;
        
        if(friendFee[aRoot]<friendFee[bRoot]) friendFee[bRoot] = friendFee[aRoot];
        else friendFee[aRoot] = friendFee[bRoot];
    }
    
    public static int find(int x) {
        if(parents[x]==x) return x;
        return parents[x]=find(parents[x]);
    }
 
}
cs

 

 

 

'문제 > 백준' 카테고리의 다른 글

백준 8911번 거북이 [JAVA]  (0) 2021.10.13
백준 6137번 문자열 생성 [JAVA]  (0) 2021.09.26
백준 2531번 회전 초밥 [JAVA]  (0) 2021.09.17
백준 1520 내리막길 [JAVA]  (0) 2021.09.10
백준 17121 연구소2 [JAVA]  (0) 2021.09.02

👉🏻react 프로젝트 만들기

  • cmd창 : create-react-app <파일명>
  • vscode 열고 npm run start


💡React의 4가지 개념

1. JSX

  • JSX는 React에서만 사용되는 구문으로, HTML 형태와 비슷하다.

💡HTML VS JSX

  • class 대신 className
  • {}를 통한 JavaScript 구문 사용

2. Components

  • Function Component - 함수 선언 후 그 함수의 반환 값으로 React Component 주기
  • Class Component - render함수를 호출하고 그 안에서 Component return

    👉🏻다른 컴포넌트에서 만들어 놓은 컴포넌트를 사용하고 싶을때는❓

💡Component 만들 때의 규칙

  • 이름은 대문자로 시작!
  • Component의 return 값은 큰 하나의 Component로 감싸져 있어야 한다.

3. props

  • 컴포넌트를 호출할 때, 상황에 따라 부모 컴포넌트에서 어떠한 값을 넘겨줘야 할 때 사용 
    💡 Function Component의 경우 함수의 인자로 props , Class Component의 경우 class 내부의 property로 받게 된다.

    👉🏻Destructuring 
    • 구조화되어 있는 형태(배열, 객체 등)을 하나의 변수로 뽑아내기
      const person = {
      	name : "juyeon",
      	age : 24
      }
      
      const name = person.name;
      const age = person.age;
      
      
      만약 더 많은 키 값을 가지고 있다면❓ : 변수를 많이 만들어야한다.
      💡그래서 사용하는 방법이 destructuring!
      
      
      const { name, age } = person;
      
      console.log(name, age);

      👉🏻위의 코드에 적용해보자!

4. state

  • Component 안에서 변하는 데이터 저장

👉🏻 Component 단위로 파일 분리하기

  • 하나의 파일에서 하나의 객체 내보내기
    불러오는 파일 : import 새로_받을_이름 from '내보낸_파일의_위치';
    내보내는 파일 : export default 내보낼_객체_이름;
  • 하나의 파일에서 여러 개의 객체 내보내기
    내보내는 파일 : export const 객체1; export const 객체2;
    불러오는 파일 import {객체1, 객체2 } from '내보낸_파일의_위치';

'정리 > Web' 카테고리의 다른 글

Vuex  (0) 2021.07.14
CSS  (2) 2021.03.19
HTML  (0) 2021.03.19
jQuery  (0) 2021.03.08
JavaScript  (2) 2021.03.05
 

2531번: 회전 초밥

첫 번째 줄에는 회전 초밥 벨트에 놓인 접시의 수 N, 초밥의 가짓수 d, 연속해서 먹는 접시의 수 k, 쿠폰 번호 c가 각각 하나의 빈 칸을 사이에 두고 주어진다. 단, 2 ≤ N ≤ 30,000, 2 ≤ d ≤ 3,000, 2 ≤

www.acmicpc.net

 

풀이 방법

손님이 먹을 수 있는 초밥 가짓수의 최댓값을 구하는 문제였습니다.

 

몇 번의 초밥을 먹었는지 확인할 수 있는 배열 : check []

종류별로 몇 개 먹었는지 확인할 변수 : count

 

1) 처음 연속해서 k개를 먹었을 경우 몇 번의 초밥과 종류별로 몇 개 먹었는지 확인

2) start=1, end=k로 한 칸씩 ++하면서 종류별로 먹은 최대 초밥 수 max 변수에 담기

3) start = N 인 경우 즉, 끝까지 확인한 경우 종료

 

 

코드

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class Main_BJ_2531_회전초밥 {
 
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;
        
        int max=0;
        
        st = new StringTokenizer(br.readLine());
 
        int N = Integer.parseInt(st.nextToken()); //접시수
        int d = Integer.parseInt(st.nextToken()); //초밥 수
        int k = Integer.parseInt(st.nextToken()); //연속해서 먹는 접시수
        int c = Integer.parseInt(st.nextToken()); //쿠폰번호
        
        int [] sushi = new int[N];
        for(int i=0;i<N;i++) {
            sushi[i] = Integer.parseInt(br.readLine());
        }
        
        int [] check = new int[d+1];
        int count=0;
        
        for(int i=0;i<k;i++) {
            if(check[sushi[i]]==0) count++;
            check[sushi[i]]++;
        }
        
        max = count;
        int start=1, end=k;
        while(true) {
            
            if(check[sushi[start-1]]==1) count--;
            check[sushi[start-1]]--;
            
            if(check[sushi[end]]==0) count++;
            check[sushi[end]]++;
            
            if(check[c]==0) max = Math.max(max, count+1);
            else max = Math.max(max, count);
            
            start++; end++;
            if(end==N) end=0;
            if(start==N) break;
        }
        System.out.println(max);
            
    }
}
cs

 

'문제 > 백준' 카테고리의 다른 글

백준 6137번 문자열 생성 [JAVA]  (0) 2021.09.26
백준 16562 친구비 [JAVA]  (0) 2021.09.21
백준 1520 내리막길 [JAVA]  (0) 2021.09.10
백준 17121 연구소2 [JAVA]  (0) 2021.09.02
백준 16236번 아기 상어 [JAVA]  (0) 2021.08.29

 

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

 

풀이 방법

이 문제는 도착점에 대응하는 출발점을 찾는 문제였습니다.

 

여러 출발점에서 2인 도착점을 찾을 경우에는 출발점이 마다 도착점이 어딘지 확인을 해야하지만

도착점에서 역으로 올라가 출발점을 찾으면 그게 답이기 때문에 역으로 거슬러 올라갔습니다.

 

코드

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class Solution_1210_Ladder1 {
    
    static int [][] map;
    static int N=100, arriveX, arriveY, answer;
    
    static int [] dx = {0,0,-1};
    static int [] dy = {-1,1,0};
 
    public static void main(String[] args) throws NumberFormatException, IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();
        StringTokenizer st;
        
        for(int tc=0;tc<10;tc++) {
            int t = Integer.parseInt(br.readLine());
            
            map = new int[N][N];
            for(int i=0;i<N;i++) {
                st = new StringTokenizer(br.readLine());
                for(int j=0;j<N;j++) {
                    map[i][j] = Integer.parseInt(st.nextToken());
                    if(map[i][j]==2) {
                        arriveX = i;
                        arriveY = j;
                    }
                }
            }
            move(arriveX, arriveY);
            sb.append("#"+t+" "+answer+"\n");
        }
        System.out.println(sb.toString());
 
    }
    
    public static void move(int x, int y) {
        
        while(true) {
            if(x==0) {
                answer = y;
                break;
            }
            for(int i=0;i<3;i++) {
                int nx = x+dx[i];
                int ny = y+dy[i];
                
                if(range(nx,ny) && map[nx][ny]==1) {
                    map[x][y] = 3;
                    x = nx; y=ny;
                }
            }
        }
    }
    
    public static boolean range(int x, int y) {
        return x>=0 && x<&& y>=0 && y<N;
    }
 
}
cs

 

'문제 > SWEA' 카테고리의 다른 글

[SWEA 5658] 보물상자 비밀번호 (JAVA)  (0) 2021.09.10
[SWEA 1227] 미로2 (JAVA)  (0) 2021.03.16
[SWEA 4012] 요리사 (JAVA)  (1) 2021.03.16
 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

 

풀이 방법

보물 상자에 적힌 숫자로 만들 수 있는 모든 수 중 K번째로 큰 수를 10진수로 만들어 출력하는 문제였습니다.

 

1. 각 변에는 동일한 개수의 숫자가 있다.

2. 시계 방향으로 회전한다.

3. 크기 순서를 셀 때 중복된 수는 세지 않는다.

이를 바탕으로

 

동일한 길이의 비밀번호를 만들기 위해

1. 숫자의 길이인 N을 4로 나누어 각 변에 숫자가 몇 개씩 들어가야 하는지 확인

2. list에 각 숫자 담기

3. N/4개씩 끊어 result에 담기

4. 시계 방향으로 회전하기 때문에 list맨뒤에 있는 값 맨 앞으로 넣어주기

위의 2 ~ 4번 N/4번 반복해준 뒤,

 

result에 담긴 값 내림차순으로 정렬해 K번째의 수를 10진수로 변환 한 뒤 출력해주었습니다.

 

코드

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;
 
public class Solution_5658_보물상자비밀번호 {
    
    public static void main(String[] args) throws NumberFormatException, IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();
        StringBuilder answer = new StringBuilder();
        
        StringTokenizer st;
        
        List<Character> list = new ArrayList<>();
        List<String> result = new ArrayList<>();
        
        int T = Integer.parseInt(br.readLine());
        
        for(int tc=1;tc<=T;tc++) {
            st = new StringTokenizer(br.readLine());
            int N = Integer.parseInt(st.nextToken())/4//숫자개수
            int K = Integer.parseInt(st.nextToken()); //k번째수
            
            String num = br.readLine();
            for(int i=0;i<num.length();i++) list.add(num.charAt(i));
            
            for(int i=0;i<N;i++) {
                int count=0;
                for(int j=0;j<num.length();j++) {
                    sb.append(list.get(j));
                    count++;
                    if(count==N) {
                        if(!result.contains(sb.toString())) {
                            result.add(sb.toString());
                        }
                        sb.setLength(0);
                        count=0;
                    }
                }
                char c = list.remove(list.size()-1);
                list.add(0,c);
            }
            
            Collections.sort(result, Collections.reverseOrder());
            
            for(int i=0;i<result.size();i++) {
                if(i==K-1) {
                    answer.append("#"+tc+" "+Integer.parseInt(result.get(i),16)+"\n");
                    break;
                }
            }
            list.clear();
            result.clear();
            
        }
        System.out.println(answer.toString());
 
    }
 
}
cs

 

 

'문제 > SWEA' 카테고리의 다른 글

[SWEA 1210] Ladder1 (JAVA)  (0) 2021.09.16
[SWEA 1227] 미로2 (JAVA)  (0) 2021.03.16
[SWEA 4012] 요리사 (JAVA)  (1) 2021.03.16
 

1520번: 내리막 길

여행을 떠난 세준이는 지도를 하나 구하였다. 이 지도는 아래 그림과 같이 직사각형 모양이며 여러 칸으로 나뉘어져 있다. 한 칸은 한 지점을 나타내는데 각 칸에는 그 지점의 높이가 쓰여 있으

www.acmicpc.net

 

풀이 방법

이 문제는 (0,0)에서 출발해 오른쪽 아래인(N-1,M-1)위치까지 내리막길로만 이동해서 도착할 수 있는 경로의 수를 구하는 문제였습니다.

1) DFS로 풀기 -> 시간초과 발생

2) DFS + DP로 풀기

 

처음에는 단순히 DFS로 이 문제를 풀었는데

DFS로 풀 경우, 이미 갔었던 경로를 다시 확인하기 때문에 시간초과가 발생했습니다.

 

그래서 두번째로 푼 방법이 DFS + DP를 이용해 풀었습니다.

(N-1,M-1)위치까지 이동했을 경우에는 DP에 경로의 개수를 저장해 두고, 다른 점에서 또 탐색을 할 경우에 해당 경로를 더해주는 방식으로 구현했습니다.

 

코드

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class Main_BJ_1520_내리막길 {
    
    static int N,M;
    static int [][] map, route;
    
    static int [] dx= {-1,0,1,0};
    static int [] dy= {0,1,0,-1};
 
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;
        
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        
        map = new int[N][M];
        route = new int[N][M];
        
        for(int i=0;i<N;i++) {
            st = new StringTokenizer(br.readLine());
            for(int j=0;j<M;j++) {
                map[i][j] = Integer.parseInt(st.nextToken());
                route[i][j] = -1;
            }
        }
        System.out.println(dfs(0,0));
        
        for(int i=0;i<N;i++) {
            for(int j=0;j<M;j++) {
                System.out.print(route[i][j]+" ");
            }
            System.out.println();
        }
    }
    
    public static int dfs(int x, int y) {
        if(x==N-1 && y==M-1) {
            return 1 ;
        }
        
        if(route[x][y]!=-1return route[x][y];
        
        route[x][y]=0;
        for(int i=0;i<4;i++) {
            int nx = x + dx[i];
            int ny = y + dy[i];
            
            if(range(nx,ny)&&map[nx][ny]<map[x][y]) {
                route[x][y]+=dfs(nx,ny);
            }
        }
        return route[x][y];
    }
    
    public static boolean range(int x, int y) {
        return x>=0 && x<&& y>=0 && y<M;
    }
 
}
cs

 

 

'문제 > 백준' 카테고리의 다른 글

백준 16562 친구비 [JAVA]  (0) 2021.09.21
백준 2531번 회전 초밥 [JAVA]  (0) 2021.09.17
백준 17121 연구소2 [JAVA]  (0) 2021.09.02
백준 16236번 아기 상어 [JAVA]  (0) 2021.08.29
백준 9081번 단어 맞추기 [JAVA]  (0) 2021.07.08

API란?

  • Application Programming Interface
  • 응용 프로그램에서 사용할 수 있도록, 운영체제나 프로그래밍 언어가 제공하는 기능을 제어할 수 있게 만든 인터페이스

👉🏻 OPEN API는 뭘까?

  • 프로그래밍에서 사용할 수 있는 개방되어 있느 상태의 인터페이스
  • NAVER, KAKAO 등 포털 서비스 사이트 등 다양한 데이터를 외부 응용 프로그램에서 사용할 수 있도록 OPEN API를 제공

REST란?

  • Representational State Transfer의 약어로 하나의 URL은 하나의 고유한 리소스를 대표하도록 설계된다는 개념에 전송방식을 결합해서 원하는 작업 지정

  • HTTP URI를 통해 제어할 자원을 명시하고 HTTP Method를 통해 해당 자원을 제어하는 명령을 내리는 방식의 아키텍처

  • HTTP Method
    • POST : 리소스 생성
    • GET : 리소스 조회
    • PUT : 리소스 수정
    • DELETE : 리소스 삭제

👉🏻GET / POST 차이

  • GET방식 : 클라이언트에서 서버로 어떤 리소스로부터 필요한 정보를 요청하기 위해 사용하는 메서드 EX) 게시판 게시물 조회
    • 데이터 URL주소 끝에 파라미터로 쿼리 스트링을 포함하여 전송
    • 요청 길이에 제한있다.
    • 파라미터에 붙여서 전달하기 때문에 보안에 취약하다.
    • 멱등이다.

  • POST방식 : 클라이언트에서 서버로 리소스를 생성하거나 업데이트하기 위해 데이터를 보낼 때 사용하는 메서드 EX) 게시판 글 작성
    • 데이터 HTTP 메시지 BODY부분에 담아서 전송
    • 요청 길이에 제한이 없다.
    • BODY에 담아서 보내기 때문에 데이터 노출되지 않아 보안에 강함
    • 멱등이 아니다.


    멱등이 뭐야❓
    • 연산을 여러 번 적용하더라도 결과가 달라지지 않는 성질
    • 즉, GET은 리소스를 조회만하기 때문에 여러 번 요청하더라도 응답은 똑같을 것이다. 하지만 POST는 리소스를 새로 생성하거나 업데이트할 때 사용되기 때문에 멱등이 아니라고 볼 수 있다.

👉🏻Swagger란?

  • 간단한 설정으로 프로젝트의 API 목록을 웹에서 확인 및 테스트 할 수 있게 해주는 라이브러리

'정리 > Spring' 카테고리의 다른 글

Spring Security 란?  (0) 2024.12.10
[Spring] DI & AOP  (0) 2021.09.24
[Spring] Spring MVC  (0) 2021.09.09
[Spring] Spring이란?  (0) 2021.09.09
[Spring Boot + Vue.js] 구글로그인  (0) 2021.08.18

Spring MVC란?

👉🏻 model, view, controller의 합성어로 소프트웨어 디자인 패턴

  • Model : Controller에서 받은 데이터를 저장하는 역할
  • View : jsp 파일등과 같이 화면에 시각적으로 표현해주는 역할
  • Controller : 사용자의 요청을 받고 응답을 하는 로직을 담당. 접근한 url에 따라 요청사항을 파악하고 그에 맞는 데이터를 model에 의뢰하고 view에 반영해서 사용자에게 보여주는 역할

👉🏻Spring MVC 요청흐름

  • Request → DispatcherServlet (web.xml) → Controller → Logic처리(service, db접근) → View 전달 → response

  • DispatcherServlet : 모든 request를 받는 관문. request를 실제로 처리할 Controller에게 클라이언트의 요청을 전달하고, controller가 리턴한 결과값을 View에게 전달하여 알맞은 응답 생성
  • Controller : 클라이언트의 요청을 처리한 뒤, Model을 호출하고 그 결과를 DispatcherServlet에게 알려줌
  • View : Controller의 처리결과를 보여울 응답화면 생성

👉🏻VO, DTO, DAO란?

  • VO(Value Object) : 실제 데이터만 저장하는 클래스
  • DTO(Data Transfer Object) : 데이터를 주고 받기 위해 사용하는 클래스
  • DAO(Data Access Object) : DB에 접근하여 실제 데이터를 조회/조작하는 클래스 Repository 또는 Mapper에 해당

👉🏻MVC Pattern 특징

  • 어플리케이션의 확장을 위해 model, view, controller 세 영역으로 분리
  • 컴포넌트의 변경이 다른 영역의 컴포턴트에 영향을 미치지 않는다. = 유지보수 용이하다.
  • 컴포넌트 간의 결합성이 낮아 프로그램 수정이 용이하다. = 확장성이 뛰어나다.

장점

  • 화면과 비즈니스 로직을 분리해서 작업 가능
  • 영역별 개발로 확장성 뛰어남
  • 표준화된 코드를 사용하므로 공동작업 용이 및 유지보수성 좋음

단점

  • xml를 기반으로하는 프로젝트 설정은 많은 시간 소요
  • Tomcat과 같은 WAS 별도 설치

해결책( = Spring Boot)

  • 자동설정을 도임하여 DispatcherServlet과 같은 설정 시간 감소
  • spring-boot-starter로 외부 도구 사용
  • 내장 톰캣 제공하여 별도의 WAS 필요 X


웹 서버 VS WAS❓

  • 웹 서버(Apache) : 클라이언트가 웹 브라우저의 어떠한 페이지 요청을 하면 웹 서버에서 그 요청을 받아 정적 컨텐츠(HTML, CSS 등 즉시 응답가능한 컨텐츠)를 제공하는 서버
  • WAS(Tomcat) : 웹 서버 단독으로 처리할 수 없는 데이터베이스의 조회나 다양한 로직 처리가 필요한 동적 컨텐츠를 제공하는 서버

👉🏻그럼 웹 서버는 동적 컨텐츠를 제공하지 못하나?

  • 웹 서버가 동적 컨텐츠 요청을 받으면 WAS에게 해당 요청을 넘겨주고, WAS에어 처리한 결과를 클라이언트에게 전달해주기도 한다!

👉🏻 그럼 WAS를 쓰면 되는거 아닌가?

  • WAS는 DB조회 및 다양한 로직처리하는 데 집중하기 때문에 단순한 정적 컨텐츠를 웹 서버에 맡겨 기능을 분리시킴으로써 서버 부하 방지!
  • 만약 WAS가 정적 컨텐츠 요청까지 처리한다면, 동적 컨텐츠 처리가 지연되면서 수행 속도도 느려질뿐더러 이로 인해 페이지 노출 시간이 지연되는 문제가 발생하여 효율성이 크게 떨어진다.

👉🏻 그럼 Apache Tomcat은 다른건가?

  • Tomcat에 정적 컨텐츠를 처리하는 기능이 추가되어, Tomcat가 Apache기능을 포함하고 있어 Apache Tomcat이라고 부른다!

👀참고

https://codechasseur.tistory.com/25 (웹서버 WAS차이)

https://minchoi0912.tistory.com/93 (Spring MVC)

'정리 > Spring' 카테고리의 다른 글

[Spring] DI & AOP  (0) 2021.09.24
[Spring] REST API  (0) 2021.09.09
[Spring] Spring이란?  (0) 2021.09.09
[Spring Boot + Vue.js] 구글로그인  (0) 2021.08.18
[Spring Boot] 이메일 인증 회원가입하기 구현  (2) 2021.07.23

+ Recent posts