728x90

https://school.programmers.co.kr/learn/courses/30/lessons/42587

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

3개의 배열을 이용해 풀었습니다.

answer는 프린터가 된 순서가 담길 배열입니다.

array는 매개변수로 입력받는 priorities의 배열이 큐로 변환될 배열입니다.

index는 array의 각 숫자들의 원래 인덱스를 저장할 배열입니다.

 

풀이 코드는 아래와 같은데 코드를 하나씩 풀어보면서 설명해보겠습니다.

import java.util.*;
class Solution {
    public int solution(int[] priorities, int location) {
        int[] answer = new int[priorities.length];
        Deque<Integer> array = new ArrayDeque<Integer>();
        Deque<Integer> index = new ArrayDeque<Integer>();
        
        for(int i = 0; i < priorities.length; i++ ){
            array.offer(priorities[i]);
            index.offer(i);
        }
        int sum = 1;
        while(array.peek() != null){
            int max = Collections.max(array);
            if(array.peek() < max){
                array.offer(array.poll());
                index.offer(index.poll());
            }else{
                array.poll();
                answer[index.poll()] = sum;
                sum += 1;
            }
        }
        
        return answer[location];
    }
}

 

 

초기값을 array와 index에 넣으면 위와 같습니다.

sum값은 프린터 되는 순서를 세어줄 변수입니다.

max는 array에서 가장 큰 값이 담기게 됩니다.

 

우선 array 배열의 첫 번째 값과 max값을 비교해서 첫 번째 값이 작을 경우

첫 번째 값을 배열 맨 뒤에 추가하고 인덱스의 첫 번째 값도 맨 뒤에 추가해줍니다.

 

이것을 반복하다가 array의 가장 큰 값과 만나면 가장 큰 값을 array에서 제거합니다.

그리고 answer의 해당 index에 순서 값인 sum을 넣어 주고 sum을 + 1 해줍니다.

이렇게 반복해서 array의 숫자가 사라질 때까지 반복하면 

프린터 순서가 담긴 answer 배열이 생성됩니다.

거기서 location으로 들어온 위치의 값을 반환하면 됩니다.

 

 

 

 

 

 

 

728x90
728x90

https://school.programmers.co.kr/learn/courses/30/lessons/12906

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

연속된 숫자가 중복될 경우 하나만 남기고 지워주면 되는 문제입니다.

처음에는 문제를 잘못 일고 중복된 숫자를 다 지우는 것인 줄 알았는데 아니었습니다.

 

제 문제 풀이 방식의 기본 개념은 아래와 같습니다.

우선 결과값을 담을 리스트와 비교할 숫자를 담을 변수를 하나 준비합니다.

그리고 배열의 첫 번째 숫자를 배열과 비교할 숫자의 변수에 담고 시작합니다.

그리고 배열을 순차적으로 돌면서 비교할 숫자와 숫자를 비교해 같으면 무시합니다.

다르다면 숫자를 결괏값 리스트에 담고 비교 변수도 같은 값으로 변경해줍니다. 

 

import java.util.*;

public class Solution {
    public int[] solution(int []arr) {
        List<Integer> l = new ArrayList<Integer>();
        int s = -1;
        for(int i : arr){
            if(s != i){
                l.add(i);
                s = i;
            }
        }
        int[] answer = new int[l.size()]; 
        for(int k = 0; k < l.size(); k++){
            answer[k] = l.get(k);
        }
        return answer;
    }
}
728x90

'Algorithm > Java 풀이' 카테고리의 다른 글

프로그래머스 폰켓몬 java 풀이  (0) 2022.09.28
프로그래머스 프린터 자바 풀이  (0) 2022.09.23
프로그래머스 K번째 수 Java풀이  (0) 2022.09.14
백준 1008 자바  (0) 2022.03.11
백준 10998 자바  (0) 2022.03.11
728x90

이번 주 스터디에서는 자료구조 중 스택과 큐에 대해 공부하고 문제를 풀어보는 시간을 가졌습니다.

전에도 스택과 큐에 대해서 공부해봤기 때문에 구조적인 측면에서 이해는 문제가 없었습니다.

하지만 파이썬으로 구현했던 거라 자바로 구현하려고 하니 '어떤 클래스를 사용하고 어떤 메서드를 사용하지?'라는 생각이 들었습니다.

그래서 이걸 간단히 정리해 보려고 합니다.

스택과 큐의 자료구조와 메서드에 대해 정리하겠습니다.

 

스택(Stack)

스택은 LIFO(Last In First Out)의 특징을 가지고 있습니다.

이건 가장 마지막으로 들어간 데이터가 가장 첫 번째로 나오는 성질을 말합니다.

다르게 표현하면 가장 먼저 들어간 데이터가 가장 마지막으로 나오는 것을 뜻하기도 합니다.

 

재귀적인 함수, 알고리즘에 사용됩니다.

데이터를 삽입 및 삭제에 O(1), 탐색에 O(n) 시간이 걸립니다.

 

자바에서는 Stack 클래스를 구현하여 제공합니다.

Stack 클래스 메서드는 아래와 같습니다.

메서드 내용
 boolean empty() 스택이 비어있는지 알려줍니다.
 Object peek() 스택의 맨 위에 저장된 객체를 반환합니다.
객체를 꺼내지는 않습니다.
비어있을 때 사용할 경우 예외 오류를 발생시킵니다.
Object pop() 스택 맨 위의 저장된 객체를 꺼냅니다.
비었을 때 사용할 경우 오류를 발생시킵니다.
Object push(Object o) 스탬 맨 위에 o를 저장합니다.
int search(Object o) 스택에서 주어진 객체 o를 찾아서 그 위치를 반환합니다.
못찾으면 -1을 반환합니다.
배열과 달리 위치는 1부터 시작합니다.
Stack<Integer> st = new Stack<Integer>();

 

큐(Queue)

큐는 FIFO(First In First Out)의 특성을 가지고 있습니다.

이는 먼저 집어넣은 데이터가 먼저 나오는 성질을 말합니다.

때문에 데이터를 집어넣으면 뒤부터 순차적으로 생성되고 

뺄 때는 가장 처음 데이터부터 나오게 됩니다.

 

삽입 및 삭제에 O(1), 탐색에 O(n)의 시간이 걸립니다.

CPU 작업을 기다리는 프로세스, 스레드 행렬 또는 네트워크 접속을 기다리는 행렬

너비 우선 탐색(BFS), 캐시 등에 사용됩니다.

 

자바에서 큐의 경우에는 클래스가 아닌 인터페이스를 제공합니다.

물론 구현해 놓은 클래스도 있기 때문에 그중 하나를 사용하면 됩니다.

예시로 ArrayDeque, ConcurrentLinkedDeque, LinkedList가 있습니다.

Deque의 경우에는 앞뒤로 데이터를 넣고 빼는 메서드를 가지고 있습니다.

 

메서드는 아래와 같습니다.

메서드 내용
 boolean add(Object o) 지정된 객체를 큐에 삽입합니다.
성공하면 true를 반환합니다.
실패하면 오류를 반환합니다.
 Object remove() 큐에서 객체를 꺼내 반환합니다.
비어있을 경우 오류를 발생시킵니다.
 Object element() 삭제없이 요소를 읽어옵니다.
비어있을 경우 오류를 발생시킵니다.
 boolean offer(Object o) 큐에 객체를 저장합니다.
성공하면 true를 반환합니다.
 Object poll() 큐에서 객체를 꺼내서 반환합니다.
비어있으면 null을 반환합니다.
 Object peek() 삭제없이 요소를 읽어옵니다.
큐가 비어 있으면 null을 반환합니다.

위 세 개와 아래 세 개의 메서드는 같은 기능을 하지만 오류를 반환하고 하지 않는 차이가 있습니다.

Queue<Integer> q = new LinkedList<Integer>()

 

728x90
728x90

https://school.programmers.co.kr/learn/courses/30/lessons/42748

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

정렬 알고리즘 1단계 문제입니다.

java.util.Arrays 클래스에 있는 메서드를 사용하지 않았다면 1단계지만 상당히 애먹었을 것 같습니다.

 

우선 코드는 아래와 같습니다.

import java.util.*;
class Solution {
    public int[] solution(int[] array, int[][] commands) {
        int[] answer = {};
        answer = new int[commands.length];
        int index = 0;
        for(int[] ijk : commands){
            int[] arr = Arrays.copyOfRange(array,ijk[0]-1,ijk[1]);
            Arrays.sort(arr);
            answer[index] = arr[ijk[2]-1];
            index += 1;
        }

        return answer;
    }
}

문제 풀이의 키는 commands의 이차원 배열을 분리해 i, j, k 각각의 값을 추출하는 것이라 판단했습니다.

그래서 향상된 for문을 사용해 ijk라는 일차원 배열로 값을 받고 배열의 인덱스를 사용해 해결했습니다.

 

배열이 있으면 자연스럽게 향상된 for문을 사용하게 되는데 이번 문제의 경우 일반 for문을 사용했으면 

index 변수를 새로 생성하지 않아도 됩니다.

 

아래의 코드는 같이 공부하는 스터디원의 풀이입니다.

Arrays 클래스의 copyOfRange() 메서드를 사용하지 않고 풀려고 했습니다.

그랬더니 sort() 메서드를 사용할 경우 배열의 실제 데이터까지 변경되어 올바른 답이 나오지 않았습니다.

그다음에는 새로운 int[] 배열을 만들어 매번 매개변수 array값으로 선언해주면 되지 않을까?라고 생각했지만

이때 새로운 int[] 배열이 array의 메모리 주소 값을 참조하는 것이기 때문에 새로운 int[] 배열을 정렬할 경우 실제 array의 

데이터 값도 정렬되어 올바른 답이 나오지 않았습니다.

때문에 얕은복사가 아닌 깊은 복사가 필요했고, clone()이라는 메서드를 생성해서 데이터 값을 담아 문제를 해결했습니다.

import java.util.*;

class Solution {
    public int[] solution(int[] array, int[][] commands) {
        int[] answer = new int[commands.length];
        
        for(int a = 0; a < commands.length; a++){
            
            int i = commands[a][0];
            int j = commands[a][1];
            int k = commands[a][2];
            int[] arr = array.clone(); // clone을 사용하지 않는다면?
             
            Arrays.sort(arr,i-1,j);
            answer[a] = arr[i+k-2];
        }
        return answer;
    }
}

 

728x90

'Algorithm > Java 풀이' 카테고리의 다른 글

프로그래머스 프린터 자바 풀이  (0) 2022.09.23
프로그래머스 같은 숫자는 싫어 자바풀이  (1) 2022.09.23
백준 1008 자바  (0) 2022.03.11
백준 10998 자바  (0) 2022.03.11
백준 1001 자바  (0) 2022.03.11
728x90

Java의 정렬 방법 중 Java.util.Arrays 클래스의 sort() 메서드를 사용해 보겠습니다.

 

sort() 메서드는 매개변수로 기본타입과 객체를 받을 수 있습니다.

그리고 시작 인덱스와 종료 인덱스를 추가로 받아 부분 정렬이 가능합니다.

추가로 기본적으로 오름차순 정렬되지만 내림차순으로도 정렬 가능합니다. 


문법

sort(primitive type array) 

  - 매개변수로 기본타입 배열을 이용합니다.

  - int[], double[], float[], long[], short[], byte[], char[] 

sort(primitive type array, int startIndext, int endIndex)

  - 기본타입에 시작 인덱스 값과 종료 인덱스 값을 지정합니다.

 

sort(Object[] o)

  - 매개변수로 객체를 받습니다.

  - Wrapper Class 값을 받을 수 있습니다.

sort(Object[] o, int startIndext, int endIndex)

 

sort(T[] a, Comparator<? super T> c)

  - 매개변수로 객체를 받으며 Comparator의 메서드에 따라 정렬할 수 있습니다.

  - 주로 Comparator.reverseOrder()를 사용해 내림차순으로 사용합니다.

sort(T[] a, int startIndext, int endIndex, Comparator<? super T> c)

 

예시

오름차순

int[] arr = {5, 3, 4, 1, 2};

Arrays.sort(arr);

String[] arr2 = {"peach", "apple", "banana"};

Arrays.sort(arr2);

Arrays.stream(arr).forEach(a -> System.out.println(a));
Arrays.stream(arr2).forEach(a -> System.out.println(a));

//결과
1
2
3
4
5
apple
banana
peach

내림차순

  - 기본타입의 배열을 내림차순으로 정렬하고 싶다면

기본타입 배열을 래퍼 클래스로 감싸야 내림차순으로 정렬할 수 있습니다.

Integer[] arr = {5, 3, 4, 1, 2};

Arrays.sort(arr, Comparator.reverseOrder());

String[] arr2 = {"peach", "apple", "banana"};

Arrays.sort(arr2, Comparator.reverseOrder());

Arrays.stream(arr).forEach(a -> System.out.println(a));
Arrays.stream(arr2).forEach(a -> System.out.println(a));

//결과
5
4
3
2
1
peach
banana
apple

 

 

728x90
728x90

어제까지 부록을 제외하고는 Clean Code라는 책을 다 읽었습니다.

깨끗한 코드라는 건 뭘까?라는 클린코드 단어의 정의 개요부터 시작해 몇몇 방법들을 소개합니다.

이후에는 기존의 코드들을 직접 리팩토링하는 과정을 보여주며 

이론을 적용하고 그런 생각을 한 이유를 작성해 독자의 이해를 도와줍니다.

 

물론 제가 초보라 이해하기 어려운 부분들이 많이 있었지만 도움이 될만한 부분도 많아서

두고두고 보면서 잊지 않으려고 글을 작성합니다.  물론 시간이 된다면 그때마다 책을 다시 읽을 생각입니다. ㅎ

클래스와 변수의 이름을 정할 때는 명사가 좋다.
메서드와 함수는 어떤 기능을 하는지 서술형으로 작성해라.
클래스의 경우 한 클래스가 하나의 역할만 가지도록 해라.
모든 테스트를 실행한다.
중복을 줄여라.
프로그래머의 의도를 표현한다.
클래스와 메서드 수를 최소로 줄인다.

등 책에는 더 많은 개념들과 자세한 수정한 과정들이 작성되어 있습니다.

 

그리고 책에서는 TDD를 굉장히 강조하는데 저는 아직 한 번도 해본 적은 없지만

저랑 잘 맞을 것 같다는 생각이 듭니다. 다음 프로젝트나 기존 프로젝트를 수정할 때

테스트 코드도 짜보도록 해야겠습니다.

728x90

'잡담' 카테고리의 다른 글

백준 CLASS 1 ++  (0) 2022.01.10
노션(Notion) 간단한 가계부 공유  (0) 2021.12.21
728x90

JavaScript 코드를 따로 정리하려고 js 파일을 만들었는데 

<%= request.getContextPath %>가 사용이 안 될지는 몰랐습니다.

그래서 다른 방법을 알아보는 데 사용하고 싶을 만큼 한눈에 와닿는 건 찾지 못했습니다.

결국 직접 만들었는데 이것도 지저분하긴 합니다. 그래도 저 같은 사람이 있을까 봐 공유합니다.

 

아래 MDN 사이트의 Location 자료를 보고 origin과 pathname 속성을 사용했습니다.

https://developer.mozilla.org/ko/docs/Web/API/Location

 

Location - Web API | MDN

Location 인터페이스는 객체가 연결된 장소(URL)를 표현합니다.

developer.mozilla.org

 

http/https에서 origin 속성을 사용하는 경우에는 도메인을 포함해 포트번호까지 문자열로 반환합니다.

pathname의 경우 도메인 이후 URL주소를 문자열로 반환합니다.

 

http://localhost:8080/controller/developer/userList.do

전체 URL 경로가 위와 같다면 origin과 pathname의 반환 값은 아래와 같습니다.

var pathname = window.location.pathname;
/controller/developer/userList.do


var origin = window.location.origin;
http://localhost:8080

 

이와 같은 결과 값을 가지고 저는 <%= request.getContextPath %>와 같은 값을 적용하기 위해

js파일 상단에 아래와 같은 변수를 설정해줬습니다.

스플릿 했기 때문에 양쪽에 "/"를 붙여주고 인덱스 1번에 있는 값을 가운데 넣습니다.

const pathname = "/" + window.location.pathname.split("/")[1] + "/";
const origin = window.location.origin;

const contextPath = origin + pathname;

그 값은 아래와 같습니다.

http://localhost:8080/controller/

 

 

728x90

'JavaScript' 카테고리의 다른 글

jQuery ajax의 processData, contentType, cache 속성  (0) 2022.08.06
728x90

cache

기본값은 true로 dataType이 'script'나 'jsonp'일 때는 기본값이 false다.

false로 설정하면 요청된 페이지가 브라우저에 캐싱되지 않도록 한다. 

그리고 HEAD와 GET요청에만 정확하게 작동한다.

contentType

ajax를 통해서 서버에 데이터를 보낼 때 데이터 유형을 결정한다.

기본값은 'application/x-www-form-urlencoded; charset=UTF-8'이다.

jQuery 1.6부터는 false값을 설정하여 요청 헤더에 콘텐츠 타입을 설정하지 않을 수 있다.

 

processData

기본값은 true로 data속성의 값이 콘텐츠 타입에 맞게 쿼리 문자열로 처리된다.

처리되지 않은 데이터를 보내려면 이 속성값으 false로 바꾸면 된다.

 

이 내용은 ajax의 multipart/form-data로 이미지를 서버로 전송하려고 할 때

500 에러가 발생하면서 해결법을 찾을 때 나온 속성들이다.

해본 결과 cache는 설정 안 해줘도 된다.

function addReview(){
    var formData = new FormData($("#addReview")[0]);
   
    $.ajax({
        url: "addReview.do",
        method: "POST",
        data: formData,
        enctype: 'multipart/form-data',
        processData: false,
        contentType: false,
        success: function(data){
        	myModal.hide();
        },
        error: function(){
        	console.log("error");
        }
    });
}

 

 


더 자세한 내용은 jQuery 공식 사이트를 활용하세요.

https://api.jquery.com/jQuery.Ajax/#jQuery-ajax-settings-settings

 

jQuery.ajax() | jQuery API Documentation

Description: Perform an asynchronous HTTP (Ajax) request. The $.ajax() function underlies all Ajax requests sent by jQuery. It is often unnecessary to directly call this function, as several higher-level alternatives like $.get() and .load() are available

api.jquery.com

 

728x90

'JavaScript' 카테고리의 다른 글

JS 파일에서 contextpath 사용하기  (0) 2022.08.12
728x90

일단 부트스트랩 5 모달창 다루는 공식 사이트입니다.

https://getbootstrap.com/docs/5.2/components/modal/#how-it-works

 

Modal

Use Bootstrap’s JavaScript modal plugin to add dialogs to your site for lightboxes, user notifications, or completely custom content.

getbootstrap.com

 

제가 원한 건 페이지에 접속 시 아래와 같이 바로 모달창이 뜨는 것이었습니다.

공식 예제에는 버튼을 주로 사용해서 혹시 필요하신 분이 있을까 올립니다.

 

<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" 
    aria-labelledby="exampleModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
            	<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
            	<button type="button" class="btn-close" 
                data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body">
            ...
            </div>
            <div class="modal-footer">
            <button type="button" class="btn btn-secondary" 
            		data-bs-dismiss="modal">Close</button>
            <button type="button" class="btn btn-primary">Save changes</button>
            </div>
        </div>
    </div>
</div>

일단 모달창을 준비해주시고요. 해당 모달은 아래와 같이 생겼습니다.

아래는 페이지에 들어왔을 때 켜는 코드입니다. 쉽게 표현하기 위해서 jQuery를 사용했습니다.

<script type="text/javascript">
	$().ready(function(){
		const myModal = new bootstrap.Modal('#exampleModal', {});
		myModal.show();
	})
</script>
const myModal = new bootstrap.Modal('모달창ID', {옵션});

 

원할 때 숨기고 싶으시면 hide() 메서드를 사용하시면 됩니다.

<script type="text/javascript">
	const myModal = new bootstrap.Modal('#exampleModal', {});
    
    $().ready(function(){
		myModal.show();
	})
    
    function closeModal(){
    	myModal.hide();
    }
</script>

 

728x90
728x90

팀 프로젝트에서 사용시간이 지난 예약 내역에 대해 사용완료 처리를 해야 할 필요성이 있었습니다.

그 방법으로 spring @scheduled 어노테이션을 찾았습니다.

 

Maven 프로젝트이고 Java 17.0.2/ sts 3.9.18 버전을 사용중입니다.

 

@scheduled 어노테이션을 사용하기 위해서는 몇 가지 사전작업이 필요합니다.

spring < appServlet < servlet-context.xml에 하단의 빨간 줄로 표시한 것을 추가해주세요

xmlns:task="http://www.springframework.org/schema/task"
http://www.springframework.org/schema/task https://www.springframework.org/schema/task/spring-task.xsd"

 

그리고 Bean 등록이 필요한데 저는 service 패키지 하위에 Scheduler 클래스를 생성했습니다.

이걸 고려하면서 Scheduler Bean등록을 해주세요. Bean 등록도 servlet-context.xml에 해주시면 됩니다.

잘 모르겠다 하시는 분들은 최하단의 공식 가이드를 봐주세요.

 

클래스에 @Component, 사용하실 메서드에 @Scheduled 어노테이션을 잊지 마세요.

@Scheduled 뒤 옵션에는 여러 가지가 있지만 제가 사용한 건 cron 옵션입니다.

@Scheduled(cron = "0 0 0-23 * * *")
	public void autoUpdate() {
		bookService.updateSuccess();
	}

cron 뒤에 오는 *가 각각 의미하는 것은 아래와 같습니다. 미리 예시로 주는 표현법도 있습니다.

제가 설정한 것은 0시부터 23시까지 매시 정각에 실행될 수 있도록 설정했습니다.

 

더 많은 옵션 정보가 필요하시면 아래 링크를 봐주세요.

https://docs.spring.io/spring-framework/docs/current/reference/html/integration.html#scheduling

 

설정은 끝났습니다.

메서드 안에 있는 bookService.updateSuccess(); 코드는 제가 매시각 실행할 서비스 로직이라 중요하지 않습니다.

 

 

 

 

https://spring.io/guides/gs/scheduling-tasks/#initial

 

Scheduling Tasks

this guide is designed to get you productive as quickly as possible and using the latest Spring project releases and techniques as recommended by the Spring team

spring.io

 

728x90

+ Recent posts