<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>196code-gray.log</title>
        <link>https://velog.io/</link>
        <description>기록을 합시다</description>
        <lastBuildDate>Sun, 10 Dec 2023 14:34:45 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>196code-gray.log</title>
            <url>https://velog.velcdn.com/images/196code-gray/profile/e580e053-5586-476b-82d5-2cc3dccc5cc2/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. 196code-gray.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/196code-gray" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[블로그 이전합니다]]></title>
            <link>https://velog.io/@196code-gray/%EB%B8%94%EB%A1%9C%EA%B7%B8-%EC%9D%B4%EC%A0%84%ED%95%A9%EB%8B%88%EB%8B%A4</link>
            <guid>https://velog.io/@196code-gray/%EB%B8%94%EB%A1%9C%EA%B7%B8-%EC%9D%B4%EC%A0%84%ED%95%A9%EB%8B%88%EB%8B%A4</guid>
            <pubDate>Sun, 10 Dec 2023 14:34:45 GMT</pubDate>
            <description><![CDATA[<p>블로그를 이전하게 되었습니다.</p>
<h2 id="왜-이전하는가">[왜 이전하는가]</h2>
<p>처음에 velog를 사용하게 된 이유는 깔끔하고 단순함. 그 두가지 이유 때문이였습니다.
velog는 특별하게 꾸미는 기능도 없고 사용자가 무언가를 건드릴 수도 없기에 글에만 집중할 수 있겠구나 싶어서 velog를 주 블로그로 고르게 되었습니다.</p>
<p>그런데 제가 장점이라고 생각했던 부분들이 단점이 되었습니다.
사용자가 손을 댈 수 없다는 것은 제 블로그 홈을 마음대로 설정할 수 없다는 의미이고 게시글도 마찬가지 였습니다. 폰트를 변경한다던가 조금 보기 쉬운 방식으로도 변경이 불가능하다는 의미였습니다.</p>
<p>그리고 제일 불편했던 점은 보기 방식인데요</p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/d5ea1459-7f31-414b-acc3-cac11a8a6977/image.png" alt=""></p>
<p>velog 본인 페이지에 들어오게 되면 이 화면이 나오게 됩니다.
그런데 게시글 이미지가 너무 커서 한 화면에 최대 2개의 게시글 밖에 보여지지않습니다.</p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/47a88b8d-c128-49aa-bf99-51a4199f4fdb/image.png" alt=""></p>
<p>그것도 이미지가 짤리면 2개까지 보여지는 모습입니다.</p>
<p>처음에 글이 몇개 없을 때는 마우스 몇번 내리면 되겠지만 글이 많아지고 계속 내려야한다면 시간이 꽤 걸립니다. </p>
<h4 id="그럼-검색기능을-이용해서-찾으면-되지않을까">[그럼 검색기능을 이용해서 찾으면 되지않을까?]</h4>
<p>검색기능을 이용해서 게시글을 찾으면 </p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/23d14cfb-78fe-42f6-b1bb-828d79bb8132/image.png" alt=""></p>
<p>네 찾아지지 않습니다.</p>
<p>맨 앞 글자부터 찾아도 그럴까?</p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/709ebaba-9aa4-43d0-be61-0c03ad8e9827/image.png" alt=""></p>
<p>네 검색이 되지않습니다.</p>
<p>그래서 태그 기능을 이용해서 게시글의 범위를 줄여서 찾는 방법도 해보았으나 범위가 줄어들었지만 결국 스크롤을 내리며 찾는 것은 똑같기에 좋은 방안이 되지 못했습니다.</p>
<h2 id="새로-이전하는-블로그">새로 이전하는 블로그</h2>
<p><a href="https://196code-gray.tistory.com/">블로그 주소</a></p>
<p>부족한 글이었음에도 불구하고 그동안 읽어주신 분들 모두 감사드립니다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Refactoring] Hello, Developer! - 1]]></title>
            <link>https://velog.io/@196code-gray/Refactoring-Hello-Developer</link>
            <guid>https://velog.io/@196code-gray/Refactoring-Hello-Developer</guid>
            <pubDate>Sat, 02 Dec 2023 05:39:23 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/196code-gray/post/b2cfb325-74b7-49d8-a869-3a17b9cd6ae2/image.png" alt=""></p>
<p>Hello, Developer 라는 프로젝트는 정보를 공유할 수 있는 개발자 커뮤니티 사이트이다.
코드스테이츠에서 한달 동안 진행한 프로젝트이다.</p>
<p><strong>목적 : 부족한 점이 많아 리팩토링을 하며 개선해보려고 한다.</strong></p>
<h2 id="리팩토링">리팩토링</h2>
<h3 id="문제점--효율이-나쁘다">문제점 : 효율이 나쁘다.</h3>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/0639e3a4-95a6-4055-85a5-ce42efa4217e/image.png" alt=""></p>
<p>위 메서드는 사용자가 추천을 눌렀을 경우 DB에 저장하는 메서드이다.</p>
<p>그리고 사용자의 ID와 게시글의 ID를 받아서 사용자가 해당 게시글에 추천을 누른 적이 있는지를 찾는 코드이다.</p>
<p>JPQL 문을 사용하면 더 편리하게 사용 할 수 있는데 왜 굳이 stream으로 사용했냐면 내가 JPQL의 존재를 알지 못 했기 때문이다. 그 당시에 JPA에 대해 잘 알지 못하면서 JPA를 사용했기 때문에 이런 상황이 발생하였다.</p>
<h3 id="개선">개선</h3>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/8ed6258f-0423-420d-b928-b746a8b1b27a/image.png" alt=""></p>
<p>repository에서 직접적으로 DB에 해당 값이 있는지를 찾는 쿼리문을 작성해주었다.</p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/7f0fa447-a804-4b41-a8c8-3133a6191171/image.png" alt=""></p>
<p>변경 후 코드 길이도 감소하였고, </p>
<h3 id="문제점--알-수-없는-set-사용">문제점 : 알 수 없는 set 사용</h3>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/6dd8f548-805c-4871-bf7a-c36f11edafbe/image.png" alt=""></p>
<p>게시글을 수정하는 부분의 코드이다.
입력으로 들어오는 petch 변수에 값이 있다면 find.setTitle 로 수정해주는 코드이다.</p>
<h3 id="개선-1">개선</h3>
<p>하지만 이게 수정인지 새로 지정을 해주는 건지 구분이 되지 않아 update 라는 메서드를 만들어 변경해주었다.</p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/d7f94d58-d321-4ffd-af56-63484a96730c/image.png" alt=""></p>
<p>이제 이 코드가 어떨 경우에 사용하는지 한눈에 알아보기 쉬워졌다.</p>
<p>그리고 현재 람다식을 사용해서 직접 update메서드에 매개변수를 넣어주고 있는데 메서드 레퍼런스를 사용해서 이 부분을 수정해보겠다.</p>
<pre><code>메서드 래퍼런스란?
람다표현식을 더 간단하게 표현한 것</code></pre><p><img src="https://velog.velcdn.com/images/196code-gray/post/23b377a4-54da-4da8-ae33-24207a9f9123/image.png" alt=""></p>
<p>아까 람다식을 사용한 것보다 메서드 래퍼런스를 이용하여 코드를 작성한 것이 읽기가 쉬워진 것을 알 수 있다.</p>
<h3 id="문제점--사용하지-않는-코드">문제점 : 사용하지 않는 코드</h3>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/1cf0cb5a-b5bb-438c-b299-7df200dfc39f/image.png" alt=""></p>
<p>위 사진처럼 사용하지 않는 메서드가 있는 것을 발견하였다.</p>
<p>해당 코드는 소수점을 계산하고 내림차순으로 정렬 한 뒤 리턴해주는 메서드인데 당시 잘 구현했다고 생각하여 담번에 참고 하고자 지우지않고 두었다.</p>
<p>하지만 읽는 사람 입장에서 가독성이 불편해질 수 있고, 쓰지 않는 메서드를 놔두는 것은 좋지않다고 생각한다.</p>
<h3 id="개선-2">개선</h3>
<p>해당 코드를 제거하고 코드길이가 12줄 줄었다.</p>
<p>그 외에도 controller에 있는 필요없는 로직을 제거하여 코드길이를 28줄 줄였다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java] 숨바꼭질 - 1697]]></title>
            <link>https://velog.io/@196code-gray/Java-%EC%88%A8%EB%B0%94%EA%BC%AD%EC%A7%88-1697</link>
            <guid>https://velog.io/@196code-gray/Java-%EC%88%A8%EB%B0%94%EA%BC%AD%EC%A7%88-1697</guid>
            <pubDate>Tue, 14 Nov 2023 03:40:41 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/196code-gray/post/bd10bdc8-910a-4b8c-9d1d-acedb8b71553/image.png" alt=""></p>
<h4 id="문제">문제</h4>
<p>난이도 - 실버1</p>
<p>유형 - BFS(너비 탐색)</p>
<p><a href="https://www.acmicpc.net/problem/1697">문제링크</a></p>
<h3 id="문제-설명">문제 설명</h3>
<p>수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때 걷는다면 1초 후에 X-1 또는 X+1로 이동하게 된다. 순간이동을 하는 경우에는 1초 후에 2*X의 위치로 이동하게 된다.</p>
<p>수빈이와 동생의 위치가 주어졌을 때, 수빈이가 동생을 찾을 수 있는 가장 빠른 시간이 몇 초 후인지 구하는 프로그램을 작성하시오.</p>
<hr>
<h3 id="풀이">풀이</h3>
<p>위 문제를 그래프로 그려봤을 때 아래 사진과 같았다.
<img src="https://velog.velcdn.com/images/196code-gray/post/b7f64f5e-5af7-4616-8841-8c3d34b50075/image.jpg" alt=""></p>
<p>엄청나게 쭉쭉 늘어나지만 이미 방문했던 곳은 가지 않기 때문에 정리하면 이렇게 된다.</p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/4737b849-b218-4d6f-9919-e48ca310783d/image.jpg" alt=""></p>
<p>왜 시작이 1초인지는 방문했던 배열과 방문하지 않았던 배열을 더 쉽게 구분하기 위함이다.
그래서 결과값을 리턴할 때 -1를 한 값을 리턴해준다.</p>
<h3 id="코드">코드</h3>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;

public class Main {
    static int n, k;
    static int[] visited;   // 시간 저장 배열
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        n = Integer.parseInt(st.nextToken());
        k = Integer.parseInt(st.nextToken());
        visited = new int[100_001];     // 최대 넓이로 선언
        System.out.println(BFS(n));
        }
        private static int BFS(int n) {
        Queue&lt;Integer&gt; q = new LinkedList&lt;&gt;();
        visited[n] = 1;     // 맨 처음 방문했던 곳을 1초로 생각
        q.add(n);
        while (!q.isEmpty()) {      // 큐가 빌 때까지 반복
            int num = q.remove();
            if (num == k) {
                return visited[num] -1;     // 처음에 1초로 시작 했으므로 1초 빼주기
            }
            if (num -1 &gt;= 0 &amp;&amp; visited[num -1] == 0) {      // 지정된 수에서 1초 뺀 경우
                visited[num -1] = visited[num] + 1;
                q.add(num -1);
            } if (num + 1 &lt;= 100_000 &amp;&amp; visited[num + 1] == 0) {        // 지정된 수에서 1초 더한 경우
                visited[num + 1] = visited[num] + 1;
                q.add(num + 1);
            } if (num * 2 &lt;= 100_000 &amp;&amp; visited[num * 2] == 0) {        // 지정된 수에서 2를 곱한 경우
                visited[num * 2] = visited[num] + 1;
                q.add(num * 2);
            }
        }
        return -1;
        }
    }</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[study] Spring Boot 스터디]]></title>
            <link>https://velog.io/@196code-gray/study-Spring-Boot-%EC%8A%A4%ED%84%B0%EB%94%94</link>
            <guid>https://velog.io/@196code-gray/study-Spring-Boot-%EC%8A%A4%ED%84%B0%EB%94%94</guid>
            <pubDate>Tue, 07 Nov 2023 13:55:08 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/196code-gray/post/ea45eac0-029d-488a-b575-cbd8c321f2e8/image.png" alt=""></p>
<p>출처 : <a href="https://www.thebestcolleges.org/17-scientifically-proven-ways-to-study-better-this-year/">https://www.thebestcolleges.org/17-scientifically-proven-ways-to-study-better-this-year/</a></p>
<p>이 스터디는 Spring Boot 를 이용해 특정 요구사항을 개발하고 스터디원끼리 코드리뷰를 해주는 스터디이다.</p>
<p>스터디를 진행한지는 꽤 되었다. 늦었지만 이제라도 리뷰를 작성해보려고 한다.</p>
<p>스터디 진행방식은 이렇다</p>
<ol>
<li>매 주차마다 추가 요구사항을 정한다.</li>
<li>팀원이 PR을 올리면 최소 3명은 코드 리뷰를 해 줄 것.</li>
</ol>
<p>프로젝트 방향은 사이렌 오더 였다.</p>
<p>1주차 요구사항</p>
<pre><code>- 메뉴 등록
- 메뉴 수정
- 메뉴 조회
- 메뉴 삭제</code></pre><hr>
<p>내가 받은 코드 리뷰(간략하게)</p>
<p>[배운 점]
생각보다 왜 이렇게 코드를 작성하는지 생각을 안하고 작성한 부분이 많았다.
그리고 내가 사용하는 기술임에도 잘 모르고 사용했구나 라는 생각이 들었다.</p>
<p>[개선 할 점]
항상 &quot;왜&quot; 라는 것을 생각하며 작성해야겠다.
오류를 해결하고 끝날 것이 아니라 왜 오류가 발생되었는지 어떻게 해결했는지를 알아보고, 같은 실수를 반복하지 않기 위해 자주 기록하는 습관 들이기.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java] Lv.2 프로그래머스 최솟값 만들기]]></title>
            <link>https://velog.io/@196code-gray/Java-Lv.2-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%B5%9C%EC%86%9F%EA%B0%92-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@196code-gray/Java-Lv.2-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%B5%9C%EC%86%9F%EA%B0%92-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Fri, 20 Oct 2023 01:36:13 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/196code-gray/post/9e48e68b-7fae-46df-b5ed-a6ec29b35082/image.png" alt=""></p>
<h2 id="문제">문제</h2>
<hr>
<p>길이가 같은 배열 A, B 두개가 있습니다. 각 배열은 자연수로 이루어져 있습니다.
배열 A, B에서 각각 한 개의 숫자를 뽑아 두 수를 곱합니다. 이러한 과정을 배열의 길이만큼 반복하며, 두 수를 곱한 값을 누적하여 더합니다. 이때 최종적으로 누적된 값이 최소가 되도록 만드는 것이 목표입니다. (단, 각 배열에서 k번째 숫자를 뽑았다면 다음에 k번째 숫자는 다시 뽑을 수 없습니다.)</p>
<p>예를 들어 A = [1, 4, 2] , B = [5, 4, 4] 라면</p>
<ul>
<li>A에서 첫번째 숫자인 1, B에서 첫번째 숫자인 5를 뽑아 곱하여 더합니다. (누적된 값 : 0 + 5(1x5) = 5)</li>
<li>A에서 두번째 숫자인 4, B에서 세번째 숫자인 4를 뽑아 곱하여 더합니다. (누적된 값 : 5 + 16(4x4) = 21)</li>
<li>A에서 세번째 숫자인 2, B에서 두번째 숫자인 4를 뽑아 곱하여 더합니다. (누적된 값 : 21 + 8(2x4) = 29)
즉, 이 경우가 최소가 되므로 29를 return 합니다.</li>
</ul>
<p>배열 A, B가 주어질 때 최종적으로 누적된 최솟값을 return 하는 solution 함수를 완성해 주세요.</p>
<p>링크 : <a href="https://school.programmers.co.kr/learn/courses/30/lessons/12941">https://school.programmers.co.kr/learn/courses/30/lessons/12941</a></p>
<hr>
<h2 id="설명">설명</h2>
<p>각 배열의 값을 곱한 뒤 누적해서 더한 값을 최소로 만들면 되는 문제이다.</p>
<p>곱해야 하므로 각 배열에서 작은 값과 큰 값을 곱하면 되겠다고 생각했다.
큰 값과 큰 값을 더하면 오히려 값이 더 커질 것이기 때문에. </p>
<p>A를 오름차순으로 정렬하고 B를 내림차순으로 정렬하여 풀었다.</p>
<h2 id="코드">코드</h2>
<pre><code class="language-java">import java.util.*;
class Solution
{
    public int solution(int []A, int []B)
    {
        int answer = 0;
        Arrays.sort(A);
        Integer[] arr = Arrays.stream(B).boxed().sorted(Collections.reverseOrder()).toArray(Integer[]::new);
        for (int i = 0; i &lt; A.length; i++) {
            answer += A[i] * arr[i];
        }

        return answer;
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[JPQL을 사용해보자!]]></title>
            <link>https://velog.io/@196code-gray/JPQL%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EC%9E%90</link>
            <guid>https://velog.io/@196code-gray/JPQL%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EC%9E%90</guid>
            <pubDate>Wed, 18 Oct 2023 03:01:28 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/196code-gray/post/d6266142-de15-4b68-b4a9-81a273876022/image.png" alt=""></p>
<p>사진 출처 : 스프링 공식 홈페이지</p>
<hr>
<p>JPQL 이란?
JPA에서 사용하는 쿼리 언어이다.</p>
<ul>
<li>JPA는 엔티티 중심으므로 쿼리 또한 엔티티 중심으로 작성해야 된다.</li>
<li>애칭이 반드시 필요하다.</li>
<li>대소문자는 구분하지 않는다. (엔티티의 대소문자는 구분)</li>
<li>엔티티에 따로 지정된 이름이 없다면 기본 엔티티 이름을 사용한다. ex. @Table(name = ~~)</li>
<li>sql과 문법이 매우 비슷하고 select, where, from, join, having 등을 지원한다.</li>
</ul>
<h3 id="사용방법">사용방법</h3>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/010e550c-4455-4454-b357-c9a0ce603933/image.png" alt=""></p>
<p>위 엔티티는 게시글 엔티티이다.</p>
<p>제목, 내용, 이름이 필드에 있다.</p>
<p>매개변수로 문자열을 받아 해당하는 게시글을 찾는 쿼리</p>
<pre><code class="language-sql">@Query(&quot;select p from DevPost p where p.title = :title&quot;)
Optional&lt;DevPost&gt; findTitle (@Param(&quot;title&quot;) String title);</code></pre>
<p>이런식으로 사용이 가능하다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java] Lv.2 프로그래머스 점프와 순간 이동]]></title>
            <link>https://velog.io/@196code-gray/Java-Lv.2-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A0%90%ED%94%84%EC%99%80-%EC%88%9C%EA%B0%84-%EC%9D%B4%EB%8F%99</link>
            <guid>https://velog.io/@196code-gray/Java-Lv.2-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A0%90%ED%94%84%EC%99%80-%EC%88%9C%EA%B0%84-%EC%9D%B4%EB%8F%99</guid>
            <pubDate>Wed, 18 Oct 2023 00:49:15 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/196code-gray/post/1ac88acf-9e73-4668-9480-72f42f2418d6/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/640ab87e-77e2-40d4-97dc-7102ef243abc/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/0e05ffbb-03a1-4d66-8cec-360b895fcbbd/image.png" alt=""></p>
<p>링크 : <a href="https://school.programmers.co.kr/learn/courses/30/lessons/12980">https://school.programmers.co.kr/learn/courses/30/lessons/12980</a></p>
<h2 id="설명">설명</h2>
<p>반복문을 돌면서 가야하는 숫자 % 2 == 0 이라면 /2를 해준다.
만약 나머지가 0이 안된다면 순간이동을 하지 못하는 상황이므로 한칸만 앞으로 가준다.</p>
<h2 id="코드">코드</h2>
<pre><code class="language-java">public class Solution {
    public int solution(int n) {
        int ans = 0;
        while (n &gt; 0) {
            if (n % 2 == 0) {
                n /= 2;
            } else {
                n -= 1;
                ans++;
            }
        }
        return ans;
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java] Lv.2 프로그래머스 짝지어 제거하기]]></title>
            <link>https://velog.io/@196code-gray/Java-Lv.2-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A7%9D%EC%A7%80%EC%96%B4-%EC%A0%9C%EA%B1%B0%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@196code-gray/Java-Lv.2-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A7%9D%EC%A7%80%EC%96%B4-%EC%A0%9C%EA%B1%B0%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sat, 14 Oct 2023 02:33:58 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/196code-gray/post/189c69c8-bd1e-4386-8cb9-cbcf01b6775e/image.png" alt=""></p>
<p>링크 : <a href="https://school.programmers.co.kr/learn/courses/30/lessons/12973">https://school.programmers.co.kr/learn/courses/30/lessons/12973</a></p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/207569a2-fdff-4a67-b586-3a7629d23850/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/a895b248-73ab-42de-80c1-a90e49d50874/image.png" alt=""></p>
<h2 id="설명">설명</h2>
<p>처음에 문자열 문제라서 substring으로 풀었다가 뭔가 이상해서 다시보니 저번 괄호문제랑 비슷한 문제였다. </p>
<p>스택으로 풀었고, 문제는 간단하다.
현재 스택 맨 위에 있는 문자열과 지금 문자열이 같은 문자열이라면 스택에서 제거해주고 아니라면 넣어주면 된다.</p>
<h2 id="코드">코드</h2>
<pre><code class="language-java">import java.util.*;
class Solution
{
    public int solution(String s) {
        Stack&lt;Character&gt; stack = new Stack&lt;&gt;();
        for (int i = 0; i &lt; s.length(); i++) {
            if (!stack.isEmpty() &amp;&amp; stack.peek().equals(s.charAt(i))) {
                stack.pop();
            } else stack.push(s.charAt(i));
        }

        return (stack.isEmpty()) ? 1 : 0;
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 메서드 Overriding (오버라이딩) / Overloading (오버로딩)]]></title>
            <link>https://velog.io/@196code-gray/JAVA-%EB%A9%94%EC%84%9C%EB%93%9C-Overriding-%EC%98%A4%EB%B2%84%EB%9D%BC%EC%9D%B4%EB%94%A9-Overloading-%EC%98%A4%EB%B2%84%EB%A1%9C%EB%94%A9</link>
            <guid>https://velog.io/@196code-gray/JAVA-%EB%A9%94%EC%84%9C%EB%93%9C-Overriding-%EC%98%A4%EB%B2%84%EB%9D%BC%EC%9D%B4%EB%94%A9-Overloading-%EC%98%A4%EB%B2%84%EB%A1%9C%EB%94%A9</guid>
            <pubDate>Thu, 12 Oct 2023 14:21:58 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/196code-gray/post/71153356-0552-4ba5-9cef-91c2bc179ab6/image.png" alt=""></p>
<h2 id="overriding-오버라이딩">Overriding (오버라이딩)</h2>
<p>상위 클래스에서 상속받은 메서드를 하위 클래스에서 재 정의 하는 것을 말한다. </p>
<h3 id="조건">조건</h3>
<p>오버라이딩은 부모 클래스의 메서드를 재 정의하는 것으로 자식 클래스에서는 <code>오버라이딩하고자 하는 메서드의 이름, 매개변수 타입, 매개변수 개수, 리턴 값 이 모두 같아야 한다.</code></p>
<p>예시</p>
<pre><code class="language-java">public class A {
    public String run() {
        System.out.println(&quot;뛴다&quot;);
     }
}

public class B extend A {
    @Override
    public String run() {
        System.out.println(&quot;숨이 차게 뛴다&quot;);
     }
}</code></pre>
<p>실제 코드로는 이런식으로 사용 가능하다.</p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/c177bcf7-c754-40da-8863-fcc943979927/image.png" alt=""></p>
<p>위 코드는 spring security로 보안을 설계할 때 사용하는 코드 중 일부이다.
CustomUsernamePasswordAuthenticationFilter 가 UsernamePasswordAuthenticationFilter 를 상속 받았다.</p>
<p>@Override 애너테이션을 붙여서 attemptAuthentication 메서드의 내부는 재정의하고 파라미터 타입, 개수, 리턴 값 모두 같은 것을 알 수 있다.</p>
<h2 id="overloading-오버로딩">Overloading (오버로딩)</h2>
<p>오버로딩은 이름이 같은 메서드를 변경하여 재정의하는 것을 말한다.</p>
<h3 id="조건-1">조건</h3>
<p>같은 클래스 내에 있어야하며 <code>이름</code> 이 같아야하고, 파라미터 타입, 파라미터 개수가 달라야한다.
하지만 <code>리턴 값</code> 만 다른 것은 허용되지 않는다.</p>
<p>예시</p>
<pre><code class="language-java">    class A {
        public void study() {
            System.out.println(&quot;공부를 합니다.&quot;);
        }
        int study(int num) {
            System.out.println(&quot;오늘 공부한 시간은?&quot;);
            return num;
        }
        boolean study(boolean status) {
            System.out.println(&quot;오늘 공부를 했나요?&quot;);
            return status;
        }
        void study(String name) {
            System.out.println(&quot;오늘 공부한 과목은? &quot; + name);
        }
    }</code></pre>
<h3 id="왜-사용할까">왜 사용할까?</h3>
<p>만약 오버로딩을 사용하지 않고 메서드를 작성한다면 같은 행동임에도 불구하고 여러가지 메서드를 정의해줘야 할 것이다.</p>
<pre><code class="language-java">class A {
    public void study() {
        System.out.println(&quot;공부를 합니다.&quot;);
    }
    public int studyTime(int num) {
        System.out.println(&quot;오늘 공부한 시간은?&quot;);
    }
    public boolean studyYN(boolean status) {
        System.out.println(&quot;오늘 공부를 했나요?&quot;);
    }</code></pre>
<p>이런식으로 말이다.</p>
<p>위 코드처럼 복잡하게 메서드를 정의하는 것 보다 오버로딩을 사용함으로써 코드가 깔끔해지는 효과가 있기 때문에 오버로딩을 사용한다.</p>
<hr>
<p>참고 : <a href="https://hyoje420.tistory.com/14">https://hyoje420.tistory.com/14</a>
공식문서 : <a href="https://docs.oracle.com/javase/8/docs/api/">https://docs.oracle.com/javase/8/docs/api/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java] Lv.1 프로그래머스 예산]]></title>
            <link>https://velog.io/@196code-gray/Java-Lv.1-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%98%88%EC%82%B0</link>
            <guid>https://velog.io/@196code-gray/Java-Lv.1-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%98%88%EC%82%B0</guid>
            <pubDate>Fri, 06 Oct 2023 02:07:21 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/196code-gray/post/064a535b-a95e-4cd7-a100-0b7f6a3b6311/image.png" alt=""></p>
<p>링크 : <a href="https://school.programmers.co.kr/learn/courses/30/lessons/12982">https://school.programmers.co.kr/learn/courses/30/lessons/12982</a></p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/ff869027-3370-4260-be42-db415aa9bb0b/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/4142bc0a-e94f-4463-984e-e926c9dab6c1/image.png" alt=""></p>
<h2 id="설명">설명</h2>
<p>문제 설명에 <code>최대한 많은 부서의 물품</code>을 구매해 줄 수 있도록 하려고 합니다. 라고 되어있다.</p>
<p>그럼 숫자가 작은 순으로 먼저 계산하면 지정된 예산 안에서 최대한 많이 구매가 가능할 것이라고 생각했다.</p>
<p>먼저 오름차순으로 정렬한 뒤, 반복문으로 배열을 순회한다.
그리고 예산을 넘지않는지 확인하며 count 증가.</p>
<h2 id="코드">코드</h2>
<pre><code class="language-java">import java.util.*;
class Solution {
    public int solution(int[] d, int budget) {
        int answer = 0;
        Arrays.sort(d);
        int count = 0;
        for (int i = 0; i &lt; d.length; i++) {
            if (d[i] + count &lt;= budget) {
                count += d[i];
                answer++;
            }
        }
        return answer;
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java] Lv.2 프로그래머스 숫자의 표현]]></title>
            <link>https://velog.io/@196code-gray/Java-Lv.2-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%88%AB%EC%9E%90%EC%9D%98-%ED%91%9C%ED%98%84</link>
            <guid>https://velog.io/@196code-gray/Java-Lv.2-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%88%AB%EC%9E%90%EC%9D%98-%ED%91%9C%ED%98%84</guid>
            <pubDate>Fri, 06 Oct 2023 01:31:20 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/196code-gray/post/52834076-9d79-4347-8642-1712e2846f63/image.png" alt=""></p>
<p>링크 : <a href="https://school.programmers.co.kr/learn/courses/30/lessons/12924">https://school.programmers.co.kr/learn/courses/30/lessons/12924</a></p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/280d9919-91f9-417c-af2d-ecb710f2bd2a/image.png" alt=""></p>
<h2 id="설명">설명</h2>
<p>이중반복문을 사용해서 1부터 n까지 n에 해당하는 수가 있는지 확인하고, 2부터 n까지 또 확인하는 식으로 풀었다.</p>
<p>하지만 문제를 풀면서도 매우 비효율적이라고 생각했기에 풀고 다른 사람 코드를 봤더니 약수를 통해 문제를 푸는 방법이 있었다.</p>
<p>해당 코드도 첨부하겠다.</p>
<h2 id="코드">코드</h2>
<pre><code class="language-java">class Solution {
    public int solution(int n) {
        int answer = 1;
        int count = 0;
        for (int i = 1; i &lt; n; i++) {
            for (int j = i; j &lt; n; j++) {
                if (count == n) {
                    answer++;
                    count = 0;
                    break;
                } else if (count &gt; n) {
                    count = 0; break;
                }
                else count += j;
            }
        }
        return answer;
    }
}</code></pre>
<h2 id="약수를-통해-방식">약수를 통해 방식</h2>
<pre><code class="language-java">class Solution {
    public int solution(int n) {
    int answer = 0;
    for (int i = 1; i &lt;= n; i += 2) 
       if (n % i == 0) 
           answer++;

   return answer;
    }
}</code></pre>
<p>홀수만 골라서 해당 수와 홀수를 나눈 나머지가 0 이라면. 약수라면 정답 개수를 올려준다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java] Lv.2 프로그래머스 JadenCase 문자열 만들기]]></title>
            <link>https://velog.io/@196code-gray/Java-Lv.2-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-JadenCase-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@196code-gray/Java-Lv.2-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-JadenCase-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Wed, 04 Oct 2023 03:11:50 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/196code-gray/post/91dfb953-1475-4510-9335-6f9981ada4db/image.png" alt=""></p>
<p>문제링크 : <a href="https://school.programmers.co.kr/learn/courses/30/lessons/12951">https://school.programmers.co.kr/learn/courses/30/lessons/12951</a></p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/47253cd3-521a-48ef-8e11-b5d80408aff7/image.png" alt=""></p>
<h2 id="설명">설명</h2>
<p>처음 문제를 봤을 때 그냥 split으로 공백 구분해서 자르고 substring 으로 맨 앞 글자는 대문자, 나머지는 소문자로 하면 되는 문제 아닌가? 라고 생각을 했는데 공백에서 은근 시간이 걸렸다.</p>
<p>리턴을 하려면 주어진 문자와 똑같은 상태로 리턴해야하는데 공백을 다 잘라버려서 어떻게 구분해야할지 고민했다.</p>
<p>생각해보니 주어진 문자는 손을 대지 않았으니 문자를 잘라 비교해보면 되는 문제였다.</p>
<h2 id="코드">코드</h2>
<pre><code class="language-java">class Solution {
    public String solution(String s) {
        String answer = &quot;&quot;;
        String[] str = s.split(&quot; &quot;);
        for (int i = 0; i &lt; str.length; i++) {
            String ss = str[i];
            if (str[i].length() == 0) { // 공백이라면 공백값 리턴
                answer += &quot; &quot;;
            } else {
                String first = str[i].substring(0, 1).toUpperCase();
                String a = str[i].substring(1, str[i].length()).toLowerCase();
                answer += first + a + &quot; &quot;;
            }
        }
        if (s.substring(s.length() -1, s.length()).equals(&quot; &quot;)) return answer;
        return answer.substring(0, answer.length() -1);
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract java.util.List ]]></title>
            <link>https://velog.io/@196code-gray/org.springframework.data.repository.query.QueryCreationException-Could-not-create-query-for-public-abstract-java.util.List</link>
            <guid>https://velog.io/@196code-gray/org.springframework.data.repository.query.QueryCreationException-Could-not-create-query-for-public-abstract-java.util.List</guid>
            <pubDate>Sat, 30 Sep 2023 07:44:09 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/196code-gray/post/181235a0-49ca-43a5-9a2d-c250317d2f39/image.png" alt=""></p>
<p>쿼리를 짜보았는데 에러가 났다.</p>
<h2 id="해결">해결</h2>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/16f65d21-9cae-4963-8a80-4d5fc79a39d1/image.png" alt=""></p>
<p>뒤에 nativeQuery 를 붙여주면 된다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spring Framework 와 Spring Boot 의 차이 알고 계신가요?]]></title>
            <link>https://velog.io/@196code-gray/Spring-Framework-%EC%99%80-Spring-Boot-%EC%9D%98-%EC%B0%A8%EC%9D%B4-%EC%95%8C%EA%B3%A0-%EA%B3%84%EC%8B%A0%EA%B0%80%EC%9A%94</link>
            <guid>https://velog.io/@196code-gray/Spring-Framework-%EC%99%80-Spring-Boot-%EC%9D%98-%EC%B0%A8%EC%9D%B4-%EC%95%8C%EA%B3%A0-%EA%B3%84%EC%8B%A0%EA%B0%80%EC%9A%94</guid>
            <pubDate>Fri, 29 Sep 2023 13:28:45 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/196code-gray/post/c5bb7d2b-6ed1-48e0-aaee-eb68f3013165/image.png" alt=""></p>
<p>알고 계시다면?? 축하드립니다!!</p>
<hr>
<p>두개의 차이가 무엇일까</p>
<h2 id="spring-framework">Spring Framework</h2>
<p>자바 기반의 오픈소스 프레임워크이다.</p>
<p>자체적으로 IoC, DI, AoP 를 제공해준다.</p>
<h3 id="ioc제어의-역전">IoC(제어의 역전)</h3>
<h3 id="di의존성-주입">DI(의존성 주입)</h3>
<p>객체간 결합이 느슨해지는 것을 의미한다.</p>
<h3 id="aop관점지향-프로그래밍">AoP(관점지향 프로그래밍)</h3>
<h2 id="spring-boot">Spring boot</h2>
<p>Spring Framework 를 기반으로 한 <code>도구</code> 이다.
개발에만 집중할 수 있도록 도와주는 <code>봄 보다 더 따스한 봄</code> 느낌이라고 볼 수 있다.</p>
<h2 id="차이점">차이점</h2>
<h3 id="dependency">Dependency</h3>
<p>프레임워크의 경우 
XML 기반의 설정 파일을 사용하며 매우 길고 복잡하다.
아래 코드는 web에 대한 기본 설정을 추가하는 코드다.</p>
<pre><code class="language-xml">&lt;dependencies&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-validation&lt;/artifactId&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.projectlombok&lt;/groupId&gt;
        &lt;artifactId&gt;lombok&lt;/artifactId&gt;
        &lt;scope&gt;compile&lt;/scope&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;com.h2database&lt;/groupId&gt;
        &lt;artifactId&gt;h2&lt;/artifactId&gt;
        &lt;scope&gt;runtime&lt;/scope&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-devtools&lt;/artifactId&gt;
        &lt;scope&gt;provided&lt;/scope&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.projectlombok&lt;/groupId&gt;
        &lt;artifactId&gt;lombok&lt;/artifactId&gt;
        &lt;scope&gt;provided&lt;/scope&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
        &lt;scope&gt;test&lt;/scope&gt;
    &lt;/dependency&gt;
&lt;/dependencies&gt;
</code></pre>
<p>부트의 경우 프레임워크 코드에서 절반 이상이 줄어들고 간단해진 것을 알 수 있다.</p>
<pre><code class="language-java">dependencies {
    implementation &#39;org.springframework.boot:spring-boot-starter-web&#39;
    implementation &#39;org.springframework.boot:spring-boot-starter-data-jpa&#39;
    implementation &quot;org.springframework.boot:spring-boot-starter-validation&quot;
    compileOnly &#39;org.projectlombok:lombok&#39;
    runtimeOnly &#39;com.h2database:h2&#39;
    developmentOnly &#39;org.springframework.boot:spring-boot-devtools&#39;
    annotationProcessor &#39;org.projectlombok:lombok&#39;
    testImplementation &#39;org.springframework.boot:spring-boot-starter-test&#39;
}</code></pre>
<h3 id="configuration">Configuration</h3>
<p>프레임워크의 환경 설정</p>
<p>부트의 환경 설정</p>
<h3 id="편리한-빌드">편리한 빌드</h3>
<h3 id="편리한-배포">편리한 배포</h3>
<hr>
<p>공식 문서 
<a href="https://spring.io/projects/spring-boot">https://spring.io/projects/spring-boot</a>
<a href="https://spring.io/projects/spring-framework">https://spring.io/projects/spring-framework</a></p>
<p>참고 블로그 : <a href="https://programforlife.tistory.com/68#google_vignette">https://programforlife.tistory.com/68#google_vignette</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java] 백준 30034 Slice String]]></title>
            <link>https://velog.io/@196code-gray/Java-%EB%B0%B1%EC%A4%80-30034-Slice-String</link>
            <guid>https://velog.io/@196code-gray/Java-%EB%B0%B1%EC%A4%80-30034-Slice-String</guid>
            <pubDate>Wed, 20 Sep 2023 06:16:53 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/196code-gray/post/aaa146e5-9d5b-4e40-89fe-d2b1c778e06c/image.png" alt=""></p>
<p>문제 링크 : <a href="https://www.acmicpc.net/problem/30034">https://www.acmicpc.net/problem/30034</a></p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/e115103d-5644-490d-81fa-3d9b58f907de/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/d011d324-422e-49eb-b4b5-cf1f7b44a3b9/image.png" alt=""></p>
<h2 id="설명">설명</h2>
<p>문제만 봤을 때는 그렇게 어려워보이는 문제가 아니였다.</p>
<p>단순히 기존 문자열에서 구분자와 병합자를 골라 구분자라면 구분지어주고, 병합자라면 그대로 두면 되는 문제였는데 생각보다 구현하는 부분에서 어려웠다.</p>
<p>나는 Set 으로 문제를 풀었다.</p>
<p>맨 처음 문자 구분자를 set에 넣어주고 숫자 구분자 역시 set에 넣어준다. 
병합자는 ch 라는 변수에 저장해준다.
그리고 set에 있는 구분자 중 병합자에 해당하는게 있다면 삭제시켜준다.
최종적으로 기존 문자열에서 구분자에 해당하는게 있다면 제외하고 구분자가 아닌 문자만 sb 라는 변수에 추가해준다.</p>
<p>그리고 구분자에 해당하는 부분에서 한 줄 내림은 한번만 진행이 되어야한다.
예로들어 </p>
<pre><code>문자 구분자 : b c d
숫자 구분자 : 1
병합자 : e
기존 문자열 : abcde1

입력이 주어질 경우 
출력형식
a
e</code></pre><p>되어야 한다는 의미이다.</p>
<h2 id="코드">코드</h2>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        int n = Integer.parseInt(br.readLine());

        HashSet&lt;Character&gt; set = new HashSet&lt;&gt;();
        StringTokenizer st = new StringTokenizer(br.readLine());    
        while(n --&gt; 0) {     // n이 0이 될 때까지 반복
            set.add(st.nextToken().charAt(0));        // 문자 구분자 저장
        }

        int m = Integer.parseInt(br.readLine());

        st = new StringTokenizer(br.readLine());
        while (m --&gt; 0) {
            set.add(st.nextToken().charAt(0));        // 숫자 구분자 저장
        }
        int k = Integer.parseInt(br.readLine());

        st = new StringTokenizer(br.readLine());
        while (k --&gt; 0) {
            char ch = st.nextToken().charAt(0);        // 병합자 저장

            if (set.contains(ch)) {        // set(구분자) 중 병합자와 같은게 있다면 제거
                set.remove(ch);
            }
        }
        br.readLine();

        boolean flag = false;    
        StringBuilder sb = new StringBuilder();
        for (char c : br.readLine().toCharArray()) {    // 기존 문자열 반복
            if (set.contains(c) || c == &#39; &#39;) {        // 구분자이거나 공백이라면
                if (flag) {        // flag 가 true 인 경우만
                    sb.append(&quot;\n&quot;);    // 한 줄 내림 진행.
                    flag = false;
                }
                continue;
            }
            sb.append(c);
            flag = true;
        }
        System.out.println(sb);
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java] Lv.2 프로그래머스 게임 맵 최단거리]]></title>
            <link>https://velog.io/@196code-gray/Java-Lv.2-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EA%B2%8C%EC%9E%84-%EB%A7%B5-%EC%B5%9C%EB%8B%A8%EA%B1%B0%EB%A6%AC</link>
            <guid>https://velog.io/@196code-gray/Java-Lv.2-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EA%B2%8C%EC%9E%84-%EB%A7%B5-%EC%B5%9C%EB%8B%A8%EA%B1%B0%EB%A6%AC</guid>
            <pubDate>Sat, 16 Sep 2023 02:43:24 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/196code-gray/post/6d384c64-a4b5-4a89-833a-48f5027b9e4c/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/48fa5a06-816d-452f-9843-8ebd87fb292d/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/dcd30daa-4107-4f4b-8d6d-7b6f2fb51c53/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/1649412a-e6a0-4ac5-801c-62b5a82e34cf/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/76b77132-1fd7-49f2-b4fb-3202a955eac2/image.png" alt=""></p>
<h2 id="설명">설명</h2>
<p>전형적인 BFS 문제이다.
잠깐 BFS 말고 다른 알고리즘 공부하니 BFS 가 기억이 잘 안나서 찾아봤다...ㅠㅠ</p>
<p>게임 캐릭터가 상대팀 진영에 <code>최대한 빨리 도착하는 것이 유리</code> 이것을 보고 BFS 로 풀어야겠다고 생각했다.</p>
<h2 id="코드">코드</h2>
<pre><code class="language-java">import java.util.*;
class Solution {
    static int[][] visited;        // 칸 수 저장 배열
    static int[] x = {0, -1, 0, 1};        // 좌, 우
    static int[] y = {1, 0, -1, 0};        // 상, 하
    public int solution(int[][] maps) {
        int answer = 0;
        visited = new int[maps.length][maps[0].length];

        BFS(0, 0, maps);    // 0,0부터 시작.
        answer = visited[maps.length -1][maps[0].length -1];    // visited의 마지막 값을 answer에 담는다.

        if (answer == 0) answer = -1;    // visited 에 값이 없었다면 갈 수 없는 게임

        return answer;
    }
    public static void BFS(int i, int j, int[][] maps) {
        Queue&lt;int[]&gt; q = new LinkedList&lt;&gt;();    // 큐를 배열 타입으로 선언
        visited[i][j] = 1;        // 1부터 시작
        q.add(new int[]{i, j});

        while (!q.isEmpty()) {        // 큐에 값이 없을때까지
            int[] now = q.remove();
            int dx = now[0];
            int dy = now[1];

            for (int a = 0; a &lt; 4; a++) {
                int nowx = dx + x[a];
                int nowy = dy + y[a];
                if (nowx &lt; 0 || nowx &gt; maps.length -1 || nowy &lt; 0 || nowy &gt; maps[0].length -1) continue;
                // 좌표 값이 0보다 작거나 maps 의 크기 보다 큰지 확인
                if (visited[nowx][nowy] == 0 &amp;&amp; maps[nowx][nowy] == 1) {    
                // 방문하지 않은 배열이면서 갈 수 있는 길일 때
                    visited[nowx][nowy] = visited[dx][dy] + 1;
                    q.add(new int[]{nowx, nowy});
                }
            }
        }
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java] Lv.2 프로그래머스 주식가격]]></title>
            <link>https://velog.io/@196code-gray/Java-Lv.2-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A3%BC%EC%8B%9D%EA%B0%80%EA%B2%A9</link>
            <guid>https://velog.io/@196code-gray/Java-Lv.2-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A3%BC%EC%8B%9D%EA%B0%80%EA%B2%A9</guid>
            <pubDate>Wed, 13 Sep 2023 02:59:47 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/196code-gray/post/5833c238-12ab-4ad2-ac27-7a7798648cdb/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/474489b4-0928-447c-9ff7-b1edb1c303ec/image.png" alt=""></p>
<p>문제 링크 : <a href="https://school.programmers.co.kr/learn/courses/30/lessons/42584">https://school.programmers.co.kr/learn/courses/30/lessons/42584</a></p>
<h2 id="설명">설명</h2>
<p>문제 설명이 매우 부실했던 문제라고 생각한다.</p>
<p>문제 설명을 보고 문제를 풀었음에도 불구하고 테스트케이스 빼고 죄다 틀려서 뭐가 문제인지 보고 또 봤다.</p>
<p>결론은 문제 설명이 상세하지 않아서 문제를 이해하지 못한 상태로 문제를 풀어서 일어난 일이다.</p>
<p>질문하기를 보니 나만 이해를 못한게 아닌 것 같았다...
지문이 리뉴얼 되었다는데 원래는 어땠던건지...</p>
<p>이 문제는 <code>해당 주가의 초로부터 n초 사이에 가격이 떨어지지 않은지</code> 를 보면 되는 문제이다.</p>
<p>1시간 넘게 걸린 문제인데... 밑에 어떤분이 올리신 설명 글을 보고 5분만에 풀었다..</p>
<p>참고 : <a href="https://school.programmers.co.kr/questions/20326?question=20326">https://school.programmers.co.kr/questions/20326?question=20326</a></p>
<p>근데 1시간 넘게 붙잡고 있었던건 너무 비효율 적...</p>
<h2 id="코드">코드</h2>
<pre><code class="language-java">import java.util.*;
class Solution {
        public int[] solution(int[] prices) {
              int[] answer = new int[prices.length];
        Stack&lt;Integer&gt; stack = new Stack&lt;&gt;();

        for (int i = 0; i &lt; prices.length; i++) {
            while (!stack.isEmpty() &amp;&amp; prices[i] &lt; prices[stack.peek()]) {
                answer[stack.peek()] = i - stack.peek();
                stack.pop();
            }
            stack.push(i);    // 스택에 인덱스를 저장.
        }

        while (!stack.isEmpty()) {
            answer[stack.peek()] = prices.length -1 - stack.peek();
            stack.pop();
        }

        return answer;
    }
}</code></pre>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/23eb318e-8271-4f0e-824d-60c8125b312b/image.png" alt=""></p>
<p>성공..!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[A problem occurred configuring root project 'preonboarding'.
> Could not resolve all files for configuration ':classpath'.
   > Could not resolve org.springframework.boot:spring-boot-gradle-plugin:3.1.2.]]></title>
            <link>https://velog.io/@196code-gray/A-problem-occurred-configuring-root-project-preonboarding.-Could-not-resolve-all-files-for-configuration-classpath.-Could-not-resolve-org.springframework.bootspring-boot-gradle-plugin3.1.2</link>
            <guid>https://velog.io/@196code-gray/A-problem-occurred-configuring-root-project-preonboarding.-Could-not-resolve-all-files-for-configuration-classpath.-Could-not-resolve-org.springframework.bootspring-boot-gradle-plugin3.1.2</guid>
            <pubDate>Tue, 05 Sep 2023 01:20:08 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/196code-gray/post/57a77ee7-fff9-44eb-8362-0b6c3a8f999e/image.png" alt=""></p>
<p>원티드 프리온보딩 과제를 clone 하던중 발생된 에러.</p>
<h2 id="원인">원인</h2>
<p>나는 자바 11버전을 쓰고 있었는데 원티드 과제는 자바 17버전이고 spring boot 3.1.2 버전은 자바 17부터 사용할 수 있다.</p>
<h2 id="첫번째-시도">첫번째 시도</h2>
<p>그래서 자바 17을 다운받아서 cmd 로 변경도 해줬다.</p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/3adb68a2-87c3-462b-80d6-bf4b8a94da9e/image.png" alt=""></p>
<p>그런데도 해결이 안됨...</p>
<h2 id="두번째-시도">두번째 시도</h2>
<p>인텔리자체의 설정을 보자.</p>
<p>단축키 <code>ctrl + alt + s</code> </p>
<p>gradle 설정에서 JVM 선택칸을 17로 변경해준다.</p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/f20cf132-1cd1-4182-9145-8def4c8278d4/image.png" alt=""></p>
<p>그리고 file -&gt; Project Structure... 에 들어간다.</p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/9cdb9673-02cb-4993-8d04-aff43f3fd2b5/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/10dae234-e2a7-4f7a-b3e8-d9e4c73acf1f/image.png" alt=""></p>
<p>SDK 를 17로 변경해준다.</p>
<p>build 를 다시 실행시키면 해결!</p>
<h3 id="해결">해결</h3>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/6ad97c4c-801c-4fac-9373-c5f918fe37ea/image.png" alt=""></p>
<p>참고한 블로그 : <a href="https://jojoldu.tistory.com/698">https://jojoldu.tistory.com/698</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java] Lv.2 프로그래머스 전화번호 목록]]></title>
            <link>https://velog.io/@196code-gray/Java-Lv.2-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A0%84%ED%99%94%EB%B2%88%ED%98%B8-%EB%AA%A9%EB%A1%9D</link>
            <guid>https://velog.io/@196code-gray/Java-Lv.2-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A0%84%ED%99%94%EB%B2%88%ED%98%B8-%EB%AA%A9%EB%A1%9D</guid>
            <pubDate>Thu, 31 Aug 2023 05:22:44 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/196code-gray/post/02ae2a1f-0509-41e2-80d3-f212f125ba37/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/3eb72ceb-8255-49fd-9ab6-4b5afc2da3ff/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/81234aa4-dfec-4ff1-a847-7c99147880f7/image.png" alt=""></p>
<h2 id="설명">설명</h2>
<p>분류가 해시로 되어있다.
그래서 Map 을 이용해서 풀었다.</p>
<p>접두어 란 문장의 시작부분에 겹치는 문자가 들어있는지 를 의미한다.</p>
<p>예제에서는 &quot;119&quot; 라는 문자열이 지영석의 전화번호 앞 글자에 있으므로 접두사가 있는 것이다.</p>
<p>그래서 처음 코드를 생각할 때는 맨 앞에 접두어가 있으니 맨 앞에 문자열을 기준으로 찾으면 되겠다 생각했는데 예제에는 없지만 접두어가 맨 뒤에 있는 경우도 있다.</p>
<p>그래서 모든 문자열을 Map 에 저장한 다음 문자열을 한글자 씩 잘라 map 에서 해당 문자열이 있는지를 탐색했다. 다만 그렇게 탐색할 경우 접두어도 같이 인식이 되므로 문자열의 마지막 글자를 빼고 key 값을 비교해야한다.</p>
<p>이 문제는 있으면 false 를 리턴하고 없으면 true 를 리턴한다.</p>
<h2 id="코드">코드</h2>
<pre><code class="language-java">import java.util.*;
class Solution {
    public boolean solution(String[] phone_book) {
        boolean answer = true;
        Map&lt;String, Boolean&gt; map = new HashMap&lt;&gt;();

        for (int i = 0; i &lt; phone_book.length; i++) {        // map 에 문자열 저장
            map.put(phone_book[i], true);
        }

        for (int i = 0; i &lt; phone_book.length; i++) {        
            String s = &quot;&quot;;        
            for (int j = 0; j &lt; phone_book[i].length() -1; j++) {
                String str = String.valueOf(phone_book[i].charAt(j));
                s += str;
                if (map.containsKey(s)) {        // map 에서 해당하는 키가 있는지 탐색
                    answer = false;
                }
            }
        }

        return answer;
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java] Lv.3 프로그래머스 입국 심사]]></title>
            <link>https://velog.io/@196code-gray/Java-Lv.3-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%9E%85%EA%B5%AD-%EC%8B%AC%EC%82%AC</link>
            <guid>https://velog.io/@196code-gray/Java-Lv.3-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%9E%85%EA%B5%AD-%EC%8B%AC%EC%82%AC</guid>
            <pubDate>Thu, 31 Aug 2023 05:08:41 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/196code-gray/post/84aeae35-1244-4f33-876e-23aff5140004/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/edede5fe-9c27-4178-85d4-d35cdbc1dec1/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/974dea86-482e-483e-b2b0-45d28b95d517/image.png" alt=""></p>
<h2 id="설명">설명</h2>
<p>일단 제한사항을 보면 최악이 10억이다. 완전탐색은 안된다.
10억이면 O(n) 도 안되기에...</p>
<p>O(log n) 으로 가야한다.</p>
<p>이 문제는 이진 탐색으로 풀 수 있는 문제인데 어디를 기준으로 잡아할지 파악 하는게 핵심인 것 같다.</p>
<p>일단 이진 탐색을 하려면 탐색할 기준이 있어야 하고, 기준을 중심으로 시작과 끝이 있어야 반으로 나누고 다시 탐색을 진행하는 방식인데...</p>
<p>핵심은 <code>K분 안에 모든 사람이 심사를 받을 수 있는가?</code> 이다. 
즉 <code>시간</code> 이 기준점이 된다.</p>
<p>예제로 설명을 하면 
n = 6 times[7, 10] 일 때</p>
<pre><code>s(시작) = 1         e(끝) = 60

시작이 1인 이유는 제일 작은 수가 1부터 시작하기 때문. 사람이 1명일 때 심사관도 무조건 1명
끝은 times 배열에서 제일 오래 걸리는 심사관(10) * 사람수(6)
최악일 경우 제일 오래 걸리는 심사관에게 모든 사람이 심사를 받을 수 있으므로.</code></pre><p>그림으로 표현하면 아래와 같다.</p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/78103cea-8eec-4681-beb9-98422a27cbc8/image.png" alt=""></p>
<h2 id="틀린-코드">틀린 코드</h2>
<pre><code class="language-java">class Solution {
    public long solution(int n, int[] times) {
        long answer = 0;
        long start = 1;
        long end = (times[times.length -1]) * (long) n;

        while (start &lt;= end) {
            long a = 0;
            long mid = (start + end) / 2;
            for (int i = 0; i &lt; times.length; i++) {
                a += mid / times[i];
            }
            if (a &gt; n) {
                end = mid -1;
            } else if (a &lt; n) {
                start = mid + 1;
            } else {
                answer = mid;
                start = mid + 1;
                end = mid - 1;
            }
        }
        return answer;
    }
}</code></pre>
<p>그래요 이 코드...
예시는 돌아갑니다..하지만 제출을 누르면?</p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/3d50fdfa-0766-4fdf-9d92-5ecd0def38a1/image.png" alt=""></p>
<p>네 왜인지 모르겠지만 예제빼고 다 틀려버리죠.</p>
<h2 id="코드">코드</h2>
<pre><code class="language-java">import java.util.*;
class Solution {
    public long solution(int n, int[] times) {
        long answer = 0;
        long start = 1;
        long end = times[times.length -1] * (long) n;

        while (start &lt;= end) {
            long a = 0;
            long mid = (start + end) / 2;
            for (int i = 0; i &lt; times.length; i++) {
                a += mid / times[i];
            }
            if (a &gt;= n) {
                end = mid -1;
                answer = mid;
            } else if (a &lt; n) {
                start = mid + 1;
            } 
        }
        return answer;
    }
}</code></pre>
<p>이 코드로 성공했다</p>
<p><img src="https://velog.velcdn.com/images/196code-gray/post/232d0e51-a9d0-41d7-bb06-a9c695bd2c0f/image.png" alt="">
오! 11점이라니!! 신기방기</p>
]]></description>
        </item>
    </channel>
</rss>