<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>oss_nue.log</title>
        <link>https://velog.io/</link>
        <description>~*</description>
        <lastBuildDate>Mon, 16 Dec 2024 09:29:06 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>oss_nue.log</title>
            <url>https://velog.velcdn.com/images/oss_nue/profile/5f67a346-51b1-4231-85b8-771090126459/image.PNG</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. oss_nue.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/oss_nue" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[프로그래머스 - 4]]></title>
            <link>https://velog.io/@oss_nue/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-4</link>
            <guid>https://velog.io/@oss_nue/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-4</guid>
            <pubDate>Mon, 16 Dec 2024 09:29:06 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/12901">문제 21 - 2016년</a>
후 나 날짜에 약한데 !
-&gt; 월 먼저 계산하고 뒤에 요일 계산하기</p>
<pre><code class="language-java">class Solution {
    public String solution(int a, int b) {

        String [] days = new String [] {&quot;SUN&quot;,&quot;MON&quot;,&quot;TUE&quot;,&quot;WED&quot;,&quot;THU&quot;,&quot;FRI&quot;,&quot;SAT&quot;};
        int [] month = new int[] {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

        int now = 0;

        for (int i = 0; i &lt; a; i++) {
            now += month[i];
        }

        now += b;

        return days[ (now + 4) % 7 ];
    }
}</code></pre>
<ul>
<li>계산 잘 안 될 때는 그냥 문제에서 주워진 조건 맞춰서 계산 ㄱㄱ</li>
</ul>
<hr>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/42576">문제 22 - 완주하지 못한 선수</a></p>
<ul>
<li>정렬을 통해 짝 맞추기</li>
</ul>
<pre><code class="language-java">class Solution {
    public String solution(String[] participant, String[] completion) {

        Arrays.sort(participant);
        Arrays.sort(completion);

        for(int i = 0; i &lt; completion.length; i++) {
            if (!participant[i].equals(completion[i])) return participant[i];
        }

        return participant[participant.length - 1];
    }
}</code></pre>
<hr>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/340213">문제 23 - 동영상 재생기</a></p>
<ul>
<li>13:00 이렇게 생긴 데이터를 초 단위 시간으로 바꿔야 함</li>
<li>또 그거를 13:00 이런 식으로 바꿔야 함</li>
<li>-&gt; 함수를 만들어 진행</li>
</ul>
<pre><code class="language-java">class Solution {
    public String solution(String video_len, String pos, String op_start, String op_end, String[] commands) {

        int nVideo_len = setSecondTime(video_len);
        int nPos = setSecondTime(pos);
        int nOp_start = setSecondTime(op_start);
        int nOp_end = setSecondTime(op_end);

        for (int i = 0; i &lt; commands.length; i++) {

            if (nPos &gt;= nOp_start &amp;&amp; nPos &lt;= nOp_end) nPos = nOp_end;

            switch (commands[i]) {
                case &quot;prev&quot; :
                    if (nPos &lt; 10) nPos = 0;
                    else nPos -= 10;
                    break;
                case &quot;next&quot; :
                    if (nPos &gt;= (nVideo_len - 10)) nPos = nVideo_len;
                    else nPos += 10;
                    break;
            }

            if (nPos &gt;= nOp_start &amp;&amp; nPos &lt;= nOp_end) nPos = nOp_end;

        }

        return setTime(nPos);
    }

    // 시간 -&gt; 초 단위
    public int setSecondTime(String time) {
        String [] pTime = time.split(&quot;:&quot;);
        return Integer.parseInt(pTime[0]) * 60 + Integer.parseInt(pTime[1]);
    }

    // 초 단위 -&gt; 시간 
    public String setTime(int time) {
        int minute = time / 60;
        int second = time % 60;
        return String.format(&quot;%02d:%02d&quot;, minute, second);
    }
}</code></pre>
<p>🔅 String.format() !</p>
<hr>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/340198">문제 23 - 공원</a></p>
<ul>
<li></li>
</ul>
<hr>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/92334">문제 24 - 신고 결과 받기</a></p>
<ul>
<li>Set으로 중복제거인 거 대박임</li>
<li>map.getOrDefalt(&quot;키의 값&quot;, &quot;없을경우 출력할 것&quot;);</li>
<li>map.entrySet() : map의 모든 키-값 쌍을 Set 형태로 반환</li>
</ul>
<pre><code class="language-java">import java.util.*;

class Solution {
    public int[] solution(String[] id_list, String[] report, int k) {

        // 1. Set으로 중복 제거
        Set&lt;String&gt; reported = new HashSet&lt;String&gt;(Arrays.asList(report));

        // 2. 신고당한 횟수 카운트 --&gt; map 사용
        Map&lt;String, Integer&gt; count = new HashMap&lt;String, Integer&gt;();

         for(String r : reported) {
            String reporter = r.split(&quot; &quot;)[1];
            count.put(reporter, count.getOrDefault(reporter, 0) + 1);
        }

        // 3. 정지 먹은 회원 판단
        Set&lt;String&gt; suspend = new HashSet();

        for(Map.Entry&lt;String, Integer&gt; map : count.entrySet()) {
            if(map.getValue() &gt;= k) {
                suspend.add(map.getKey());
            }
        }

        // 4. 메일 보내기
        Map&lt;String , Integer&gt; mail = new HashMap&lt;String, Integer&gt;();

        for(String id : id_list) {
            mail.put(id, 0);
        }

        for(String r : reported) {
            String sender = r.split(&quot; &quot;)[0];
            String reporter = r.split(&quot; &quot;)[1];

            if(suspend.contains(reporter)) {
                mail.put(sender, mail.get(sender) + 1);
            }
        }


        // 5. set을 배열로 바꿔주기
        int [] result = new int [id_list.length];

        for(int i = 0; i &lt; result.length; i++) {
            result[i] = mail.get(id_list[i]);
        }

        return result;
    }
}</code></pre>
<p>어우 변수 너무 많아</p>
<hr>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/1845">문제 25 - 폰켓몬</a></p>
<pre><code class="language-java">import java.util.*;

class Solution {
    public int solution(int[] nums) {

        Set&lt;Integer&gt; unique = new HashSet&lt;&gt;();

        for (int i : nums) {
            unique.add(i);
        }

        int maxSize = nums.length / 2;

        return Math.min(unique.size(), maxSize);
    }
}</code></pre>
<hr>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/42748">문제 26 - k번째수</a></p>
<pre><code class="language-java">import java.util.*;

class Solution {
    public int[] solution(int[] array, int[][] commands) {

        int [] result = new int [commands.length];

        for(int i = 0; i &lt; commands.length; i++) {
            int start = commands[i][0];
            int end = commands[i][1];
            int k = commands[i][2];

            int [] sub = new int [end - start + 1 ];
            int num = 0;

            for(int j = start - 1; j &lt; end; j++) {
                sub[num] = array[j];
                num++;
            }

            Arrays.sort(sub);
            result[i] = sub[k - 1];
        }

        return result;
    }
}</code></pre>
<hr>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/12906">문제 27 - 같은 숫자는 싫어</a></p>
<ul>
<li>스택과 큐로 중복처리를 어케 할지 훔냐 --&gt; 그냥 if문 조건 걸어</li>
<li><blockquote>
<p>스택 젤 위에 있는 게 i랑 같은지 다른지</p>
</blockquote>
</li>
</ul>
<pre><code class="language-java">import java.util.*;

public class Solution {

    public int[] solution(int []arr) {

        Stack&lt;Integer&gt; stack = new Stack&lt;&gt;();

        for(int i : arr) {
            if(stack.isEmpty() || stack.peek() != i) stack.push(i);
        }

        int[] answer = new int[stack.size()];

        for(int i = stack.size() - 1 ; i &gt;= 0; i--) {
            answer[i] = stack.pop();
        }

        return answer;
    }
}</code></pre>
<p>레벨 1 끝 ~.. ㅜ</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 - 3]]></title>
            <link>https://velog.io/@oss_nue/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-3</link>
            <guid>https://velog.io/@oss_nue/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-3</guid>
            <pubDate>Thu, 12 Dec 2024 07:07:29 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/135808">문제 14 - 과일 장수</a></p>
<ol>
<li>내림차순 정렬하는 법</li>
</ol>
<p>--&gt; Arrays.sort(배열, Collections.reverseOrder())
--&gt; 대신 int 배열은 Integer로 바꿔주고 진행해야 함</p>
<pre><code class="language-java">        Integer[] arr = new Integer[score.length];

        for (int i = 0; i &lt; score.length; i++) {
            arr[i] = score[i];  // 각 요소를 복사
        }

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

        int sum = 0;

        for(int i = 1; i &lt;= (score.length / m); i++) {
            sum += arr[i * m - 1] * m;
        }</code></pre>
<hr>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/134240">문제 15 - 푸드 파이트 대회</a></p>
<ul>
<li>이 문제에서 가장 중요한 건 &#39;대칭&#39;</li>
<li><blockquote>
<ol>
<li>StringBuilder로 반만 일단 만들고 reverse() 함수 사용하기</li>
</ol>
</blockquote>
</li>
<li><blockquote>
<ol start="2">
<li>일단 반만 배열에 넣고 for문으로 붙히기</li>
</ol>
</blockquote>
</li>
</ul>
<pre><code class="language-java">class Solution {
    public String solution(int[] food) {

        StringBuilder half = new StringBuilder();

        for(int i = 1; i &lt; food.length; i++) {
            for(int j = 1; j &lt;= (food[i] / 2); j++) {
                half.append(i);
            }
        }

        return half.toString() + &quot;0&quot; + half.reverse();
    }
}</code></pre>
<hr>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/133502">문제 16 - 햄버거 만들기</a></p>
<ul>
<li>짝 맞춰진 거 찾기 </li>
<li><blockquote>
<p>리스트를 만들고 만들어지면 제거하는 방식으로 풀기</p>
</blockquote>
</li>
</ul>
<pre><code class="language-java">import java.util.*;

class Solution {
    public int solution(int[] ingredient) {

        ArrayList&lt;Integer&gt; list = new ArrayList&lt;Integer&gt;();

        for(int i : ingredient) {
            list.add(i);
        }

        int count = 0;
        for(int i = 0; i &lt;= list.size() - 4;) {
            if (list.get(i) == 1 &amp;&amp; list.get(i + 1) == 2 &amp;&amp; list.get(i + 2) == 3 &amp;&amp; list.get(i + 3) == 1) {
                list.remove(i);
                list.remove(i);
                list.remove(i);
                list.remove(i);
                count++;
                i = 0;
            } else {
                i++;
            }
        }

        return count;
    }
}</code></pre>
<p>이렇게 풀었는데 시간초과 5개나 떠서 스택으로 해보려고 합니다</p>
<pre><code class="language-java">import java.util.*;

class Solution {
    public int solution(int[] ingredient) {

        Stack&lt;Integer&gt; stack = new Stack&lt;Integer&gt;();

        int count = 0;
        for(int i : ingredient) {
            stack.push(i);

            if(stack.size() &gt;= 4) {
                int size = stack.size();
                if(stack.peek() == 1 &amp;&amp; stack.get(size - 2) == 3 &amp;&amp; stack.get(size - 3) == 2 &amp;&amp; stack.get(size - 4) == 1) {
                    count++;
                    stack.pop();
                    stack.pop();
                    stack.pop();
                    stack.pop();
                }
            }
        }
        return count;
    }
}</code></pre>
<p>처음엔 stack.get(size-1)이 peek() 밑인 줄 알았는데 인덱스가 0부터 시작한다는 걸 까먹음 바보바보 ..~~</p>
<hr>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/133499">문제 17 - 옹알이(2)</a></p>
<ul>
<li>같은 문자열이 있으면 count+1인 건 알겠는데 yee랑 ye 이걸 어케 구분하지? 싶음</li>
<li>-&gt; 공백으로 바꾸고 제거 </li>
</ul>
<pre><code class="language-java">class Solution {
    public int solution(String[] babbling) {

        String [] possible = new String[] {&quot;aya&quot;, &quot;ye&quot;, &quot;woo&quot;, &quot;ma&quot;};
        int count = 0;

        for(String s : babbling) {
            boolean isCorrect = true;

            for (int i = 0; i &lt; possible.length; i++) {
                if(s.contains(possible[i] + possible[i])) {
                    isCorrect = false;
                    break;
                }
            }

            if(isCorrect) {
                for(String p : possible) {
                    s = s.replace(p, &quot; &quot;);
                }

                if(s.trim().isEmpty()) count++;
            }
        }

        return count;
    }
}</code></pre>
<hr>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/132267">문제 18 - 콜라 문제</a></p>
<pre><code class="language-java">class Solution {
    public int solution(int a, int b, int n) {

        int total = 0;

        while(n &gt;= a) {
            int give = (n / a) * a;
            int receive = (give / a) * b;
            total += receive;
            n = n - give + receive;

        }

        return total;
    }
}</code></pre>
<p>걍 수학문제</p>
<hr>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/131705">문제 19 - 삼총사</a></p>
<ul>
<li><p>세 가지의 수의 합을 어떻게 반복하면서 판단하지? 제거하려니까 제거된 수에서도 답이 나올 수도 있어서 마음대로 제거 못함</p>
</li>
<li><blockquote>
<p>이건 해결</p>
</blockquote>
</li>
<li><p>어떻게 횟수를 셌던 숫자인 걸 구별하지?</p>
</li>
<li><blockquote>
<p>걍 이거 dfs로 푸는 거였삼...</p>
</blockquote>
</li>
</ul>
<hr>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/131128">문제 20 - 숫자 짝꿍</a></p>
<pre><code class="language-java">import java.util.*;

class Solution {
    public String solution(String X, String Y) {

        int [] countX = new int[10];
        int [] countY = new int[10];

        for (char c : X.toCharArray()) {
            countX[c - &#39;0&#39;]++;
        }

        for (char c : Y.toCharArray()) {
            countY[c - &#39;0&#39;]++;
        }

        StringBuffer result = new StringBuffer();

        for(int i = 9; i &gt;= 0; i--) {
            int num = Math.min(countX[i], countY[i]);

            for(int j = 0; j &lt; num; j++) {
                result.append(i);
            }
        }

        if (result.length() == 0) return &quot;-1&quot;;
        if (result.toString().equals(&quot;0&quot;.repeat(result.length()))) return &quot;0&quot;;

        return result.toString();
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 - 2]]></title>
            <link>https://velog.io/@oss_nue/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-2</link>
            <guid>https://velog.io/@oss_nue/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-2</guid>
            <pubDate>Sat, 07 Dec 2024 03:38:46 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/159994">문제 6 - 카드 뭉치</a></p>
<pre><code class="language-java">class Solution {
    public String solution(String[] cards1, String[] cards2, String[] goal) {

        int c1 = 0;
        int c2 = 0;

         for(int i = 0; i &lt; goal.length; i++) {
             if(c1 &lt; cards1.length &amp;&amp; cards1[c1].equals(goal[i])) {
                 c1++;
             } else if (c2 &lt; cards2.length &amp;&amp; cards2[c2].equals(goal[i])) {
                 c2++;
             } else {
                 return &quot;No&quot;;
             }
         }

        return &quot;Yes&quot;;

    }
}</code></pre>
<p>인덱스를 따로 둬서 순서대로 되어있는지 체크하면 끝</p>
<hr>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/155652">문제 7 - 둘만의 암호</a></p>
<ol>
<li>빠르게 조회하기 위해 list에 넣어 포함되어 있는지 안 되어있는지 확인</li>
<li>속도를 위해 StringBuilder 사용해서 append 실행<pre><code class="language-java">import java.util.*;
</code></pre>
</li>
</ol>
<p>class Solution {</p>
<pre><code>public String solution(String s, String skip, int index) {

    // 1. 쉬운 탐색을 위해 list로 변환
    List&lt;Character&gt; skipList = new ArrayList&lt;&gt;();

    for(int i = 0; i &lt; skip.length(); i++) {
        skipList.add(skip.charAt(i));
    }

     StringBuilder result = new StringBuilder();

    // 2. 순회하며 확인
    for(char c : s.toCharArray()) {
        char cCount = c;

        for(int i = 1; i &lt;= index; i++) {
            cCount++;

            if(cCount &gt; &#39;z&#39;) {
                cCount = &#39;a&#39;;
            }

            if(skipList.contains(cCount)) {
                i--; // cCount의 횟수만 증가시키고 반복은 한번 더 실행
            }
        }

        result.append(cCount);
    }

    return result.toString();
}</code></pre><p>}</p>
<pre><code>
---
[문제 8 - 크기가 작은 부분 문자열](https://school.programmers.co.kr/learn/courses/30/lessons/147355)

**🔎 접근법**
1. 문자열을 숫자로 바꿔야 함
2. 슬라이딩 사용

```java
class Solution {
    public int solution(String t, String p) {

        int start = 0;
        int end = p.length();
        int count = 0;

        while(start + p.length() &lt;= t.length()) {
            long num = Long.parseLong(t.substring(start,end));
            if (num &lt;= Long.parseLong(p)) count++;
            start++;
            end++;
        }

        return count;
    }
}</code></pre><p>long이랑 int 땜에 런타임 에러 발생할 수도 있구나</p>
<hr>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/142086">문제 9 - 가장 가까운 같은 글자</a></p>
<p><strong>🔎 접근법</strong></p>
<ol>
<li>map으로 인덱스 저장해서 갱신</li>
</ol>
<pre><code class="language-java">import java.util.*;

class Solution {
    public int[] solution(String s) {


        int[] result = new int[s.length()];
        Map&lt;Character, Integer&gt; map = new HashMap&lt;&gt;();

        for(int i = 0; i &lt; s.length(); i++) {
            char c = s.charAt(i);

            if(map.containsKey(c)) {
                result[i] = i - map.get(c);
            } else {
                result[i] = -1;
            }

            map.put(c, i);

        }


        return result;
    }
}</code></pre>
<hr>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/82612">문제 10 - 부족한 금액 계산</a>
Ezzzzzzzzzzz</p>
<pre><code class="language-java">class Solution {
    public long solution(int price, int money, int count) {

        long sum = 0;

        for(int i = 1; i &lt;= count; i++) {
            sum += price * i;
        }

        long answer = sum - money;
        return answer &gt;= 0 ? answer : 0;
    }
}</code></pre>
<hr>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/140108">문제 11 - 문자열 나누기</a></p>
<pre><code class="language-java">class Solution {
    public int solution(String s) {

        int sameCount = 0;
        int difCount = 0;
        int count = 0;
        int index = 0;

        for(int i = 0; i &lt; s.length(); i++) {

            if(s.charAt(index) == s.charAt(i)) sameCount++;   
            else difCount++;

            if (sameCount == difCount) {
                count++;
                index = i + 1;
                sameCount = 0;
                difCount = 0;
            }
        }

        if(sameCount &gt; 0 || difCount &gt; 0) {
            count++;
        }

        return count;
    }
}</code></pre>
<p>변수가 좀 많긴한데 먼가 뿌듯한 코드 ^ㅁ^</p>
<hr>
<p>[문제 12 - 명예의 전당 (1)] (<a href="https://school.programmers.co.kr/learn/courses/30/lessons/138477">https://school.programmers.co.kr/learn/courses/30/lessons/138477</a>)</p>
<p>우선순위 큐 쓰면 될 것 같습니더</p>
<pre><code class="language-java">import java.util.*;

class Solution {
    public int[] solution(int k, int[] score) {
        int[] answer = new int[score.length];

        PriorityQueue&lt;Integer&gt; que = new PriorityQueue&lt;&gt;((o1, o2) -&gt; {
            return o1 &gt; o2 ? 1 : -1;
        });

        for(int i = 0; i &lt; score.length; i++) {
            que.add(score[i]); 

            if(que.size() &gt; k) {
                que.poll();
            }

            answer[i] = que.peek();
        }


        return answer;
    }
}</code></pre>
<p>간단히 정리</p>
<ul>
<li><p>큐 추가 : que.add()</p>
</li>
<li><p>큐 삭제 : que.poll()</p>
</li>
<li><p>큐 사이즈 : que.size()</p>
</li>
<li><p>큐 맨 마지막에 있는 거 출력 : que.peek()</p>
<hr>
<p>[문제 13 - 기사단원의 무기] (<a href="https://school.programmers.co.kr/learn/courses/30/lessons/136798">https://school.programmers.co.kr/learn/courses/30/lessons/136798</a>)</p>
</li>
</ul>
<p>약수를 우째 구하지 --&gt; 제곱근 사용 !!! Math.sqrt() ==&gt; double형 리턴</p>
<pre><code class="language-java">class Solution {
    public int solution (int number, int limit, int power) {

        // 1 -&gt; 1* 1
        // 2 -&gt; 1 * 2 
        // 3 -&gt; 1 * 3
        // 4 -&gt; 1 * 4 | 2 * 2


        int sum = 0;
        for(int i = 1; i &lt;= number; i++) {

            int count = 0;

            for(int j = 1; j &lt;= (int)Math.sqrt(i); j++) {
                if(i % j == 0) count += 2;
                if(j * j == i) count -= 1;
            }

            sum += count &gt; limit ? power : count;
        }

        return sum;
    }
}</code></pre>
<p>&lt;중요&gt;
-&gt; 나머지가 0인 건 count + 2
-&gt; 자기 자신 곱한 건 -1</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 1일차]]></title>
            <link>https://velog.io/@oss_nue/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-1%EC%9D%BC%EC%B0%A8</link>
            <guid>https://velog.io/@oss_nue/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-1%EC%9D%BC%EC%B0%A8</guid>
            <pubDate>Wed, 04 Dec 2024 12:33:09 GMT</pubDate>
            <description><![CDATA[<p>목표 
✨ 프로그래머스 레벨2 혼자 풀기</p>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/178871?language=java">문제 1 - 달리기 경주</a></p>
<ul>
<li>일단 인덱스를 아는 게 중요할 것 같음 -&gt; 배열에서 할 수 없으니 map 사용</li>
<li>map.get()은 인덱스를 통해 값을 가져오는 것. 그러니 map을 저장할 때 &lt;인덱스, 값&gt; 형태로 저장</li>
</ul>
<pre><code class="language-java">import java.util.*;

class Solution {
    public String[] solution(String[] players, String[] callings) {

        Map&lt;String, Integer&gt; map = new HashMap&lt;&gt;();

         int index = 0;
         for(String p : players) map.put(p, index++);

         for(String c : callings) {
             int callingsIndex = map.get(c).intValue(); // get 함수는 값을 가져오는 것. 즉 인덱스 추출
             int targetIndex = callingsIndex - 1; // 자리가 바뀔 선수의 인덱스

             String targetPlayer = players[targetIndex]; // 원래 순위 사람 저장
             players[targetIndex] = c; // 앞에 순위로 바꿔줌
             players[callingsIndex] = targetPlayer; // 원래 순위 사람은 뒤로

             // map에 저장
             map.put(targetPlayer, callingsIndex);
             map.put(c, targetIndex);
             System.out.println(map);
         }

         return players;
    }
}</code></pre>
<hr>
<p>[문제 2 - 추억 점수] (<a href="https://school.programmers.co.kr/learn/courses/30/lessons/176963">https://school.programmers.co.kr/learn/courses/30/lessons/176963</a>)</p>
<ul>
<li>2차원 배열 안의 배열의 길이를 구하고 싶을 땐 배열이름[i].length 사용</li>
<li>map에 값이 없을 땐 null이 출력된다.</li>
</ul>
<pre><code class="language-java">import java.util.*;

class Solution {
    public int[] solution(String[] name, int[] yearning, String[][] photo) {

        int[] result = new int[photo.length];

        // map에 저장
        Map&lt;String, Integer&gt; map = new HashMap&lt;&gt;();

        for(int i = 0; i &lt; name.length; i++){
            map.put(name[i], yearning[i]);
        }

        // 계산        
        for(int i = 0; i &lt; photo.length; i++) {
            int sum = 0;
            for(int j = 0; j &lt; photo[i].length; j++) {
                if(map.get(photo[i][j]) != null) {
                     sum += map.get(photo[i][j]).intValue();
                 } else {
                     sum += 0;
                 }
            }

            result[i] = sum;
        }

        return result;
    }
}</code></pre>
<hr>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/172928">문제 3 - 공원 산책</a></p>
<p><strong>🔎 접근법</strong></p>
<ol>
<li>문제는 배열에 OOO 이렇게 담겨 있는 걸 어떻게 직사각형의 모양으로 생각하면서? 풀 수 있는가임 --&gt; 2차원 배열을 활용할까 싶음</li>
<li>명령어가 &quot;E 2&quot;이런 형식인데 이걸 분해해서 전달해야 할 것 같은데.. 움 -&gt; split() 사용하장</li>
<li>내가 간과한 것 -&gt; 시작 위치 설정 </li>
</ol>
<pre><code class="language-java">class Solution {
    static char [][] cPark;
    static int [] now; // 현재 위치

    public int[] solution(String[] park, String[] routes) {

        // 정원 만들기
        cPark = new char[park.length][park[0].length()]; 

        for(int i = 0; i &lt; park.length; i++) {
            for(int j = 0; j &lt; park[i].length(); j++) {
                cPark[i][j] = park[i].charAt(j);
            }
        }

        // 시작 위치 설정
        now = new int[2];

        for(int i = 0; i &lt; park.length; i++) {
            for(int j = 0; j &lt; park[i].length(); j++) {
                if(cPark[i][j] == &#39;S&#39;) {
                    now[0] = i;
                    now[1] = j;
                    break;
                }
            }
        }

        // 명령 처리
        for(int i = 0; i &lt; routes.length; i++) {
            boolean isCorrect = move(routes[i].split(&quot; &quot;)[0], Integer.parseInt(routes[i].split(&quot; &quot;)[1]));
        }

        return now;
    }


    public static boolean move(String direction, int distance) {

        int x = now[1]; // 현재 가로
        int y = now[0]; // 현재 세로

        // 이동 시키기
        for(int i = 0; i &lt; distance; i++) {

            switch (direction) {
            case &quot;N&quot;: y--; break;
            case &quot;S&quot;: y++; break;
            case &quot;W&quot;: x--; break;
            case &quot;E&quot;: x++; break;
            }


            // 범위 넘는지 확인
            if (y &lt; 0 || y &gt;= cPark.length || x &lt; 0 || x &gt;= cPark[0].length) {
                return false; // 공원을 벗어나면 이동하지 않음
            }

            // X면 실행하지 않기
            if(cPark[y][x] == &#39;X&#39;) {
                return false;
            }

        }

        now[0] = y;
        now[1] = x;

        return true;
    }

}</code></pre>
<p>가로 세로 헷갈려 죽는줄 ㅡㅡ ;;;</p>
<hr>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/161990">문제 4 - 바탕화면 정리</a></p>
<p><strong>🔎 접근법</strong></p>
<ol>
<li>#가 존재하는 최대 x, y와 최소 x, y를 구해야 함</li>
<li>최대는 +1 해줘야 함 !!</li>
</ol>
<pre><code class="language-java">    public int[] solution(String[] wallpaper) {

        char[][] arr = new char[wallpaper.length][wallpaper[0].length()];

        // char로 변환
        for(int i = 0; i &lt; wallpaper.length; i++) {
            for(int j = 0; j &lt; wallpaper[i].length(); j++) {
                arr[i][j] = wallpaper[i].charAt(j);
            }
        }

        // 계산
        // #가 존재하는 최대 x, y와 최소 x, y를 구해야 함

        int xMin = 50;                                 
        int xMax = 0;
        int yMin = 50;
        int yMax = 0;

        // j가 x 좌표 i가 y좌표
        for(int i = 0; i &lt; wallpaper.length; i++) {
            for(int j = 0; j &lt; wallpaper[i].length(); j++) {
                if(arr[i][j] == &#39;#&#39;) {
                    if(j &gt; xMax) xMax = j;
                    if(j &lt; xMin) xMin = j;

                    if(i &gt; yMax) yMax = i;
                    if(i &lt; yMin) yMin = i;
                }
            }
        }

        int [] drag = new int[] {yMin, xMin, yMax + 1, xMax + 1};

        return drag;
    }</code></pre>
<hr>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/161989">문제 5 - 덧칠하기</a></p>
<p>*<em>🔎 접근법 *</em></p>
<ul>
<li>일단 길이 구해서 페인트 길이랑 비교하는 건 알겟음 그 담은 어케 함유..? 부분배열..? 그 길이를 어케해여...?</li>
<li>-&gt; 칠한 길이를 저장할 변수 만들기</li>
</ul>
<pre><code class="language-java">class Solution {
    public int solution(int n, int m, int[] section) {

        int distance = 0;
        int count = 0;

        for(int i = 0; i &lt; section.length; i++) {
            if(distance &gt;= section[i]) continue;
            distance = section[i] + m - 1;
            count++;
        }

        return count;
    }
}</code></pre>
<p>원래는 칠한 여부를 표시하는 배열을 만들까 했는데 복잡해질 것 같아서 변경함</p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[[파트1] 코딩테스트 기초 (정렬 - 버블, 선택정렬, 삽입정렬)]]></title>
            <link>https://velog.io/@oss_nue/%ED%8C%8C%ED%8A%B81-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B8%B0%EC%B4%88-%EC%A0%95%EB%A0%AC-%EB%B2%84%EB%B8%94-%EC%84%A0%ED%83%9D%EC%A0%95%EB%A0%AC-%EC%82%BD%EC%9E%85%EC%A0%95%EB%A0%AC</link>
            <guid>https://velog.io/@oss_nue/%ED%8C%8C%ED%8A%B81-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B8%B0%EC%B4%88-%EC%A0%95%EB%A0%AC-%EB%B2%84%EB%B8%94-%EC%84%A0%ED%83%9D%EC%A0%95%EB%A0%AC-%EC%82%BD%EC%9E%85%EC%A0%95%EB%A0%AC</guid>
            <pubDate>Wed, 27 Nov 2024 08:06:11 GMT</pubDate>
            <description><![CDATA[<h3 id="📢-버블-정렬">📢 버블 정렬</h3>
<p>: 데이터의 <span style="background-color: #FAF4C0">인접 요소끼리</span> 비교하고, swap 연산을 수행하여 정렬</p>
<p><img src="https://velog.velcdn.com/images/oss_nue/post/b80c97b7-163f-4c32-9715-6280d32e192d/image.jpg" alt=""></p>
<hr>
<p>문제 1. <a href="https://www.acmicpc.net/problem/2750">백준 2750번 수 정렬하기1</a></p>
<p>** 🔎 접근법 **
두가지 방법을 이용해봤어욤</p>
<ol>
<li>sort() 해서 정렬하기</li>
<li>temp를 이용한 정렬</li>
</ol>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

public class bubbleArray1 {
    public static void main(String[] args) throws IOException {

        /* 백준 2750번 수 정렬하기1 */

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int count = Integer.parseInt(br.readLine());

        int[] nums = new int[count];

        for(int i = 0; i &lt; count; i++) {
            nums[i] = Integer.parseInt(br.readLine());

        }

        // 방법 1 sort() 사용
        /* Arrays.sort(nums); */

        // 방법 2 버블 정렬
        for(int i = 0; i &lt; count - 1; i++) {
            for(int j = 0; j &lt; count - 1; j++) {
                if(nums[j] &gt; nums[j+1]) {
                    int temp = nums[j];
                    nums[j] = nums[j+1];
                    nums[j+1] = temp;
                }
            }
        }


        for(int i = 0; i &lt; count; i++) {
            System.out.println(nums[i]);
        }

    }
}
</code></pre>
<p>문제2. <a href="https://www.acmicpc.net/problem/1377">백준 1377번 버블 소트</a></p>
<p>** 🔎 접근법 **</p>
<ol>
<li>swap이 언제 끝났는지 알기 위해선 원소의 최대 이동 횟수를 구해야 함</li>
<li>이동한 인덱스 차이를 구해야 함니도</li>
</ol>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

public class main {
    public static void main(String[] args) throws IOException {

        /* 백준 1377번 버블 소트 */

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int size = Integer.parseInt(br.readLine());

        mData[] a = new mData[size];

        for(int i = 0; i &lt; size; i++) {
            a[i] = new mData(Integer.parseInt(br.readLine()),i); 
        }

        Arrays.sort(a);

        int max = 0;
        for(int i = 0; i &lt; size; i++) {

            if(max &lt; a[i].index - i) { // a[i].index - i의 의미 = 원소가 이동한 인덱스 범위
                max = a[i].index - i;
            }
        }

        System.out.println(max + 1);
    }
}

class mData implements Comparable&lt;mData&gt; { // sort() 함수 실행하기 위한 정렬기준 정하기 위해 구현
    int value;
    int index;

    public mData(int value, int index) {
        this.value = value;
        this.index = index;
    }

    /* compareTo 메서드는 두 객체를 비교하여 정렬 순서를 정의 
     * 음수, 양수, 0으로 반환한다 즉, 첫번째 객체가 두번째 객체보다 작은지 큰지 비교 */

    @Override
    public int compareTo(mData o) {
        return this.value - o.value;
    }
}</code></pre>
<hr>
<h3 id="📢-선택-정렬">📢 선택 정렬</h3>
<p>: 대상 데이터에서 최대나 최소 데이터를 데이터가 <span style="background-color: #FAF4C0">나열된 순으로 찾아가며 선택</span>하는 방법</p>
<p><img src="https://velog.velcdn.com/images/oss_nue/post/77728167-f129-49cc-af58-c9b238a6c7fa/image.jpg" alt=""></p>
<hr>
<p>문제 1. <a href="https://www.acmicpc.net/problem/1427">백준 1427번 내림차순으로 자릿수 정렬하기</a></p>
<p>** 🔎 접근법 **</p>
<ul>
<li>값을 입력받을 때 공백 없이 받으니까 구분해 줘야 함 </li>
<li><blockquote>
<p>String으로 받은 뒤, substring 실행</p>
</blockquote>
</li>
</ul>
<pre><code class="language-java">import java.util.Arrays;
import java.util.Scanner;

public class main {
    public static void main(String[] args) {
        /* 백준 1427번 내림차순으로 자릿수 정렬하기 */

        // 1. 입력받아서 나누기
        Scanner scan = new Scanner(System.in);

        String str = scan.next();
        int [] nums = new int[str.length()];

        for(int i = 0; i &lt; nums.length; i++) {
            nums[i] = Integer.parseInt(str.substring(i, i + 1));
        }

        // 2. 정렬하기

        // [방법 1] sort() 사용
        /* Arrays.parallelSort(nums); */

        // [방법 2] 삽입정렬 사용
        for(int i = 0; i &lt; nums.length; i++) {
            int max = i;

            for(int j = i + 1; j &lt; nums.length; j++) {
                if(nums[j] &gt; nums[max]) {
                    max = j;
                }
            }

            if(nums[max] &gt; nums[i]) {
                int temp = nums[i];
                nums[i] = nums[max];
                nums[max] = temp;
            }
        }

        for(int i = 0; i &lt; nums.length; i++) {
            System.out.print(nums[i]);
        }
    }
}
</code></pre>
<hr>
<h3 id="📢-삽입-정렬">📢 삽입 정렬</h3>
<p>: 이미 정렬된 데이터 범위에 정렬되지 않은 데이터를 <span style="background-color: #FAF4C0">적절한 위치에 삽입</span>시켜 정렬하는 방식
: 평균 시간 복잡도는 O(N^2)로 느린편</p>
<hr>
<p>문제1. <a href="https://www.acmicpc.net/problem/11399">백준 11399번 ATM 인출 시간 계산하기</a></p>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {

        /* 백준 11399번 ATM 인출 시간 계산하기 */

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int size = Integer.parseInt(br.readLine()); // 크기
        int [] n = new int[size]; // 배열
        int [] s = new int[size]; // 합 배열

        StringTokenizer line = new StringTokenizer(br.readLine());
        for(int i = 0; i &lt; size; i++) {
            n[i] = Integer.parseInt(line.nextToken()); 
        }

        // 삽입 정렬
        for(int i = 1; i &lt; size; i++) {
            int insertPoint = i;
            int insertValue = n[i];

            for(int j = i-1; j &gt;= 0; j--) {
                if(n[j] &lt; n[i]) {
                    insertPoint = j + 1;
                    break;
                }

                if(j == 0) {
                    insertPoint = 0;
                }
            }

            // 오른쪽으로 밀기
            for(int j = i; j &gt; insertPoint; j--) {
                n[j] = n[j-1];
            }

            // 삽입
            n[insertPoint] = insertValue;
        }

        s[0] = n[0];

        // 합배열
        int sum = s[0];

        for(int i = 1; i &lt; size; i ++) {
            s[i] = s[i-1] + n[i];
            sum += s[i];
        }

        System.out.println(sum);


    }
}
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[파트1] 코딩테스트 기초 (스택과 큐)]]></title>
            <link>https://velog.io/@oss_nue/%ED%8C%8C%ED%8A%B81-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B8%B0%EC%B4%88-%EC%8A%A4%ED%83%9D%EA%B3%BC-%ED%81%90</link>
            <guid>https://velog.io/@oss_nue/%ED%8C%8C%ED%8A%B81-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B8%B0%EC%B4%88-%EC%8A%A4%ED%83%9D%EA%B3%BC-%ED%81%90</guid>
            <pubDate>Thu, 21 Nov 2024 05:21:17 GMT</pubDate>
            <description><![CDATA[<h3 id="📢-스택과-큐">📢 스택과 큐</h3>
<p><span style="color: red">01. 스택 </span>
: 삽입과 삭제 연산이 후입선출 LIFO 
: 삽입과 삭제가 <span style="background-color: #FAF4C0">한쪽에서만</span> 발생</p>
<ul>
<li>top : 삽입 삭제가 일어나는 위치</li>
<li>push : 새로운 데이터 삽입</li>
<li>pop : 데이터 삭제하고 확인</li>
<li>peek : top 위치에 있는 데이터 확인</li>
</ul>
<p><span style="color: red">2. 큐</span>
: 삽입과 삭제 연산이 선입선출 FIFO
: 삽입 삭제가 <span style="background-color: #FAF4C0">양방향에서</span> 발생</p>
<ul>
<li>rear : 큐에서 가장 끝 데이터를 가리키는 영역</li>
<li>front : 큐에서 가장 앞의 데이터를 가리키는 영역</li>
<li>add : rear 부분에 새로운 데이터 삽입</li>
<li>poll : front 부분에 데이터 삭제하고 확인</li>
<li>peek : front 부분에 있는 데이터 확인</li>
</ul>
<hr>
<p>문제1. [백준 1874번 스택으로 오름차순 수열 만들기] (<a href="https://www.acmicpc.net/problem/1874">https://www.acmicpc.net/problem/1874</a>)</p>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;

public class Main {
    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        int n = Integer.parseInt(br.readLine()); // 수열의 개수
        Stack&lt;Integer&gt; arr = new Stack&lt;Integer&gt;(); // 스택
        int num = 1; // 스택에 추가할 수
        boolean result = true; // 결과값
        StringBuffer bf = new StringBuffer(); // 콘솔창 입력

        for(int i = 0; i &lt; n; i++) {

            int target = Integer.parseInt(br.readLine()); // 입력받은 수

            if(target &gt;= num) {  // 예. target = 4 num = 1

                while (target &gt;= num) { 
                    arr.push(num++);
                    bf.append(&quot;+\n&quot;);
                }

                arr.pop(); // target = num일 때 실행
                bf.append(&quot;-\n&quot;);

            } else { // target = 3이고 num이 5

                int num2 = arr.pop();

                if(num2 &gt; target) {
                    System.out.println(&quot;NO&quot;);
                    result = false;
                    break;

                } else {
                    bf.append(&quot;-\n&quot;);
                }

            }
        }

        if(result) System.out.println(bf.toString());

    }
}
</code></pre>
<p>StringBuffer 사용하는 이유 결과를 나중에 한꺼번에 출력하려고 그럼</p>
<p>문제2. <a href="https://www.acmicpc.net/problem/17298">백준 17298번 오큰수 구하기</a></p>
<pre><code class="language-java">package part1;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Stack;
import java.util.StringTokenizer;

public class stackQueue2 {
    public static void main(String[] args) throws IOException {

        /* 백준 17298번 오큰수 구하기 */

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int size = Integer.parseInt(br.readLine()); // 크기

        // 1) 변수 정의
        StringTokenizer line = new StringTokenizer(br.readLine());
        int [] arr = new int[size]; // 입력받은 수 배열
        int [] ans = new int[size]; // 정답 배열

        for(int i = 0; i &lt; size; i++) {
            arr[i] = Integer.parseInt(line.nextToken());
        }

        Stack&lt;Integer&gt; stack = new Stack&lt;Integer&gt;();
        stack.push(0); // 비교를 위한 초기화

        // 2) 오큰수 판별 
        for(int i = 1; i &lt; size; i++) {

            // 만약, arr[2] = 3이면 스택에 1과 2가 존재
            // arr[3] = 8이 되었을 때, ans[1, 2] = arr[8]이 된다. 

            while (!stack.isEmpty() &amp;&amp; arr[stack.peek()] &lt; arr[i]) { // arr[0] = 3 arr[1] = 5 오큰수일 때, 정답 배열에 넣기
                ans[stack.pop()] = arr[i]; // 0이 pop되고, ans[0]= 5가 됨
            }

            stack.push(i);

        }

        // 3) -1 처리하기
        while(!stack.empty()) { // 반복문 다 돌고 stack이 빌 때까지 -1 넣기
            ans[stack.pop()] = -1;
        }

        // 4) 출력하기
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        for(int i = 0; i &lt; size; i++) {
            bw.write(ans[i] + &quot; &quot;);
        }

        bw.flush();
    }
}
</code></pre>
<p>인덱스를 스택에 저장하는 거 어케 생각하지 .. ? 대단하다 </p>
<p>문제 3. <a href="https://www.acmicpc.net/problem/2164">백준 2164번 카드게임</a></p>
<p>** 🔎 접근법 **</p>
<ul>
<li>큐를 사용한다!
삭제는 poll() 추가는 add()</li>
</ul>
<pre><code class="language-java">import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {

        /* 백준 2164번 카드게임 */

        Scanner sc = new Scanner(System.in);
        Queue&lt;Integer&gt; q = new LinkedList&lt;&gt;();

        // 1. 변수 선정 및 초기화
        int num = sc.nextInt();


        for(int i = 1; i &lt;= num; i++) {
            q.add(i);
        }

        // 2. 한장 남을때까지 반복
        while(q.size() &gt; 1) {
            q.poll(); // 첫장 버리기
            q.add(q.poll()); // 버린 거 다시 아래에 넣기
        }

        // 3. 한장 출력
        System.out.println(q.poll());
    }
}
</code></pre>
<p>문제 4. <a href="https://www.acmicpc.net/problem/11286">백준 11286번 절대값 힙 구하기</a></p>
<p>** 🔎 접근법 **</p>
<ul>
<li><p>들어온 순서에 상관없이 크기가 작으면 삭제할 수 있어야함 -&gt; 우선순위 큐 ( 저장 시 오름차순 정렬)</p>
</li>
<li><p>절댓값 힙 
: 정수 x 넣는다 ( x != 0)
: 배열에서 절댓값 가장 작은 수 출력 후 제거
: 값이 같을 경우 그중 가장 작은 수 출력</p>
</li>
</ul>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.PriorityQueue;

public class Main {
    public static void main(String[] args) throws IOException {

        /* 백준 11286번 절댓값 힙 구하기 */

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int size = Integer.parseInt(br.readLine());

        PriorityQueue&lt;Integer&gt; q = new PriorityQueue&lt;&gt;((o1, o2) -&gt; {

            int first_abs = Math.abs(o1);
            int second_abs = Math.abs(o2);

            if (first_abs == second_abs) {

                /* [1과 -1의 의미]
                 * 1은 뒤로 가야 함
                 * -1은 앞으로 가야 함  */

                return o1 &gt; o2 ? 1 : -1;

            } else {
                return first_abs - second_abs;
            }
        }); 

        for(int i = 0; i &lt; size; i++) {
            int n = Integer.parseInt(br.readLine());

            if(n == 0) { // 제거
                if(q.isEmpty()) {
                    System.out.println(&quot;0&quot;);
                } else {
                    System.out.println(q.poll());
                }
            } else { // 추가
                q.add(n);
            }
        }
    }
}

</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[파트1] 코딩테스트 기초 (슬라이딩 윈도우)]]></title>
            <link>https://velog.io/@oss_nue/%ED%8C%8C%ED%8A%B81-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B8%B0%EC%B4%88-%EC%8A%AC%EB%9D%BC%EC%9D%B4%EB%94%A9-%EC%9C%88%EB%8F%84%EC%9A%B0</link>
            <guid>https://velog.io/@oss_nue/%ED%8C%8C%ED%8A%B81-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B8%B0%EC%B4%88-%EC%8A%AC%EB%9D%BC%EC%9D%B4%EB%94%A9-%EC%9C%88%EB%8F%84%EC%9A%B0</guid>
            <pubDate>Mon, 18 Nov 2024 05:15:48 GMT</pubDate>
            <description><![CDATA[<h3 id="📢-슬라이딩-윈도우">📢 슬라이딩 윈도우</h3>
<blockquote>
<p>2개의 포인터로 범위를 지정한 다음, 범위를 유지한 채로 이동하며 문제 해결</p>
</blockquote>
<ul>
<li>투 포인터와 원리 유사</li>
</ul>
<hr>
<p>문제 1. <a href="https://www.acmicpc.net/problem/12891">백준 12891번 DNA 비밀번호</a></p>
<p><strong>🔎 접근법</strong> (가정) 전체 길이 S 부분 길이 P</p>
<ol>
<li>길이가 P인 윈도우를 지정하여 배열 S 시작점에 놓기</li>
<li>오른쪽으로 밀면서 조건 탐색</li>
<li>P 문자열이 배열 S 끝에 도달할 때까지 이동</li>
</ol>
<p>&lt;중요&gt;</p>
<ul>
<li>비밀번호 체크 배열, 현재 상태 배열, 조건 충족 판단 변수 필요</li>
<li>메서드를 따로 만들어 슬라이딩 윈도우 실행할 것</li>
</ul>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {

    // 모든 메서드에서 사용할 수 있도록 static으로 선언
    static int checkArr[]; // 조건 배열
    static int myArr[]; // 현재 상태 배열
    static int total; // 몇 개의 문자와 관련된 개수를 충족했는지 판단

    public static void main(String[] args) throws IOException {

        /* 백준 12891번 DNA 비밀번호 */

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer line1 = new StringTokenizer(br.readLine());

        // 1. 변수 초기화
        int length = Integer.parseInt(line1.nextToken()); // DNA 문자열 길이
        int sLength = Integer.parseInt(line1.nextToken()); // 부분 문자열 길이
        int result = 0; // 몇 개가 총 조건이 충족됐는지

        char [] arr = br.readLine().toCharArray(); // 입력받은 문자열 배열
        checkArr = new int[4]; // 4인 이유는 조건 A, C, G, T 4개이기 때문
        myArr = new int[4];
        total = 0;


        StringTokenizer line2 = new StringTokenizer(br.readLine());

        // 조건 저장
        for(int i = 0; i &lt; 4; i++) {
            checkArr[i] = Integer.parseInt(line2.nextToken());
            if(checkArr[i] == 0) total++; // 있든 없든 조건 무조건 충족하는 것이기 때문에 증가
        }

        // 2. 초기 윈도우 처리
        for (int i = 0; i &lt; sLength; i++) {
            Add(arr[i]);
        }

        if(total == 4) result++;

        // 3. 슬라이딩 윈도우 시작
        for(int i = sLength; i &lt; length; i++) {
            int n = i - sLength; // 예. sLength = 4, i = 4이면 n = 0 length가 6이면 n=2까지

            Add(arr[i]); // arr[4] 
            remove(arr[n]); // arr[0]
            if(total == 4) result++; 

        }

        System.out.println(result);


    }

    // [조건에 맞는 문자 처리 1]
    // 새로 들어온 문자에 대한 조건 처리
    // 조건 배열인 check와 현재 my가 같을 경우 충족변수 +
    private static void Add(char c) {
        switch (c) {
        case &#39;A&#39;:
            myArr[0]++;
            if(checkArr[0] == myArr[0]) total++;
            break;
        case &#39;C&#39; :
            myArr[1]++;
            if(checkArr[1] == myArr[1]) total++;
            break;
        case &#39;G&#39; :
            myArr[2]++;
            if(checkArr[2] == myArr[2]) total++;
            break;
        case &#39;T&#39; :
            myArr[3]++;
            if(checkArr[3] == myArr[3]) total++;
            break;
        }
    }

    // [조건에 맞는 문자 처리 2]
    // 이전 문자 제거하기

    private static void remove(char c) {
        switch(c) {
        case &#39;A&#39; :
            if(checkArr[0] == myArr[0]) total--;
            myArr[0]--;
            break;
        case &#39;C&#39; :
            if(checkArr[1] == myArr[1]) total--;
            myArr[1]--;
            break;
        case &#39;G&#39; :
            if(checkArr[2] == myArr[2]) total--;
            myArr[2]--;
            break;
        case &#39;T&#39; :
            if(checkArr[3] == myArr[3]) total--;
            myArr[3]--;
            break;
        }
    }

}
</code></pre>
<p>remove()함수에서</p>
<pre><code class="language-java">case &#39;A&#39; :
    if(checkArr[0] == myArr[0]) total--;
    myArr[0]--;
    break;</code></pre>
<p>이 부분을 원래 </p>
<pre><code class="language-java">case &#39;A&#39; :
     myArr[0]--;
     if(checkArr[0] == myArr[0]) total--;
     break;</code></pre>
<p>이렇게 써버림.. 현재 상태를 제거하고 비교하면 당연히 안 맞겠죠..? </p>
<p>문제2. <a href="https://www.acmicpc.net/problem/11003">백준 11003번 최솟값 찾기</a></p>
<p><strong>🔎 접근법</strong></p>
<ol>
<li>덱의 구조 이해 : 양끝에서 데이터 삽입 / 삭제 가능</li>
</ol>
<ul>
<li>형태 : (인덱스, 숫자)</li>
<li>앞 인덱스와 뒤 인덱스의 값을 비교하여 뒤의 인덱스가 클 경우 추가 뒤에 인덱스가 작을 경우엔 앞 인덱스 제거 과정을 거치며 정렬됨</li>
</ul>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Scanner;
import java.util.StringTokenizer;


public class Main {

    // public static final Scanner scan = new Scanner(System.in);

    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer line1 = new StringTokenizer(br.readLine());

        int s = Integer.parseInt(line1.nextToken()); // 전체 크기
        int p = Integer.parseInt(line1.nextToken()); // 슬라이딩 윈도우 크기

        StringTokenizer line2 = new StringTokenizer(br.readLine());

        Deque&lt;Node&gt; nums = new LinkedList&lt;&gt;(); // 숫자 배열 데크 형식

        for(int i = 0; i &lt; s; i++) {
            int now = Integer.parseInt(line2.nextToken());

            while(!nums.isEmpty() &amp;&amp; nums.getLast().value &gt; now) { // 새로운 값보다 이전 값이 크다면 제거
                nums.removeLast();
            }

            nums.addLast(new Node(now, i));

            // 범위에서 벗어난 인덱스 제거
            if(nums.getFirst().index &lt;= i - p) {
                nums.removeFirst();
            }

            bw.write(nums.getFirst().value + &quot; &quot;);
        }

        bw.flush(); // 출력
        bw.close();
    }

    // Node 형식 정하기
    static class Node {
        public int value;
        public int index;

        Node(int value, int index) {
            this.value = value;
            this.index = index;
        }
    }
}
</code></pre>
<p>BufferdWriter은 처음 써보는데 bw.write()했는데 왜 콘솔에 안 나오지 싶었다. 근데 bw.flush() 해줘야 출력됨 </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[파트1] 코딩테스트 기초(투 포인터)]]></title>
            <link>https://velog.io/@oss_nue/%ED%8C%8C%ED%8A%B81-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B8%B0%EC%B4%88%ED%88%AC-%ED%8F%AC%EC%9D%B8%ED%84%B0-%EC%8A%AC%EB%9D%BC%EC%9D%B4%EB%94%A9-%EC%9C%88%EB%8F%84%EC%9A%B0-%EC%8A%A4%ED%83%9D%EA%B3%BC-%ED%81%90</link>
            <guid>https://velog.io/@oss_nue/%ED%8C%8C%ED%8A%B81-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B8%B0%EC%B4%88%ED%88%AC-%ED%8F%AC%EC%9D%B8%ED%84%B0-%EC%8A%AC%EB%9D%BC%EC%9D%B4%EB%94%A9-%EC%9C%88%EB%8F%84%EC%9A%B0-%EC%8A%A4%ED%83%9D%EA%B3%BC-%ED%81%90</guid>
            <pubDate>Thu, 14 Nov 2024 10:33:54 GMT</pubDate>
            <description><![CDATA[<h3 id="📢-1-투-포인터">📢 1) 투 포인터</h3>
<p><strong>(1) 개념</strong></p>
<blockquote>
<p>시작 인덱스와 종료 인덱스 지정</p>
</blockquote>
<ul>
<li>시작 인덱스를 오른쪽으로 한 칸 이동하는 것은 연속된 자연수에서 왼쪽 값을 &#39;삭제&#39;하는 것</li>
<li>종료 인덱스를 오른쪽으로 한 칸 이동하는 것은 연속된 자연수의 범위를 한칸 더 확장하는 것</li>
<li>같을 때는 경우의 수 1 증가 시키고 종료 인덱스 오른쪽 이동</li>
</ul>
<p><strong>(2) 이동 원칙</strong></p>
<ul>
<li>sum &gt; N : sum = sum - start_index; start_index++;</li>
<li>sum &lt; N : sum = sum + end_index; end_index++;</li>
<li>sum == N : end_index++; sum = sum + end_index; count++;</li>
</ul>
<hr>
<p>문제 1. <a href="https://www.acmicpc.net/problem/2018">백준 2018번 연속된 자연수의 합 구하기</a></p>
<p><strong>🔎 접근법</strong>
: N의 최대값이 10,000,000이므로 O(n) 복잡도 알고리즘 사용</p>
<ul>
<li>연속된 자연수 합 구하는 것이기 때문에 시작인덱스와 끝 인덱스 지정</li>
</ul>
<p><span style="background-color:#FFD8D8">1. sum이 n보다 작을 때:</span></p>
<ul>
<li>end_index를 증가시키고 증가된 end_index 값을 sum에 추가한다.</li>
<li>end_index는 연속된 자연수를 더해주는 역할이기 때문에 현재 값(end_index)을 먼저 더한 후 증가한다.</li>
</ul>
<p><span style="background-color:#FFD8D8">2. sum이 n보다 클 때:</span></p>
<ul>
<li>start_index를 먼저 sum에서 빼고 나서 start_index를 증가시킨다.</li>
<li>start_index는 더 이상 필요 없는 구간을 제거하는 역할을 하기 때문에 현재 값(start_index)을 빼고 나서 증가한다.</li>
</ul>
<pre><code class="language-java">import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        /* 백준 2018번 연속된 자연수의 합 구하기 */

        Scanner sc = new Scanner(System.in);

        // 1) 값 초기화
        int n = sc.nextInt();
        int count = 1; // n 자체를 선택할 경우 카운트
        int sum = 1;
        int start_index = 1;
        int end_index = 1;

        // 2) 계산
        while(end_index != n) {
            if(sum &gt; n) { // 합이 정해진 수보다 클 경우 (빼준다-&gt; start 움직이기)
                sum -= start_index;
                start_index++;
            }
            else if (sum &lt; n) { // 합이 정해진 수보다 작을 경우 (더해준다 -&gt; end 움직이기) 
                end_index++;
                sum += end_index;
            }
            else { // 합이 N과 같을 경우 (count 횟수 올린다 후에 end 움직이기)
                count++;
                end_index++;
                sum += end_index;
            }
        }

        System.out.println(count);

    }

}
</code></pre>
<p>문제 2. <a href="https://www.acmicpc.net/problem/1940">백준 1940번 주몽의 명령</a></p>
<p><strong>🔎 접근법</strong></p>
<ul>
<li>위에랑 비슷한 문제긴 하지만 연속된 자연수가 아니고 입력받은 숫자 내의 합을 구해야 함으로 투 포인터를 사용하기 위해 <span style="background-color:#FFD8D8">정렬</span>을 먼저 해 줘야 한다. </li>
<li>같은 지점이 아닌 정렬의 시작과 끝에 위치</li>
</ul>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {

        /* 백준 1940번 주몽의 명령 */

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        // 1) 값 초기화
        int n = Integer.parseInt(br.readLine());
        int sum = Integer.parseInt(br.readLine());
        int [] in = new int[n];

        StringTokenizer line = new StringTokenizer(br.readLine());
        for(int i = 0; i &lt; n; i++) {
            in[i] = Integer.parseInt(line.nextToken());
        }

        // 정렬
        Arrays.sort(in);

        int count = 0; // 횟수
        int start = 0; // 시작 포인터
        int end = n-1; // 끝 포인터

        // 2) 계산

        while (start &lt; end) { // 교차 시 중지 
            int nSum = in[start] + in[end];

            if(nSum &gt; sum) end--; // 정해진 합보다 클 경우 end 포인터 감소
            else if (nSum &lt; sum) start++; // 정해진 합보다 작을 경우 start 증가
            else {
                count++;
                end--;
                start++;
            }
        }

        System.out.println(count);

    }
}
</code></pre>
<p>문제 3. <a href="https://www.acmicpc.net/problem/1253">백준 1253번 좋은 수 구하기</a></p>
<p><strong>🔎 접근법</strong></p>
<ul>
<li>정렬할 것</li>
<li>같은 지점에서 시작할 것인지 / 양쪽 끝과 끝에서 시작할 것인지
==&gt; 양쪽 끝에서 시작</li>
<li>두 수의 합이 배열 안에 존재함을 판별해야 함</li>
</ul>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

class Main {
    public static void main(String[] args) throws IOException {

        /* 백준 1253번 좋은 수 구하기 */

        // 1. 변수 초기화
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());

        StringTokenizer line = new StringTokenizer(br.readLine());
        int [] nums = new int[n];

        for(int i = 0; i &lt; n; i++) {
            nums[i] = Integer.parseInt(line.nextToken());
        }

        int count = 0;

        // 2. 정렬
        Arrays.sort(nums);

        // 3. 계산

        for(int i = 0; i &lt; n; i++) {

            int start = 0; // 값을 찾기 위해서 다시 처음부터 시작해야 하니 while문 밖에 선언
            int end = n-1;
            int find = nums[i]; // 찾을 값

            while(start &lt; end) {

                if (start == i) {
                    start++;
                    continue;
                }
                if (end == i) {
                    end--;
                    continue;
                }

                int nSum = nums[start] + nums[end];

                if (nSum == find) {
                        count++;
                        break; // 좋은 수를 찾았으니 다음 i로 넘어감
                } else if (nSum &lt; find) {
                    start++;
                } else {
                    end--;
                }
            }

        }

        System.out.println(count);
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[파트1] 코딩테스트 기초편 (배열/리스트/구간합)]]></title>
            <link>https://velog.io/@oss_nue/%ED%8C%8C%ED%8A%B81-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B8%B0%EC%B4%88%ED%8E%B8-%EB%B0%B0%EC%97%B4%EB%A6%AC%EC%8A%A4%ED%8A%B8%EA%B5%AC%EA%B0%84%ED%95%A9</link>
            <guid>https://velog.io/@oss_nue/%ED%8C%8C%ED%8A%B81-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B8%B0%EC%B4%88%ED%8E%B8-%EB%B0%B0%EC%97%B4%EB%A6%AC%EC%8A%A4%ED%8A%B8%EA%B5%AC%EA%B0%84%ED%95%A9</guid>
            <pubDate>Mon, 11 Nov 2024 04:01:21 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/oss_nue/post/38dc8a93-8d73-4d9a-9c8c-8c93893a7d11/image.jpg" alt=""></p>
<p>이 책으로 코테 준비해보려고 함니다.. 
파팅 </p>
<p><a href="https://github.com/nueoss/STUDY">깃 레퍼지토리</a></p>
<h3 id="📢-1-배열과-리스트">📢 1) 배열과 리스트</h3>
<p>(1) 배열의 개념 및 특징</p>
<p>배열이란 ? 메모리의 연속공간에 값이 채워져있는 형태의 자료구조</p>
<ul>
<li>인덱스를 사용하여 값에 바로 접근할 수 있다.</li>
<li>새로운 값을 삽입하거나 특정 인덱스에 있는 값을 삭제하기 어렵다.</li>
<li>배열의 크기는 선언할 때 지정할 수 있으며 한 번 선언하면 크기를 늘리거나 줄일 수 없다</li>
</ul>
<p>(2) 리스트의 개념 및 특징</p>
<p>리스트란? 값과 포인터를 묶은 노드라는 것을 포인터로 연결한 자료구조</p>
<ul>
<li><p>인덱스가 없으므로 값에 접근하려면 Head부터 순서대로 접근 (<span style="color:red">속도가 느리다</span>)</p>
<ul>
<li>포인터로 연결되어 있어 데이터를 삽입하거나 삭제하는 연산 속도가 빠르다</li>
<li>선언할 때 크기를 별도로 지정하지 않아도 된다. (크기 변하기 쉬운 데이터 사용할 때 적절)</li>
<li>포인터를 저장할 공간이 필요하므로 배열보다 구조가 복잡하다</li>
</ul>
<hr>
<p>문제 1. <a href="https://www.acmicpc.net/problem/11720">백준 11720번 숫자의 합 구하기 </a></p>
<p>🔎 접근법 : N의 버위가 1부터 100까지니까 숫자형으로 담을 수 없다
그러니 문자열로 입력값을 받고 문자로 바꿔준 뒤, 숫자로 바꿔 계산</p>
<ul>
<li>문자열 -&gt; 문자형 : toCharArray / 문자형 -&gt; 문자열 : String.valueOf</li>
<li>문자열 입력 받을땐 next() 함수 사용</li>
</ul>
<pre><code class="language-java">import java.util.Scanner;

class Main { 
  public static void main(String[] args) {
      Scanner sc = new Scanner(System.in);

      // 첫 번째 입력: 숫자의 개수
      int N = sc.nextInt();

      // 두 번째 입력: 숫자 문자열
       String sNum = sc.next();
      char[] cNum = sNum.toCharArray(); // 문자로 바꿔 주기

      int sum = 0;

      for(int i = 0; i &lt; cNum.length; i++) {
          sum += cNum[i] - &#39;0&#39;;
      }

      System.out.println(sum);
  }
}
</code></pre>
</li>
</ul>
<p>아스키코드에서 같은 의미의 문자의 숫자 코드 값 차이는 48이다
<span style="color:red">&#39;1&#39;- 48 또는 &#39;1&#39;-0 의 형식으로 변환</span></p>
<p>문제2. <a href="https://www.acmicpc.net/problem/1546">백준 1546번 평균 구하기</a></p>
<p> 🔎 접근법 </p>
<blockquote>
<p>변환 점수 평균 구하는 법 &gt;  ( A + B + C ) * 100 / 최댓값 / 3</p>
</blockquote>
<pre><code class="language-java"> import java.util.Scanner;

class Main {
    public static void main(String[] args) {

    Scanner sc = new Scanner(System.in);

    // 1. 전체 과목 수 받아오기 + 선언
    int total = sc.nextInt();
    int [] score = new int[total]; // 이 부분 

    // 2. 점수 받아오기 + 최대값 구하기 + 총합 구하기

    long max = 0;
    long scoreSum = 0;

     for (int i = 0; i &lt; total; i++) {
          score[i] = sc.nextInt();
          if(max &lt; score[i]) {
              max = score[i];
          }

          scoreSum += score[i];
      }

        System.out.println(scoreSum * 100.0 / max / total);
    }</code></pre>
<p>여기서 굳이 long을 사용한 이유는 total의 크기가 1000까지라고 해서 사용함</p>
<hr>
<h3 id="📢-2-구간-합">📢 2) 구간 합</h3>
<p><strong>(1) 합 배열 S 정의</strong>
S[i] = A[0] + A[1] + A[2] + ... + A[i-1] + A[i]</p>
<blockquote>
<p>기존 배열의 일정 범위의 합을 구하는 시간 복잡도가 O(N)에서 O(1)로 감소</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/oss_nue/post/a1b1a027-eaa4-4ae3-8f89-727de888e7fa/image.jpg" alt=""></p>
<p><strong>(2) 합 배열 S를 만드는 공식</strong>
S[i] = S[i-1] + A[i]</p>
<p><strong>(3) 구간 합 구하는 공식</strong>
S[j] - S[i-1] : i에서 j까지 구간 합</p>
<p><img src="https://velog.velcdn.com/images/oss_nue/post/08802ba5-deab-4ca8-b771-766591ff71d9/image.jpg" alt=""></p>
<hr>
<p>문제 1. <a href="">백준 11659번 구간 합 구하기</a></p>
<p>** 🔎 접근법 :**</p>
<ol>
<li>BufferedReader가 Scanner보다 빠르다</li>
<li>StringTokenizer로 문자열을 구분하여 각 입력 줄을 따로 사용하자</li>
</ol>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class rangeSum1 {
    public static void main(String[] args) throws IOException {

        // 백준 11659번 구간 합 구하기
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 사용자 입력 받기
        StringTokenizer line1 = new StringTokenizer(br.readLine()); // 문자열 분리

        // 1. 개수 정하기
        int nData = Integer.parseInt(line1.nextToken());
        int nQuiz = Integer.parseInt(line1.nextToken());

        // 2. 부분 합 배열 만들기
        long [] sArr = new long[nData + 1]; // sArr[0] = 0으로 초기화

        StringTokenizer line2 = new StringTokenizer(br.readLine());

        for(int i = 1; i &lt;= nData; i++) {
            sArr[i] = sArr[i-1] + Integer.parseInt(line2.nextToken());
        }

        // 3. 질의 세 개 만들고 계산하기

        for(int i = 0; i &lt; nQuiz; i++) {
            StringTokenizer line3 = new StringTokenizer(br.readLine()); // 질의를 반복해야 하니까 for문 안에 입력
            int q1 = Integer.parseInt(line3.nextToken());
            int q2 = Integer.parseInt(line3.nextToken());

            System.out.println(sArr[q2] - sArr[q1-1]);
        }

    }
}</code></pre>
<p>문제 2. <a href="https://www.acmicpc.net/problem/11660">백준 11660번 구간 합 구하기</a></p>
<p>** 🔎 접근법 **</p>
<ol>
<li><p>2차원 배열 합 배열 활용</p>
<blockquote>
<p>이차원 배열 선언하는 법
int[][] a = new int[n][n]</p>
</blockquote>
<ol start="2">
<li>이차원 배열 구간합 구하는 법
dArr[i][j] = dArr[i][j-1] + dArr[i-1][j] - dArr[i-1][j-1] + sArr[i][j]</li>
</ol>
</li>
</ol>
<ol start="3">
<li><p>이차원 배열 부분합 구하는 법
dArr[x2][y2] - dArr[x1-1][y2] - dArr[x2][y1-1] + dArr[x1-1][y1-1]</p>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
</code></pre>
</li>
</ol>
<p>public class rangeSum2 {
    public static void main(String[] args) throws IOException {
        /* 백준 11660번 구간 합 구하기 */</p>
<pre><code>    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    StringTokenizer line1 = new StringTokenizer(br.readLine());

    // 1. 배열 사이즈, 질의 개수
    int nSize = Integer.parseInt(line1.nextToken());
    int nQize = Integer.parseInt(line1.nextToken());

    // 2. 2차원 배열 만들기
    int [][] sArr = new int[nSize + 1][nSize + 1]; // sArr[0] = 0

    for(int i = 1; i &lt;= nSize; i++) {
        StringTokenizer line2 = new StringTokenizer(br.readLine());
        for(int j = 1; j &lt;= nSize; j++) {
            sArr[i][j] = Integer.parseInt(line2.nextToken());
        }
    }

    // 3. 구간합 구하기
    int [][] dArr = new int[nSize + 1][nSize + 1];

    for(int i = 1; i &lt;= nSize; i++) {
        for(int j = 1; j &lt;= nSize; j++) {
            dArr[i][j] = dArr[i][j-1] + dArr[i-1][j] - dArr[i-1][j-1] + sArr[i][j];
        }
    }

    // 4. 질의
    for(int i = 0; i &lt; nQize; i++) {
        StringTokenizer line3 = new StringTokenizer(br.readLine());
        int x1 = Integer.parseInt(line3.nextToken());
        int y1 = Integer.parseInt(line3.nextToken());
        int x2 = Integer.parseInt(line3.nextToken());
        int y2 = Integer.parseInt(line3.nextToken());

        System.out.println(dArr[x2][y2] - dArr[x1-1][y2] - dArr[x2][y1-1] + dArr[x1-1][y1-1]);
    }
}</code></pre><p>} </p>
<pre><code></code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[컬렉션 : COLLECTION]]></title>
            <link>https://velog.io/@oss_nue/%EC%BB%AC%EB%A0%89%EC%85%98-COLLECTION</link>
            <guid>https://velog.io/@oss_nue/%EC%BB%AC%EB%A0%89%EC%85%98-COLLECTION</guid>
            <pubDate>Tue, 24 Sep 2024 12:31:57 GMT</pubDate>
            <description><![CDATA[<h3 id="🤍-1-컬렉션이란">🤍 1) 컬렉션이란</h3>
<blockquote>
<p>컴퓨터 시스템에서 데이터를 효율적으로 저장 및 관리하는 법</p>
</blockquote>
<p> <span style="background-color : #D4F4FA "> 컬렉션 3대 인터페이스 : SET, LIST, MAP </span>
 =&gt; 각 인터페이스를 구현한 구현체 클래스들이 제공된다.
 =&gt; 이 중 Set과 List 계열은 Collention 인터페이스를 공동으로 상속받았으므로 대부분의 메서드가 동일함</p>
<hr>
<h3 id="📌-1-set-계열">📌 (1) Set 계열</h3>
<blockquote>
<ol>
<li>저장 순서가 유지되지 않는다. (인덱스 사용 불가)<ol start="2">
<li>데이터 중복을 허용하지 않음 (중복 데이터 X)</li>
</ol>
-&gt; 효율적인 중복 제거 수단으로 사용됨</li>
</ol>
</blockquote>
<p> <span style="background-color : #D4F4FA ">  &lt; Set 계열의 구현체 클래스 &gt; </span>
 HashSet, LikedHashSet(순서), TreeSet(정렬) </p>
<pre><code class="language-java">   HashSet set1 = new HashSet(); /* 일반적인 HashSet 객체 생성 */
   Set set2 = new HashSet(); /* 업캐스팅 */</code></pre>
<p><span style="background-color : #D4F4FA ">  &lt; Set 계열의 메서드 &gt; </span></p>
<pre><code class="language-java">  // 비어있는지, 개수, 모든 요소 출력
  System.out.println(&quot;Set 객체가 비어있는가?&quot; set.isEmpty);
  System.out.println(&quot;Set 객체에 저장된 요소 개수 &quot; set.size() );
  System.out.println(&quot;Set 객체의 모든 요소 &quot; + set);

  /* --------------------------------------------------------- */

  // 추가 방법 및 포함 여부
  System.out.println(&quot;요소 추가 방법 : &quot; + set.add(9));
  System.out.println(&quot;9가 포함되어 있는가? &quot; + set.contains(9));

  /* -------------------------------------------------------- */

  // set 옮기기
  Set set2 = new HashSet();
  System.out.println(&quot;set2에 set객체 모두 추가 : &quot; + set2.addAll(set));

  // 모두 제거
  set2.clear();

 /* -------------------------------------------------------- */

  Set set4 = new HashSet();
  set4.add(100);
  set4.add(99);
  set4.add(500);
  set4.add(2);
  set4.add(35);
  set4.add(999);

  // 정렬
  Set set5 = new TreeSet(set4);
  System.out.println(set5); // [2, 35, 99, 100, 500, 999] 크기순으로 정렬

  /* -------------------------------------------------------- */

  Set&lt;Integer&gt; set6 = new LinkedHashSet(); 
  set6.add(100);
  set6.add(99);
  set6.add(500);
  set6.add(2);
  set6.add(35);
  set6.add(999);

  // 순서
  System.out.println(set6); // [100, 99, 500, 2, 35, 999]
</code></pre>
<hr>
<h3 id="📌-2-list-계열">📌 (2) List 계열</h3>
<blockquote>
<ol>
<li>인덱스 번호를 이용하여 저장 순서가 유지됨<ol start="2">
<li>데이터 중복 허용</li>
<li>배열과 유사하나, 배열과 달리 저장 공간이 자동 확장된다.</li>
</ol>
</li>
</ol>
</blockquote>
<p><span style="background-color : #D4F4FA ">  &lt; List 계열의 구현체 클래스 &gt; </span>
: ArrayList, Vector, LikedList 등</p>
<p><span style="background-color : #D4F4FA ">  &lt; ArrayList VS Vector &gt; </span><br> : 기본적인 구조가 동일하며, 메서드가 동일하다
 : Vector의 경우 멀티쓰레드 환경에서 안전하게 객체를 사용할 수 있다.
 : ArrayList는 멀티쓰레드 환경을 지원하지 않음</p>
<p><span style="background-color : #D4F4FA ">  &lt; ArrayList VS LinkedList &gt; </span>
 : 기본적인 구조가 완전 다르며 메서드는 동일하다
 : ArrayList는 배열구조로써 인덱스를 활용하여 데이터 탐색이나 순차적인 추가 / 삭제가 빠르다
 : LinkedList는 다음 데이터 위치를 현재 데이터가 갖고 있는 형태 데이터 탐색이나 순차적인 작업은 느리다</p>
<p> <span style="background-color : #D4F4FA ">  &lt; List 계열의 메서드 &gt; </span></p>
<pre><code class="language-java"> List list = new ArrayList();

 // (1) 추가
 list.add(&quot;RED&quot;);
 list.add(1);
 list.add(3.14);

 // (1-1) 중복 데이터 추가
 list.add(1); // 가능

 // (1-2) 인덱스를 이용하여 추가
 list.add(2,3) // 기존의 2번 인덱스를 밀어내고 정수 3을 2번 인덱스에 삽입

 // (2) 비어있는지, 개수 출력, 요소 모두 출력
 System.out.println(&quot;list 객체가 비어있는가? &quot; + list.isEmpty);
 System.out.println(&quot;list 객체에 저장된 요소 개수 : &quot; + list.size());
 System.out.println(&quot;list 객체의 모든 요소 : &quot; + list);

 // (3) 출력
 System.out.println(&quot;3번 인덱스 요소 출력 : &quot; +list.get(3)); 

 // (4) 제거
 // Object remove(int index): index에 해당하는 요소 제거 (제거되는 요소 리턴)
 // boolean remove(Object o): o에 해당하는 객체 제거(제거될 경우 true 리턴)
 //System.out.println(&quot;인덱스를 사용하여 정수2(인덱스1) 삭제: &quot; + list.remove(1));
 //System.out.println(&quot;정수 2를 지정하여 해당 요소 직접 삭제: &quot; + list.remove(2));
   // =&gt; 정수 2를 지정하는 것이 아닌 2번 인덱스 지정으로 취급됨
   //    따라서,정수2를 지정하여 삭제해야하는 경우 Object 타입으로 형변환 필요
   System.out.println(&quot;정수 2를 지정하여 해당 요소 직접 삭제: &quot; + list.remove((Object)2));
   System.out.println(&quot;list 객체에 모든 요소 출력: &quot; + list);

 // (5) 인덱스 번호 알아내기
  System.out.println(&quot;RED의 인덱스 번호 알아내기 : &quot; + list.indexOf(&#39;RED&#39;) );

 // (6) 정렬
 List list3 = new ArrayList();

 list3.add(3);
 list3.add(4);
 list3.add(1);
 list3.add(6);
 list3.add(5);
 list3.add(2);
 System.out.println(&quot;정렬 전: &quot; + list3); // [3,4,1,6,5,2]

 // Collections 클래스의 static 메서드 sort() 사용 시 List 객체 정렬 가능
 Collections.sort(list3);
 System.out.println(&quot;정렬 후: &quot; + list3); // [1, 2, 3, 4, 5, 6]

 // Collections 클래스의 static 메서드 shuffle() 사용 시 List 객체 섞기 가능
 Collections.shuffle(list3);
 System.out.println(&quot;셔플 후: &quot; + list3); // [무작위]

 // (7) 배열 전달
 String [] str = new String[] {&quot;a&quot;,&quot;b&quot;,&quot;c&quot;};
 List arrList = Arrays.asList(str);

 // (8) Set과 List 상호 호환

 Set set = new HashSet();
 set.add(1); set.add(20); set.add(3); set.add(450); set.add(55);
 List list4 = new ArrayList(set);

 // (9) 중복 제거
 // =&gt; 목표 ABCD, A, AB, ABC
 List list5 = Arrays.asList(&quot;ABCD&quot;, &quot;A&quot;, &quot;ABCD&quot;, &quot;AB&quot;, &quot;A&quot;, &quot;AB&quot;, &quot;ABC&quot;);

 Set set2 = new LinkedHashSet(list5); // 순서 유지되면서 중복 제거

 List list6 = new ArrayList(set2);
</code></pre>
<hr>
<h3 id="📌-3-map-계열">📌 (3) Map 계열</h3>
<blockquote>
<ol>
<li>데이터 키와 값 한 쌍의 형태로 관리하는 자료 구조 (해쉬테이블 구조)<ol start="2">
<li>키는 중복이 불가능하며, 값은 중복 가능함</li>
</ol>
</li>
</ol>
</blockquote>
<p><span style="background-color : #D4F4FA ">  &lt; Map 계열의 구현체 클래스 &gt; </span>
  : HashMap, LikedHashMap, TreeMap</p>
<p> <span style="background-color : #D4F4FA ">  &lt; Map 계열의 메서드 &gt; </span></p>
<pre><code class="language-java">  map map = new HashMap();

  // (1) 값 저장
   map.put(1,&quot;java&quot;);
   map.put(2, &quot;jsp&quot;);
   map.put(3, &quot;Spring&quot;);

  // (1-1) 중복되는 키 사용할 경우
   map.put(3,&quot;oracle&quot;); // 3번 값이 Spring -&gt; Oralce로 바뀐다.

  // (2) 출력
  // (2-1) 모든 키 출력
   Set keySet = map.ketSet();
   System.out.println(&quot;map 객체 내의 모든 키 : &quot; + keySet);

  // (2-2) 모든 값 출력
   System.out.println(&quot;map 객체 내의 모든 값 : &quot; + map.values());

  // (2-3) 키를 통해 값 출력
   System.out.println(&quot;키 3번에 해당하는 값 출력 &quot; + map.get(3));</code></pre>
<p>코테 전 발등에 불떨어짐 이슈 .. <del>~</del> !! ㅠㅠ</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQL] GROUP BY 정리]]></title>
            <link>https://velog.io/@oss_nue/SQL-GROUP-BY-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@oss_nue/SQL-GROUP-BY-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Tue, 24 Sep 2024 10:57:42 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/parts/17044">https://school.programmers.co.kr/learn/courses/30/parts/17044</a>
여기 문제 참고했습니다 ^__^</p>
<h3 id="01-월별-같은-자동차의-합">01. 월별 같은 자동차의 합</h3>
<p><span style="color:#00AAFF">[문제]</span>
CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블에서 대여 시작일을 기준으로 2022년 8월부터 2022년 10월까지 총 대여 횟수가 5회 이상인 자동차들에 대해서 해당 기간 동안의 월별 자동차 ID 별 총 대여 횟수(컬럼명: RECORDS) 리스트를 출력하는 SQL문을 작성해주세요. 결과는 월을 기준으로 오름차순 정렬하고, 월이 같다면 자동차 ID를 기준으로 내림차순 정렬해주세요. 특정 월의 총 대여 횟수가 0인 경우에는 결과에서 제외해주세요.</p>
<p>📌 <span style="background-color:pink">날짜 비교 시</span> &gt; TO_CHAR이 아닌 TO_DATE를 사용한다 </p>
<blockquote>
<p>TO_DATE(&quot;날짜&quot;,&quot;형식)
 예)  TO_DATE(&quot;2020-02-05&quot;,&quot;YYYY-MM-DD&quot;)</p>
</blockquote>
<p>📌 <span style="background-color:pink">BETWEEN 사용 시</span> &gt; 컬럼명 BETWEEN 값 AND 값</p>
<blockquote>
<p>START_DATE BETWEEN 비교1 AND 비교2</p>
</blockquote>
<p><span style="color:#00AAFF">[정답]</span></p>
<pre><code class="language-sql">SELECT TO_NUMBER(TO_CHAR(START_DATE, &#39;MM&#39;)) AS MONTH
    , CAR_ID
    , COUNT(CAR_ID) AS RECORDS
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE CAR_ID IN ( -- CAR_ID를 조건을 걸어야 함 (기간 및 횟수)
    SELECT CAR_ID
    FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
    WHERE TO_CHAR(START_DATE,&#39;YYYYMM&#39;) BETWEEN &#39;202208&#39; AND &#39;202210&#39;
    GROUP BY CAR_ID
    HAVING COUNT(CAR_ID) &gt; 4
) AND TO_CHAR(START_DATE,&#39;YYYYMM&#39;) BETWEEN &#39;202208&#39; AND &#39;202210&#39;
GROUP BY TO_CHAR(START_DATE, &#39;MM&#39;), CAR_ID
HAVING COUNT(CAR_ID) &gt; 0
ORDER BY TO_CHAR(START_DATE, &#39;MM&#39;), CAR_ID DESC;</code></pre>
<hr>
<h3 id="02-카테고리-및-저자별-특정-월-매출액-구하기">02. 카테고리 및 저자별 특정 월 매출액 구하기</h3>
<p><span style="color:#00AAFF">[문제]</span>
2022년 1월의 도서 판매 데이터를 기준으로 저자 별, 카테고리 별 매출액(TOTAL_SALES = 판매량 * 판매가) 을 구하여, 저자 ID(AUTHOR_ID), 저자명(AUTHOR_NAME), 카테고리(CATEGORY), 매출액(SALES) 리스트를 출력하는 SQL문을 작성해주세요. 결과는 저자 ID를 오름차순으로, 저자 ID가 같다면 카테고리를 내림차순 정렬해주세요.</p>
<p><span style="color:#00AAFF">[정답]</span></p>
<pre><code class="language-sql">SELECT B.AUTHOR_ID
    , A.AUTHOR_NAME
    , B.CATEGORY
    , SUM(BS.SALES * B.PRICE) AS TOTAL_SALES
FROM BOOK B
    JOIN AUTHOR A ON  B.AUTHOR_ID = A.AUTHOR_ID
    JOIN BOOK_SALES BS ON B.BOOK_ID = BS.BOOK_ID
WHERE TO_CHAR(SALES_DATE,&#39;YYYYMM&#39;) LIKE &#39;202201%&#39;
GROUP BY A.AUTHOR_ID, A.AUTHOR_NAME, B.CATEGORY
ORDER BY A.AUTHOR_ID, B.CATEGORY DESC;</code></pre>
<p>여기서 틀린 게 뭐게요 놀랍게도 SELECT에선 B.AUTHOR_ID를 사용하고 GROUP BY에선 A.AUTHOR_ID를 사용해서 틀림 .. 이것도 맞춰줘야 하는 구나.. </p>
<hr>
<h3 id="03-카테고리별-가장-비싼-가격이-얼마인지-구하기">03. 카테고리별 가장 비싼 가격이 얼마인지 구하기</h3>
<p><span style="color:#00AAFF">[문제]</span>
FOOD_PRODUCT 테이블에서 식품분류별로 가격이 제일 비싼 식품의 분류, 가격, 이름을 조회하는 SQL문을 작성해주세요. 이때 식품분류가 &#39;과자&#39;, &#39;국&#39;, &#39;김치&#39;, &#39;식용유&#39;인 경우만 출력시켜 주시고 결과는 식품 가격을 기준으로 내림차순 정렬해주세요.</p>
<p>📌 제품별로 가장 비싼 가격을 구해야 하니까 MAX를 사용할 수 없음 -&gt; 서브쿼리 필요</p>
<p>난 뭔가 서브쿼리에 대한 이해가 부족한 것 같다... </p>
<p>만약 서브쿼리를 사용하지 않고, MAX를 구한다면 식용유가 4개 나온다.
서브쿼리를 사용한다면 각 카테고리별로 가장 비싼 제품의 정보를 명확히 추출할 수 있어서 가장 비싼 가격의 식용유 1개만 추출할 수 있다</p>
<blockquote>
<p>즉 서브쿼리에서 카테고리별 최대 가격을 구하고, 이를 원본 테이블과 조인하여 해당 가격을 가진 제품명만 가져올 수 있다.</p>
</blockquote>
<p>또 하나의 궁금한 점
<span style="color:#5F00FF">FROM에서 사용하는 거랑 WHERE에서 사용하는 거의 차이점을 뭘까?</span></p>
<p>🍥 FROM의 경우
<span style="background-color:#D4F4FA">목적</span> : 서브쿼리 결과를 테이블처럼 다룰 수 있습니다. 이 경우 서브쿼리는 임시 테이블로 간주되어 외부 쿼리에서 사용할 수 있습니다.
<span style="background-color:#D4F4FA"> 구조</span> : 이 방식을 사용하면 복잡한 계산이나 집계 결과를 미리 계산하여, 이후의 메인 쿼리에서 이를 조작하거나 필터링할 수 있습니다.</p>
<p>🍥 WHERE의 경우
<span style="background-color:#D4F4FA">목적</span> : 주 쿼리의 조건을 필터링하기 위해 사용합니다. 서브쿼리 결과를 조건으로 사용하여 특정 행을 선택하는 방식입니다.
<span style="background-color:#D4F4FA">구조</span> : 이 방식은 서브쿼리가 특정 조건을 만족하는지 확인하는 데 초점을 맞춥니다</p>
<p><span style="color:#00AAFF">[정답]</span></p>
<pre><code class="language-sql">SELECT FP.CATEGORY
    , FP.PRICE
    , FP.PRODUCT_NAME
FROM FOOD_PRODUCT FP
JOIN (
    SELECT CATEGORY
        , MAX(PRICE) AS MAX_PRICE
--        , PRODUCT_NAME
    FROM FOOD_PRODUCT
    WHERE CATEGORY IN (&#39;과자&#39;, &#39;국&#39;, &#39;김치&#39;, &#39;식용유&#39;)
    GROUP BY CATEGORY -- PRODUCT_NAME까지 그룹화해서 여러개 나옴
) SFP ON FP.CATEGORY = SFP.CATEGORY -- JOIN 절에서 AS 사용할 필요 없다.
WHERE FP.PRICE = SFP.MAX_PRICE;
</code></pre>
<hr>
<h3 id="04-자동차-대여-중--대여가능-구분하기">04. 자동차 대여 중 / 대여가능 구분하기</h3>
<p><span style="color:#00AAFF">[문제]</span>
CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블에서 2022년 10월 16일에 대여 중인 자동차인 경우 &#39;대여중&#39; 이라고 표시하고, 대여 중이지 않은 자동차인 경우 &#39;대여 가능&#39;을 표시하는 컬럼(컬럼명: AVAILABILITY)을 추가하여 자동차 ID와 AVAILABILITY 리스트를 출력하는 SQL문을 작성해주세요. 이때 반납 날짜가 2022년 10월 16일인 경우에도 &#39;대여중&#39;으로 표시해주시고 결과는 자동차 ID를 기준으로 내림차순 정렬해주세요.</p>
<p>📝 진짜 고민됐던 건 그거임 .. 이게 데이터가 600개 있는데 DISTINCT로 뽑아야 할 건 알겠는데 END_DATE가 MAX인 걸 뽑는 게 맞나..? 이게 고민이였어 ㅠ</p>
<hr>
<h3 id="05-오라클의-비밀">05. 오라클의 비밀</h3>
<p>걍 SQL이랑 달랐던 비밀을 말해 보겟음
💡 별칭 입력 시, 보통 &#39;&#39;를 사용하지만 공백이 포함되면 반드시 &quot;&quot; 사용</p>
<hr>
<h3 id="06-총-거래-금액">06. 총 거래 금액</h3>
<p><span style="color:#00AAFF">[문제]</span>
USED_GOODS_BOARD와 USED_GOODS_USER 테이블에서 완료된 중고 거래의 총금액이 70만 원 이상인 사람의 회원 ID, 닉네임, 총거래금액을 조회하는 SQL문을 작성해주세요. 결과는 총거래금액을 기준으로 오름차순 정렬해주세요.</p>
<p>📝 고민인 게 그거임.. 총거래금액을 구할 때 서브쿼리를 사용해서 해야 할 것 같은데 SELECT에서 해야 할지 WHERE에서 해야 할지.. </p>
<p>-&gt; 바보인가.. 그룹화된 값을 사용하고 싶으면 HAVING을 사용하면 됨</p>
<pre><code class="language-sql">--  완료된 중고 거래의 총금액이 70만 원 이상인 사람의 회원 ID, 닉네임, 총거래금액을 조회
--  총거래금액을 기준으로 오름차순

SELECT USER_ID
    , NICKNAME
    , SUM(PRICE) AS TOTAL_SALES
FROM USED_GOODS_BOARD B
JOIN USED_GOODS_USER U ON B.WRITER_ID = U.USER_ID
WHERE STATUS = &#39;DONE&#39; 
GROUP BY USER_ID, NICKNAME
HAVING SUM(PRICE) &gt;= 700000
ORDER BY TOTAL_SALES</code></pre>
<hr>
<h3 id="07-같은-아이디가-두-개-이상인-사람을-추출">07. 같은 아이디가 두 개 이상인 사람을 추출</h3>
<p>움... 서브쿼리 써야 하는 건가 </p>
<pre><code class="language-sql">SELECT P.ID
    , P.NAME
    , P.HOST_ID
FROM PLACES P
JOIN ( -- 여러개인 거 추출해서 그 HOST_ID 거만 추출해서 뽑아내기!
    SELECT HOST_ID
    FROM PLACES
    GROUP BY HOST_ID
    HAVING COUNT(*) &gt; 1
) SP ON P.HOST_ID = SP.HOST_ID
WHERE P.HOST_ID = SP.HOST_ID;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQL] SELECT문 헷갈리는 것들 정리]]></title>
            <link>https://velog.io/@oss_nue/SELECT%EB%AC%B8-%ED%97%B7%EA%B0%88%EB%A6%AC%EB%8A%94-%EA%B2%83%EB%93%A4-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@oss_nue/SELECT%EB%AC%B8-%ED%97%B7%EA%B0%88%EB%A6%AC%EB%8A%94-%EA%B2%83%EB%93%A4-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sat, 21 Sep 2024 08:18:14 GMT</pubDate>
            <description><![CDATA[<h3 id="01-날짜-출력-형식-바꾸기">01. 날짜 출력 형식 바꾸기</h3>
<p>| 2020-03-01 00:00:00 --&gt; 2020-03-01 바꾸기 |
<code>TO_CHAR(테이블명, &#39;YYYY-MM-DD&#39;)</code></p>
<hr>
<h3 id="02-재구매한-상품-번호와-회원-구하기">02. 재구매한 상품 번호와 회원 구하기</h3>
<p><span style="color:#00aaff">[문제]</span>
ONLINE_SALE 테이블에서 동일한 회원이 동일한 상품을 재구매한 데이터를 구하여, 재구매한 회원 ID와 재구매한 상품 ID를 출력하는 SQL문을 작성해주세요. 결과는 회원 ID를 기준으로 오름차순 정렬해주시고 회원 ID가 같다면 상품 ID를 기준으로 내림차순 정렬해주세요.</p>
<pre><code class="language-sql">SELECT USER_ID
    , PRODUCT_ID
FROM ONLINE_SALE
WHERE PRODUCT_ID == (
    SELECT PRODUCT_ID
    FROM ONLINE_SALE
);</code></pre>
<p>이렇게 말도 안 되게 풀었는데 <span style="color:red"> 같은 수/글자가 얼마나 있는지 알려면 GROUP BY</span>를 써야지 멍청아!</p>
<p><span style="color:#00aaff">[정답]</span></p>
<pre><code class="language-sql">SELECT USER_ID
    , PRODUCT_ID
FROM ONLINE_SALE
GROUP BY USER_ID
        ,PRODUCT_ID
HAVING COUNT(*) &gt; 1
ORDER BY USER_ID, PRODUCT_ID DESC;</code></pre>
<hr>
<h3 id="03-날짜-형식-데이터에서-값-뽑아오기">03. 날짜 형식 데이터에서 값 뽑아오기</h3>
<p>| DATE형식 데이터(예. 2020-03-18)에서 3월 생일인 사람만 출력하기 |</p>
<blockquote>
<p>[첫번째 풀이 방법]</p>
</blockquote>
<ol>
<li>WHERE 절에서 바로 TO_CHAR(컬럼명, &#39;MM&#39;)으로 구분</li>
</ol>
<p>-&gt; 저장된 날짜 값에서 월(month) 부분을 추출하여 문자열로 변환하는 기능을 수행
[두번째 풀이 방법]</p>
<ol>
<li>TO_CHAR(컬럼명, 형식)으로 문자열로 만든다.</li>
<li>EXTRACT(MONTH FROM 컬럼명) = &#39;03&#39;</li>
</ol>
<p>중요한 건 <span style="color:red"> 날짜를 문자 타입으로 바꾸기 ! </span></p>
<hr>
<h3 id="04-조인">04. 조인</h3>
<p><span style="color:#00aaff">[문제]</span>
REST_INFO와 REST_REVIEW 테이블에서 서울에 위치한 식당들의 식당 ID, 식당 이름, 음식 종류, 즐겨찾기수, 주소, 리뷰 평균 점수를 조회하는 SQL문을 작성해주세요. 이때 리뷰 평균점수는 소수점 세 번째 자리에서 반올림 해주시고 결과는 평균점수를 기준으로 내림차순 정렬해주시고, 평균점수가 같다면 즐겨찾기수를 기준으로 내림차순 정렬해주세요.</p>
<p>제가 모르는 것 같은 건... 그 이게 그룹화를 해서 평균을 내야 하는지가 고민이거든요
근데 해결했어요 
<span style="color:red"> GROUP BY에 있는 건 모두 SELECT에 있어야 할 것 !!!!!</span></p>
<p><span style="color:#00aaff">[정답]</span></p>
<pre><code class="language-sql">SELECT RI.REST_ID
    , REST_NAME
    , FOOD_TYPE
    , FAVORITES
    , ADDRESS
    , ROUND(AVG(REVIEW_SCORE),2) SCORE
FROM REST_INFO RI JOIN REST_REVIEW RR
ON RI.REST_ID = RR.REST_ID
WHERE ADDRESS LIKE &#39;서울%&#39;
GROUP BY RI.REST_ID, RI.REST_NAME, RI.FOOD_TYPE, RI.FAVORITES, RI.ADDRESS 
ORDER BY SCORE DESC, FAVORITES DESC;</code></pre>
<hr>
<h3 id="05-가장-큰-것-10개만-추출">05. 가장 큰 것 10개만 추출</h3>
<p><span style="color:#00aaff">[문제]</span>
FISH_INFO 테이블에서 가장 큰 물고기 10마리의 ID와 길이를 출력하는 SQL 문을 작성해주세요. 결과는 길이를 기준으로 내림차순 정렬하고, 길이가 같다면 물고기의 ID에 대해 오름차순 정렬해주세요. 단, 가장 큰 물고기 10마리 중 길이가 10cm 이하인 경우는 없습니다.</p>
<p>갑자기 헷갈림.. MAX? LIMIT? 먼가 MAX는 하나만 뽑을 것같고 LIMIT은 걍 10개인 느낌.. 갑자기 이거적다가 깨달았음 ORDER BY 쓰고 LIMIT쓰기  --&gt; ORACLE은 안 된다고 하네요 ^...^</p>
<p>알고 보니 MYSQL 문제 였다는</p>
<p><span style="color:#00aaff">[정답]</span></p>
<pre><code class="language-sql">SELECT ID
    , LENGTH
FROM FISH_INFO
WHERE LENGTH &gt; 10
ORDER BY LENGTH DESC, ID ASC LIMIT 10;</code></pre>
<hr>
<p>오랜만에 해서 진짜 기본도 다 까먹었네 큰일이슈</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQL] 한 해에 잡은 물고기 수 구하기]]></title>
            <link>https://velog.io/@oss_nue/SQL-%ED%95%9C-%ED%95%B4%EC%97%90-%EC%9E%A1%EC%9D%80-%EB%AC%BC%EA%B3%A0%EA%B8%B0-%EC%88%98-%EA%B5%AC%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@oss_nue/SQL-%ED%95%9C-%ED%95%B4%EC%97%90-%EC%9E%A1%EC%9D%80-%EB%AC%BC%EA%B3%A0%EA%B8%B0-%EC%88%98-%EA%B5%AC%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 06 Aug 2024 11:34:51 GMT</pubDate>
            <description><![CDATA[<h3 id="1-문제">1. 문제</h3>
<p> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/298516">https://school.programmers.co.kr/learn/courses/30/lessons/298516</a></p>
<pre><code>FISH_INFO 테이블에서 2021년도에 잡은 물고기 수를 출력하는 SQL 문을 작성해주세요.
이 때 컬럼명은 &#39;FISH_COUNT&#39; 로 지정해주세요.</code></pre><p>&lt;표 - FIST_INFO&gt;</p>
<table>
<thead>
<tr>
<th>ID</th>
<th align="left">FISH_TYPE</th>
<th align="center">LENGTH</th>
<th align="right">TIME</th>
</tr>
</thead>
<tbody><tr>
<td>0</td>
<td align="left">0</td>
<td align="center">13.37</td>
<td align="right">2021/12/04</td>
</tr>
<tr>
<td>1</td>
<td align="left">0</td>
<td align="center">50</td>
<td align="right">2020/03/07</td>
</tr>
<tr>
<td>2</td>
<td align="left">0</td>
<td align="center">40</td>
<td align="right">2020/03/07</td>
</tr>
<tr>
<td>3</td>
<td align="left">1</td>
<td align="center">43.33</td>
<td align="right">2022/03/09</td>
</tr>
<tr>
<td>4</td>
<td align="left">1</td>
<td align="center">NULL</td>
<td align="right">2022/04/08</td>
</tr>
<tr>
<td>5</td>
<td align="left">2</td>
<td align="center">NULL</td>
<td align="right">2021/04/28</td>
</tr>
</tbody></table>
<hr>
<h3 id="2-시도한-풀이">2. 시도한 풀이</h3>
<p><span style="background-color:#D4F4FA"> <strong>첫번째 실행</strong> </span></p>
<pre><code class="language-sql">select count(ID) as &#39;FISH_COUNT&#39;
from fish_info
where substring(time, 0,4) = &#39;2021&#39;;</code></pre>
<p>--&gt; <span style="color:red"> 실패</span></p>
<p>이유) substring이 아니라 substr이고, 0부터가 아니라 1부터 해야 함 !</p>
<p><span style="background-color:#D4F4FA"> <strong>두번째 실행</strong> </span></p>
<pre><code class="language-sql">SELECT COUNT(*) AS FISH_COUNT
FROM FISH_INFO
WHERE SUBSTR(TIME,1,4) = 2021</code></pre>
<p>--&gt; <span style="color:blue"> 성공 ! </span></p>
<hr>
<h3 id="3-오답-및-다른-방식으로-풀기">3. 오답 및 다른 방식으로 풀기</h3>
<h4 id="1-오답">1) 오답</h4>
<p>일단 처음 시도했을 때 틀렸던 이유는 substring이라는 건 java에만 있는 건데 sql에 써버림
ㅠㅠ 넘 헷갈리잔아 ! 그리고 오타 주의하자 ^_^.. </p>
<blockquote>
<p>SUBSTR(&quot;데이터열&quot;, &quot;시작위치&quot;, &quot;길이&quot;)</p>
</blockquote>
<h4 id="2-다른-방식으로-푸는-방법">2) 다른 방식으로 푸는 방법</h4>
<pre><code class="language-sql">SELECT COUNT(*) AS FISH_COUNT
FROM FIST_INFO
WHERE YEAR(TIME) = 2021    </code></pre>
<p>YEAR(&quot;시간열&quot;)을 써서 년도만 출력하는 거 완~전 까먹었었음 
그외에도 MONTH(), DAY()도 있다는 거 잊지 말자 </p>
<hr>
<h3 id="4-총-소감">4. 총 소감</h3>
<p>오랜만에 하려니까 진짜 다 까먹었다 감 익혀보도록 열시미 하쟈.. 아자아자아앚아자</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[번외 ) 자바 정리]]></title>
            <link>https://velog.io/@oss_nue/%EB%B2%88%EC%99%B8-%EC%9E%90%EB%B0%94-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@oss_nue/%EB%B2%88%EC%99%B8-%EC%9E%90%EB%B0%94-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Mon, 08 Apr 2024 12:46:04 GMT</pubDate>
            <description><![CDATA[<p>하나의 게시글로 올리기엔 짜잘하지만
공부 필요한 것들 ! </p>
<hr>
<h3 id="🤍-1-변수-위치에-따른-분류">🤍 1. 변수 위치에 따른 분류</h3>
<p> <code>1) 로컬 변수</code></p>
<p> ~ <span style = "background-color : #FFFFE4">메서드 내부에 선언된 변수 + if문, for문 내에서 선언된 변수</span>
 ~ for문의 소괄호 내에서 제어되는 변수 또한 로컬변수
 ~ 메서드 파라미터 내 변수
 ~ <span style = "background-color : #FFFFE4">선언된 위치부터 소속된 괄호가 끝낼 때까지만 존재</span>한다.
 ~ 반드시 초기화 후 사용한다</p>
<p> <code>2) 멤버 변수</code></p>
<p> ~ <span style = "background-color : #FFFFE4">클래스 내부 및 메서드 외부에 존재하는 변수</span>
 ~ 클래스 내의 생성자나 메서드에서 접근 가능
 ~ 초기화하지 않을 경우, 기본값으로 자동 초기화된다
 ~ 종류로는 인스턴스 멤버 변수와 클래스 멤버 변수가 존재한다</p>
<p> <code>2-1) 인스턴스 멤버 변수</code>
 ~ <span style = "background-color : #FFFFE4">접근제한자 뒤에 아무것도 붙지 않은 변수</span>
 ~ 인스턴스가 생성될 때마다 각 공간이 새로 할당되므로 인스턴스가 다르면 인스턴스 멤버변수가 다르다
 ~ <strong>인스턴스가 생성되면</strong> 메모리에 로딩되고 인스턴스 제거 시 메모리에서 제거된다.</p>
<p> <code>2-2) 클래스 (정적) 멤버 변수</code>
 ~ <span style = "background-color : #FFFFE4">static 키워드가 붙은 변수</span></p>
<hr>
<h3 id="🤍-2-접근-제한자">🤍 2. 접근 제한자</h3>
<p> <code>1) public</code> : 모든 클래스에서 접근 가능 (제한 없음)
 <code>2) protected</code> : 같은 패키지 또는 다른 패키지더라도 상속 관계에 있는 서브클래스만 접근 가능 
 <code>3) default</code> : 같은 패키지에서만 가능
 <code>4) private</code> : 자신의 클래스에서만 접근 가능</p>
<hr>
<h3 id="🤍-3-string-클래스">🤍 3. String 클래스</h3>
<p>  ~ 리터럴로 생성했을 때 문자열이 중복되는 경우, 가리키는 주소값은 같다. --&gt; 문자를 비교하고 싶으면 equals() 사용</p>
<p><code>사용 문자열</code></p>
<pre><code class="language-java">String s1 = &quot;Hello World&quot;;
String s2 = &quot;    Person  !&quot;;
String s3 = &quot;집/가고/싶다&quot;;

System.out.println()은 생략하겠습니다
</code></pre>
<p><code>1) 길이</code></p>
<pre><code class="language-java">s1.length();  // 결과 11</code></pre>
<p><code>2) 비교</code></p>
<pre><code class="language-java">// 대소문자까지 비교
s1.equals(&quot;HELLO WORLD&quot;); // 결과 false -&gt; 대소문자 구분한다

// 대소문자 구분 무시하고 비교
s1.equalsIgnoreCase(&quot;HELLO WORLD&quot;);</code></pre>
<p><code>3) 추출</code></p>
<pre><code class="language-java">// 세번째 문자 추출
s1.charAt(3); // 결과 l

// 문자열 추출
s1.substring(6) // 결과 World
s1.substring(6,9) // 결과 Wor --&gt; 6포함 9포함 x</code></pre>
<p><code>4) 결합</code></p>
<pre><code class="language-java">s1.concat(&quot;!&quot;); // 결과 Hello World!</code></pre>
<p><code>5) 검색</code></p>
<pre><code class="language-java">s1.indexOf(&#39;e&#39;); // 결과 2
s1.indexOf(&quot;World&quot;); // 결과 6 --&gt; 시작지점 리턴</code></pre>
<p><code>6) 치환</code></p>
<pre><code class="language-java">s1.replace(&#39;l&#39;, &#39;*&#39;); // 결과 He**o Wor*d</code></pre>
<p><code>7) 대소문자 및 소문자로 변경</code></p>
<pre><code class="language-java"> s1.toUpperCase(); // 대문자로 변경
 s1.toLowerCase(); // 소문자로 변경</code></pre>
<p><code>8) 공백 제거 (문자열 앞뒤 공백만 제거된다)</code></p>
<pre><code class="language-java">s2.trim();</code></pre>
<p><code>9) 문자 나누기</code></p>
<pre><code class="language-java">String [] sub = s3.split(&quot;/&quot;);

for (String str : sub) {
    System.out.println(str);
} 

/* 
&lt; 결과 &gt;
집
가고
싶다
*/</code></pre>
<p><code>10) 포함 여부</code></p>
<pre><code class="language-java">s1.contatins(&quot;안녕&quot;); // 결과 false</code></pre>
<hr>
<p>예시
<code>문제</code></p>
<blockquote>
<p>str = &quot;주소:부산 해운대구 세실로69번길 5 연하남, 층수: 1층, 번호: 010-2222-1111&quot;;
위의 문장에서 중요한 부분만 추출하시오</p>
</blockquote>
<p><code>코드</code></p>
<pre><code class="language-java">String str = &quot;주소:부산 해운대구 세실로69번길 5 연하남, 층수: 1층, 번호: 010-2222-1111&quot;;
str.split(&quot;:&quot;)

for (String sArr : str.split(&quot;,&quot;)) {
            System.out.println(sArr.split(&quot;:&quot;)[1].trim());
}

</code></pre>
<hr>
<h3 id="🤍-4-난수-발생">🤍 4. 난수 발생</h3>
<p><code>방법 1</code></p>
<pre><code class="language-java">Random r = new Random(); // 객체 생성
int num; // 난수 저장할 변수 선언

num = r.nextInt(10); // 0~9 난수 발생</code></pre>
<p><code>방법2</code></p>
<pre><code class="language-java">Math.random() // 0.0 &lt;= x &lt;= 1.0
Math.random() * 10 // 0.0 &lt;= x &lt;= 10.0</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[오류처리 : try-catch]]></title>
            <link>https://velog.io/@oss_nue/%EC%98%A4%EB%A5%98%EC%B2%98%EB%A6%AC-try-catch</link>
            <guid>https://velog.io/@oss_nue/%EC%98%A4%EB%A5%98%EC%B2%98%EB%A6%AC-try-catch</guid>
            <pubDate>Mon, 08 Apr 2024 12:26:50 GMT</pubDate>
            <description><![CDATA[<h3 id="🤍-1-기본-문법">🤍 1. 기본 문법</h3>
<p><code>예외가 1개일 경우</code></p>
<blockquote>
<p>try {
    // 일반 코드 &amp; 예외 발생 가능성이 있는 코드
} catch (예외클래스명 변수명) {
     // 예외가 발생할 경우 처리할 코드
}</p>
</blockquote>
<p><code>예외가 복수개일 경우</code></p>
<blockquote>
<p>try {
          예외발생1코드
          예외발생2코드
         예외발생3코드
          예외발생4코드
          } catch (예외발생1클래스 변수명){
          } catch (예외발생2클래스 변수명){
          } catch (예외발생3클래스 | 예외발생4클래스 변수명){
          } catch (Exception e){
           위의 모든 예외가 일치하지 않을 경우 나머지 예외를 모두 처리하는 코드
           }</p>
</blockquote>
<p><code>finally 사용할 경우</code>
-&gt; 예외가 발생하더라도 실행된다. try 안에서 return문을 넣어도 실행됨</p>
<blockquote>
<p> try {
    // 일반 코드 &amp; 예외 발생 가능성이 있는 코드
} catch (예외클래스명 변수명) {
     // 예외가 발생할 경우 처리할 코드
} finally {
    // 예외가 발생하든 안하든 실행될 코드
}</p>
</blockquote>
<h3 id="🤍-2-예외-종류">🤍 2. 예외 종류</h3>
<blockquote>
<p>1) Complie Checked Exception
 컴파일 시점에서 예외 발생 가능성 판별 가능 (예외 처리 강제성 있음)</p>
</blockquote>
<p>예시) IOException, SQLException, ClassNotFoundException
--&gt; try - catch 필수</p>
<blockquote>
<p>2) Compile Unchecked Exception
컴파일 시점에서 예외 발생 가능성 판별 불가능하며 실행 시점에서 예외 발생 여부 판별</p>
</blockquote>
<p>예시) RuntimeException, ArithmeticException, ArrayIndexOutOfBoundsException, NullPointerException, ClassCastException</p>
<h3 id="🤍-3-예외-처리에-대한-위임--throws">🤍 3. 예외 처리에 대한 위임 (= throws)</h3>
<blockquote>
<p>-예외 발생 시 예외가 발생한 메서드에서 직접 처리하는 것이 아니라 메서드 호출한 곳에서 예외처리할 수 있도록 위임하는 것
-각각의 예외클래스를 따로 기술하거나 상위 타입 예외클래스 하나만으로 대체 가능</p>
</blockquote>
<p>예1) throws RuntimeException 기술 시
 RuntimeException 계열 예외는 외부로 던지고, 나머지 예외는 직접 예외 처리
예2) throws Exception 기술 시 모든 예외를 외부로 던짐</p>
<h3 id="🤍-4-사용자-정의-예외-발생">🤍 4. 사용자 정의 예외 발생</h3>
<blockquote>
<p>미리 정해진 예외가 아닌 개발자가 지정한 상황에서 예외 발생시키는 것</p>
</blockquote>
<p><code>예시</code></p>
<pre><code class="language-java">public static void main(String[] args) {
    int age = 10000; // 1 ~ 150살까지만 입력 가능하다고 가정
    try {
        na2(age);
    } catch (Exception e){
        e.printStackTrace();
    }

    System.out.println(&quot;프로그램 종료됩니다&quot;);
}
public static void na2(int age) throws Exception {
    if (age &lt; 1 || age &gt; 151) {
        throw new Exception(&quot;나이 입력 오류&quot;); // 객체 생성하여 던진다
    }
}</code></pre>
<blockquote>
<p>뿐만 아니라 예외 발생 클래스 또한 지정이 가능하다</p>
</blockquote>
<p><code>예시</code>
*예외 클래스 정의</p>
<pre><code class="language-java">class InvaildAgeInputException extends Exception {
    public InvaildAgeInputException(String str) {
        super(str);
    }
} </code></pre>
<p>*불러오기</p>
<pre><code class="language-java">public static void main(String[] args) {
    int age = 10000; // 1 ~ 150살까지만 입력 가능하다고 가정
    try {
        na2(age);
    } catch (Exception e){
        e.printStackTrace();
    }

    System.out.println(&quot;프로그램 종료됩니다&quot;);
}
public static void na2(int age) throws Exception {
    if (age &lt; 1 || age &gt; 151) {
        throw new InvaildAgeInputException(&quot;나이 입력 오류&quot;);
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[인터페이스 : Interface]]></title>
            <link>https://velog.io/@oss_nue/%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-Interface</link>
            <guid>https://velog.io/@oss_nue/%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-Interface</guid>
            <pubDate>Thu, 04 Apr 2024 12:33:44 GMT</pubDate>
            <description><![CDATA[<h3 id="🤍-01-인터페이스-정의">🤍 01. 인터페이스 정의</h3>
<blockquote>
<p>추상 클래스와 마찬가지로 추상된 틀을 만들어 개발의 도움을 주는 것</p>
</blockquote>
<h3 id="🤍-02-인터페이스-특징">🤍 02. 인터페이스 특징</h3>
<blockquote>
<p>1) 클래스가 아니므로 class 키워드 대신 interface 사용
2) <span style = "background-color : #FFD9FA">추상메서드와 상수만</span> 가진다
 -&gt;public abstract가 붙은 추상메서드로 취급 (생략 가능)
 -&gt;public static final이 붙은 상수로 취급 (생략 가능)
3) <span style = "background-color : #FFD9FA">객체 생성 불가능</span>
-&gt; 단, 참조타입으로는 가능
4) 코드의 통일성이 향상됨
5) <span style = "background-color : #FFD9FA">다중 구현</span> 가능</p>
</blockquote>
<p>그렇다면 도대체 이게 추상클래스와 다른 게 뭘까?</p>
<h3 id="🤍-03-추상클래스와의-차이점">🤍 03. 추상클래스와의 차이점</h3>
<blockquote>
<p><span style = "color : #4641D9"><strong>추상 클래스</strong></span> : 일반 메서드와 변수 가질 수 있다. / 다중 상속 불가능
<span style = "color : #4641D9"><strong>인터페이스</strong></span> : 추상 메서드와 상수만 가진다 / 다중 구현 가능</p>
</blockquote>
<p>즉, 인터페이스는 여러 클래스에서 공통으로 사용하는 기능을 정의하는 데 사용되며, 추상 클래스는 클래스들 간의 공통된 특성을 정의하는 데 사용된다.</p>
<p>굳이 굳이 추상클래스가 있음에도 인터페이스를 사용하는 이유는 <span style = "background-color : #FFD9FA">&#39;다중 구현&#39;</span> 때문인 경우가 많다. </p>
<p>추상클래스를 상속받게 되면 다른 클래스를 상속 받을 수 없는 경우가 존재한다. 이런 경우를 해결하고자 인터페이스를 사용한다.</p>
<h3 id="🤍-04-인터페이스의-장점">🤍 04. 인터페이스의 장점</h3>
<blockquote>
<ol>
<li><span style = "color : #4641D9">구현의 강제성 부여</span> : 인터페이스를 구현하는 서브크래스에서 메서드 정의 필수</li>
<li><span style = "color : #4641D9">모듈의 교체 용이</span> : 특정 서브클래스가 추가되더라도 공통 코드 변경 필요없이 사용 가능</li>
<li><span style = "color : #4641D9">상속 관계가 없는 객체끼리 관계 부여 가능</span> : 다형성 활용 가능</li>
<li><span style = "color : #4641D9">개발 기간 단축</span> : 모듈 간 독립적 프로그래밍 가능</li>
</ol>
</blockquote>
<hr>
<h3 id="🤍-05-인터페이스-예시">🤍 05. 인터페이스 예시</h3>
<h4 id="💗-1-모듈의-교체-용이">💗 1) 모듈의 교체 용이</h4>
<p><code>인터페이스 및 서브클래스 정의</code></p>
<pre><code class="language-java"></code></pre>
<p>나중에 수정할게용 .. 급한 것부터 해야즤 </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[추상화 : Abstract]]></title>
            <link>https://velog.io/@oss_nue/%EC%B6%94%EC%83%81%ED%99%94-Abstract</link>
            <guid>https://velog.io/@oss_nue/%EC%B6%94%EC%83%81%ED%99%94-Abstract</guid>
            <pubDate>Mon, 01 Apr 2024 12:30:59 GMT</pubDate>
            <description><![CDATA[<h3 id="🤍-01-추상메서드-abstract-method">🤍 01 추상메서드 (Abstract Method)</h3>
<h4 id="💗-1-추상메서드-정의">💗 1. 추상메서드 정의</h4>
<blockquote>
<p>메서드 구현부(=바디 {})가 없는 메서드</p>
</blockquote>
<h4 id="💗-2-추상메서드-특징">💗 2. 추상메서드 특징</h4>
<blockquote>
<p>1) 바디가 없고 선언부만 존재하며 선언부 마지막에 세미콜론(;)을 붙여 준다
2) 실행할 수 있는 코드가 없기 때문에 외부에서 호출하면 안됨 -&gt; 서브클래스에서 구현한 후 호출
3) 메서드 정의 시 선언부의 접근제한자 뒤에 abstract 붙여서 정의
4) 슈퍼클래스에서 추상메서드로 선언하면 서브클래스는 <span style = "background-color : #FFFFD2">반드시 <strong>오버라이딩</strong> 필수</span></p>
</blockquote>
<h4 id="💗-3-추상메서드-형식">💗 3. 추상메서드 형식</h4>
<blockquote>
<p>[접근제한자] abstract 리턴타입 메서드명 ([매개변수]);</p>
</blockquote>
<p>*[대괄호]는 생략 가능</p>
<p><code>예시</code></p>
<pre><code class="language-java">public abstract void print();</code></pre>
<hr>
<h3 id="🤍-02-추상-클래스-abstract-class">🤍 02 추상 클래스 (Abstract Class)</h3>
<h4 id="💗-1-추상클래스-정의">💗 1. 추상클래스 정의</h4>
<blockquote>
<ul>
<li>객체를 생성할 수 없는 클래스</li>
</ul>
</blockquote>
<ul>
<li>new 연산자를 통해 생성자 호출 불가능</li>
</ul>
<h4 id="💗-2-추상클래스-특징">💗 2. 추상클래스 특징</h4>
<blockquote>
<p>1) 상속받는 서브클래스에서 반드시 오버라이딩 해야 한다.
2) 추상클래스는 추상메서드, 일반메서드, 생성자, 멤버변수를 <strong>모두</strong> 가질 수 있다 (인터페이스와 차이점)
3) 상속을 통해 서브클래스에서 사용 가능하며 업캐스팅을 통한 다형성 활용 가능
4) 추상메서드를 하나라도 가지는 클래스는 <span style = "background-color : #FFFFD2">추상클래스가 되어야 한다.</span></p>
</blockquote>
<h4 id="💗-3-추상클래스-형식">💗 3. 추상클래스 형식</h4>
<blockquote>
<p>abstract class 클래스명 {
    멤버변수 (인스턴스 멤버, 클래스&lt;static&gt;멤버변수)
    생성자
    메서드 (일반, 추상메서드)
}</p>
</blockquote>
<hr>
<h3 id="🤍-03-예시">🤍 03 예시</h3>
<p><code>1. 추상 메서드 및 추상 클래스 정의</code></p>
<pre><code class="language-java">abstract class A {
    //추상 메서드 정의
    public abstract void abstractMethod(); // 추상 메서드는 바디를 가질 수 없다

    // 멤버변수, 생성자, 일반 메서드를 가질 수 있다
    int x;
    static int y; //멤버변수

    public A() {} // 생성자

    public void Coding() {} // 일반 메서드
}</code></pre>
<p><code>2. 서브 클래스 정의</code>
-&gt; 추상 클래스를 상속 받은 클래스는 <span style = "background-color : #FFFFD2">반드시 오버라이딩</span> 해야 한다.
-&gt; <span style = "background-color : #FFFFD2">메서드 바디를 정의해야만 나머지 모든 상속이 적용된다</span>
-&gt; 만일, 오버라이딩 하지 않을 경우 서브클래스 또한 추상클래스로 변경한 후 이를 상속 받는 클래스에서 오버라이딩 해 줘야만 한다.</p>
<pre><code class="language-java">class B extends A {
    @Override
    public void abstractMethod() {
        System.out.println(&quot;추상메서드 오버라이딩&quot;);
    }
}</code></pre>
<p><code>3. 호출</code></p>
<pre><code class="language-java">// 서브클래스 객체 생성 및 호출
B sub = new B();
sub.abstactMethod(); // 출력 = 추상메서드 오버라이딩

// 추상클래스 호출
// 객체 생성은 안 되지만 다형성 활용은 가능하다 -&gt; 클래스 타입으로 접근 가능
A abs = sub;
abs.abstactMethod(); // 출력 = 추상메서드 오버라이딩</code></pre>
<p>업캐스팅 시 참조영역이 축소되지만, 추상메서드는 서브클래스에서 반드시 구현되었기 때문에 호출 가능</p>
<hr>
<h3 id="🤍-04-결론">🤍 04 결론</h3>
<p>-&gt; 추상을 하는 이유는 &#39;강제성&#39; 부여 + 코드의 통일성 때문이다. 하지만 상속은 하나밖에 되지 않기 때문에 다중 상속이 안 되는 불편함을 가지고 있다. 이러한 불편함을 해결하기 위해 &#39;인터페이스&#39;가 존재한다. </p>
<p>인터페이스는 다음 장에서 총총 .. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[참조 형변환 : casting]]></title>
            <link>https://velog.io/@oss_nue/%EC%B0%B8%EC%A1%B0-%ED%98%95%EB%B3%80%ED%99%98-casting</link>
            <guid>https://velog.io/@oss_nue/%EC%B0%B8%EC%A1%B0-%ED%98%95%EB%B3%80%ED%99%98-casting</guid>
            <pubDate>Tue, 19 Mar 2024 14:47:39 GMT</pubDate>
            <description><![CDATA[<p>자바 2차 관문 형변환 
넘 어렵더 〒▽〒
머리가 뒤죽박죽뒤죽박죽
그래도가보자고 쭈고</p>
<h3 id="🤍-1-참조-형변환">🤍 1. 참조 형변환</h3>
<blockquote>
<p><span style = "background-color : #FAF4C0">참조형끼리의 형변환</span> (상속 관계에서만 가능)
참조형 변수를 사용하여 다른 타입의 객체를 참조하기 위해 변환하는 것
<strong><em>업캐스팅</em></strong>과 <strong><em>다운캐스팅</em></strong>으로 분류된다</p>
</blockquote>
<h4 id="💙-1-업캐스팅-up-casting">💙 (1) 업캐스팅 (Up Casting)</h4>
<blockquote>
<p>부모클래스의 참조형 변수가 자식클래스의 객체를 참조하는 것
<img src="https://velog.velcdn.com/images/oss_nue/post/23391d92-cef3-4435-9cfc-5424e2069e4e/image.PNG" alt=""></p>
</blockquote>
<ul>
<li>특징 </li>
</ul>
<ol>
<li>자동 형변환 발생</li>
<li>참조영역의 축소 발생</li>
<li>다형성(Polymorphism) 활용 가능</li>
</ol>
<h4 id="💙-2-다운캐스팅-down-casting">💙 (2) 다운캐스팅 (Down Casting)</h4>
<blockquote>
<p>자식클래스의 참조형 변수가 부모 클래스의 객체를 참조하는 것
<img src="https://velog.velcdn.com/images/oss_nue/post/0f5e1828-d4fe-42d4-b263-6cfebf727533/image.PNG" alt=""></p>
</blockquote>
<ul>
<li>특징</li>
</ul>
<ol>
<li>강제 형변환 필수</li>
<li>참조영역의 확대 발생</li>
</ol>
<hr>
<h3 id="🤍-2-참조-형변환-예시">🤍 2. 참조 형변환 예시</h3>
<p><code>초등학생, 중학생, 고등학생 클래스를 만들어 보자</code></p>
<pre><code class="language-java">class 초등학생 {
    public void 덧셈() {
        System.out.println(&quot;덧셈을 하자&quot;);
    }
} // 초등학생 클래스

class 중학생 extends 초등학생 {
    public void 이차방정식() {
        System.out.println(&quot;이차방정식을 하자&quot;);
    }
} // 중학생 클래스

class 고등학생 extends 중학생 {
    public void 미적분() {
        System.out.println(&quot;미적분을 하자&quot;);
    }
} // 고등학생 클래스</code></pre>
<p><code>업캐스팅 예시: 초등학생 참조형 변수가 고등학생의 객체 참조</code></p>
<pre><code class="language-java">초등학생 초딩 = new 고등학생(); // 자동 형변환 발생

초딩.이차방정식(); // 오류 
초딩.미적분(); // 오류</code></pre>
<p>두 메서드가 오류가 나는 이유는 <span style = "background-color : #D9E5FF">&#39;참조영역의 축소&#39;</span> 때문이다.
초등학생은 이차방정식과 미적분을 풀지 못하는 것처럼 객체가 고등학생이더라도 데이터 타입이 초등학생이므로 초등학생이 할 수 있는 &lt;덧셈&gt;으로 참조영역이 축소가 된다.</p>
<p>이러한 오류를 없애기 위해서는 <span style = "background-color : #D9E5FF">다운캐스팅이 필요</span>하다. 초딩이라는 참조변수를 고등학생으로 다운캐스팅 해 주는 것이다.</p>
<p><code>위에 코드 오류 해결 -&gt; 다운캐스팅 예시</code></p>
<pre><code class="language-java">초등학생 초딩 = new 고등학생();
고등학생 고딩 = (고등학생)초딩;

고딩.이차방정식();
고딩.미적분();</code></pre>
<hr>
<p><code>다운캐스팅 주의할 점</code></p>
<pre><code class="language-java">고등학생 고딩 = (고등학생)new 초등학생();</code></pre>
<p>위와 같은 코드를 실행해 보면 오류가 난다.
이유는 <span style = "background-color : #D9E5FF">초등학생 객체가 생성할 때쯤에 고등학생 class가 메모리에 올라와 있지 않기 때문</span>이다.</p>
<p>이러한 오류를 해결하려면 <span style = "background-color : #FAF4C0">먼저 업캐스팅을 실행 후, 다운캐스팅</span>을 실행한다.</p>
<p><code>위에 코드 오류 해결 -&gt; 업캐스팅 후 다운캐스팅</code></p>
<pre><code class="language-java">초딩학생 초딩 = new 고등학생(); // 업캐스팅
고등학생 고딩 = (고등학생)초딩; // 다운캐스팅

고딩.덧셈();
고딩.이차방정식();
고딩.미적분(); // -&gt; 참조영역의 확장 발생</code></pre>
<hr>
<h3 id="🤍-3-참조-형변환-정리">🤍 3. 참조 형변환 정리</h3>
<p>간단한 문제로 참조 형변환 될 수 있는지 없는지 해석하면서 이를 정리해 보쟈</p>
<pre><code class="language-java">class A{}
class B extends A{}
class C extends A{}

class D extends B{}
class E extends B{}

class F extends C{}

class G extends F{}
class H extends F{}</code></pre>
<p>이러한 클래스들이 있을 때</p>
<pre><code class="language-java">C c = new F(); // 1번
E e = (E)c;    // 2번
G g = c;       // 3번
A a = c;       // 4번</code></pre>
<p>이 코드의 T/F를 알아보고 이유를 찾아보자</p>
<p>답은 
1번 T
2번 F
3번 F
4번 T</p>
<p>먼저 객체 F가 참조할 수 있는 변수는 <span style = "background-color : #FAF4C0">상속받은 A, B, C와 상속한 G,H</span>다.
<strong>1번</strong>은 F가 참조할 수 있는 변수에 C가 있으니 가능하다
<strong>2번</strong>은 F가 참조할 수 있는 변수에 E는 존재하지 않으니 형변환이 불가능하다
<strong>3번</strong>은 G 데이터 타입은 참조 변수로 존재하나 강제 형변환을 해 주지 않았으므로 틀렸다고 할 수 있다.
<strong>4번</strong>은 F가 참조할 수 있는 변수에 A가 존재하니 가능하다.</p>
<hr>
<p>ㅎ 암튼 끝남
잘 모르겠으면 처음에 선언된 객체가 뭔지를 보고 상속관계를 알아본 뒤 업캐스팅인지 다운캐스팅인지 알아보면 될듯 
암튼 형변환 끝 ( •̀ ω •́ )✧</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[캡슐화 : Encapsulation]]></title>
            <link>https://velog.io/@oss_nue/%EC%BA%A1%EC%8A%90%ED%99%94-Encapsulation</link>
            <guid>https://velog.io/@oss_nue/%EC%BA%A1%EC%8A%90%ED%99%94-Encapsulation</guid>
            <pubDate>Mon, 18 Mar 2024 14:00:00 GMT</pubDate>
            <description><![CDATA[<h3 id="🤍-1-캡슐화란">🤍 1) 캡슐화란?</h3>
<blockquote>
<p><span style = "background : #D4F4FA">객체 내부의 구조*를 외부로부터 숨기고</span> 메세지만으로 객체와 통신하도록 하는 것</p>
</blockquote>
<p> *객체 내부의 구조 : 멤버변수 및 메서드 처리과정 </p>
<h3 id="🤍-2-캡슐화-형식">🤍 2) 캡슐화 형식</h3>
<blockquote>
<ol>
<li>클래스 정의 시, <span style = "color :#4374D9 ">멤버변수</span>에 private 접근제한자를 사용하여 외부 접근 차단<ol start="2">
<li><span style = "color :#4374D9 ">메서드</span>는 public 접근제한자를 사용하여 선언된 Getter/Setter 메서드 정의 </li>
</ol>
-&gt; 간접적으로 객체 내의 멤버변수에 접근하도록 하기 위함</li>
</ol>
</blockquote>
<blockquote>
<p>2-1 ) <span style = "background : #D4F4FA"><strong><em>Getter 메서드</em></strong></span> : 내부 멤버변수의 값을 외부로 리턴 / 파라미터 x 리턴값 ㅇ
  2-2 ) <span style = "background : #D4F4FA"> <strong>* Setter 메서드 *</strong> </span> : 외부로부터 전달받은 값을 내부 멤버변수에 저장 / 파라미터 ㅇ 리턴값 x</p>
</blockquote>
<hr>
<h3 id="🤍-3-캡슐화-예시">🤍 3) 캡슐화 예시</h3>
<p>   <code>Person 클래스 생성 및 캡슐화</code></p>
<pre><code class="language-java">   class Person {
       // 멤버변수 선언
    private String name;
    private int age;

    // 메서드 선언
    // 1) name
    public void setName (String name) {
        this.name = name;
    }

    public String getName () {
        return name;
    }

     // 1) age
    public void setAge (int age) {
        this.age = age;
    }

    public int getage () {
        return age;
    }

   }</code></pre>
<p>   <code>메인에서 객체 생성 및 접근</code></p>
<pre><code class="language-java">   Person p = new Person();
   p.setName(&quot;이도현&quot;); // 저장
   System.out.println(p.getName()); // 호출

   p.setAge(30); //배우와 무관합니다..!
   System.out.println(p.getAge()); 
</code></pre>
<hr>
<p>   이걸 언제 쓰는지는 모르겠지만 일단 이해 완
   이거만 기억하면 될듯</p>
<ol>
<li>멤버변수 생성은 private를 붙인다</li>
<li>메서드 생성은 getter/setter를 이용한다</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[~240318]]></title>
            <link>https://velog.io/@oss_nue/240318</link>
            <guid>https://velog.io/@oss_nue/240318</guid>
            <pubDate>Mon, 18 Mar 2024 13:32:08 GMT</pubDate>
            <description><![CDATA[<ul>
<li>java</li>
</ul>
<ol>
<li><a href="https://velog.io/@oss_nue/%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-Interface">인터페이스</a></li>
<li>[try - catch (간단하게)] (<a href="https://velog.io/@oss_nue/%EC%98%A4%EB%A5%98%EC%B2%98%EB%A6%AC-try-catch">https://velog.io/@oss_nue/%EC%98%A4%EB%A5%98%EC%B2%98%EB%A6%AC-try-catch</a>)</li>
</ol>
<ul>
<li>jsp</li>
</ul>
<ol>
<li>servlet</li>
<li>jsp와 데이터베이스 연결</li>
<li>DAO/DTO</li>
</ol>
<p>아놔 앞에 거 공부 다 안 했는데 모르는 것만 늘어남</p>
]]></description>
        </item>
    </channel>
</rss>