<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>개발 정리 노트</title>
        <link>https://velog.io/</link>
        <description>배운 내용 정리하기 위해 쓰는 블로그</description>
        <lastBuildDate>Thu, 23 Jan 2025 06:49:36 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>개발 정리 노트</title>
            <url>https://velog.velcdn.com/images/s2__heee/profile/26cb6799-b2ba-4f29-9395-cac72f815b73/image.PNG</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. 개발 정리 노트. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/s2__heee" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[queue]]></title>
            <link>https://velog.io/@s2__heee/queue</link>
            <guid>https://velog.io/@s2__heee/queue</guid>
            <pubDate>Thu, 23 Jan 2025 06:49:36 GMT</pubDate>
            <description><![CDATA[<h3 id="1-queue-생성">1. queue 생성</h3>
<pre><code>Queue&lt;Integer&gt; queue = new LinkedList&lt;&gt;();</code></pre><ul>
<li>BFS에 사용할 큐</li>
<li>queue는 선입선출(FIFO)구조이므로, BFS에 적합</li>
<li>큐에 탐색할 노드를 저장 후, 하나씩 꺼내서 탐색</li>
</ul>
<hr>
<h3 id="2-queue-시작노드-추가">2. queue 시작노드 추가</h3>
<pre><code>queue.add(start);</code></pre><hr>
<h3 id="3-시작노드-방문-처리">3. 시작노드 방문 처리</h3>
<pre><code>visited[start] = true;</code></pre><hr>
<h3 id="4-큐가-비어있지않을-때까지-반복">4. 큐가 비어있지않을 때까지 반복</h3>
<pre><code>while (!queue.isEmpty())</code></pre><hr>
<h3 id="5-큐에서-노드-꺼내기">5. 큐에서 노드 꺼내기</h3>
<h4 id="📘-queuepoll">📘 queue.poll</h4>
<pre><code>int node = queue.poll();</code></pre><ul>
<li>큐에서 노드 하나를 꺼내서 그 노드에 연결된 다른 노드 탐색하게됨</li>
<li>queue.poll()은 노드를 꺼내면서 동시에 큐에서 제거</li>
</ul>
<hr>
<h3 id="6-모든-a-검사">6. 모든 A 검사</h3>
<pre><code>for (int i = 0; i &lt; n; i++)</code></pre><ul>
<li>i는 현재 노드와 연결된 다른 노드들을 검사하기 위한 변수</li>
<li>n은 총 검사할 모든 A의 개수</li>
</ul>
<hr>
<h3 id="7-연결-여부-및-방문-여부-확인">7. 연결 여부 및 방문 여부 확인</h3>
<pre><code>if(computers[node][i] == 1 &amp;&amp; !visited[i])</code></pre><hr>
<h3 id="8-방문-처리">8. 방문 처리</h3>
<pre><code>visited[i] = true;</code></pre><hr>
<h3 id="9-새로-탐색해야할-노드를-큐에-추가">9. 새로 탐색해야할 노드를 큐에 추가</h3>
<pre><code>queue.add(i);</code></pre><ul>
<li>현재 노드와 연결된 새로운 노드인 i를 탐색하기위해 큐에 추가</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[DFS(Depth-First Search) / BFS(Breadth-First Search)]]></title>
            <link>https://velog.io/@s2__heee/DFSDepth-First-Search</link>
            <guid>https://velog.io/@s2__heee/DFSDepth-First-Search</guid>
            <pubDate>Thu, 23 Jan 2025 04:32:46 GMT</pubDate>
            <description><![CDATA[<p><strong>그래프나 트리 관련 문제</strong> 나오면, <strong>BFS/DFS</strong>로 풀어야할 가능성 높음!!</p>
<ul>
<li><p>DFS는 경로 찾기,탐색을 끝까지 진행하는 문제</p>
<ul>
<li>모든 경우의 수 찾기</li>
<li>연결된 컴포넌트 탐색 등</li>
</ul>
</li>
<li><p>BFS는 보통 최단거리 문제, 레벨별 탐색 문제</p>
<ul>
<li>최단 경로</li>
<li>레벨별 출력 등</li>
</ul>
</li>
</ul>
<hr>
<h3 id="📘-dfs">📘 DFS</h3>
<p>먼저 깊게 파고들어간 후, 더 이상 갈 곳이 없으면 다시 돌아오는 방식으로 탐색</p>
<h4 id="✨-특징">✨ 특징</h4>
<ul>
<li>한 경로를 끝까지 탐색</li>
<li>현재 노드에서 자식노드로 계속 깊이 들어가다가 더이상 갈 곳이 없으면 되돌아와서 다른 경로 탐색</li>
<li>트리 or 그래프에서 한 뱡향으로 깊이 파고들면서 탐색</li>
</ul>
<hr>
<h3 id="📘-bfs">📘 BFS</h3>
<p>넓게 탐색하는 방식, 한번에 모든 노드 탐색 -&gt; 자식노드 탐색</p>
<p>현재 노드와 같은 깊이의 노드들 먼저 탐색 후, 아래로 내려가서 탐색</p>
<h4 id="✨-특징-1">✨ 특징</h4>
<ul>
<li>현재 경로에서 한 단계씩 확장하면서 탐색</li>
<li>모든 노드 한번에 탐색 후, 자식 노드 탐색 방식</li>
<li>너비 우선(같은 레벨 노드 먼저)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[깊이/너비 우선 탐색(DFS/BFS)
_타겟 넘버]]></title>
            <link>https://velog.io/@s2__heee/%EA%B9%8A%EC%9D%B4%EB%84%88%EB%B9%84-%EC%9A%B0%EC%84%A0-%ED%83%90%EC%83%89DFSBFS%ED%83%80%EA%B2%9F-%EB%84%98%EB%B2%84</link>
            <guid>https://velog.io/@s2__heee/%EA%B9%8A%EC%9D%B4%EB%84%88%EB%B9%84-%EC%9A%B0%EC%84%A0-%ED%83%90%EC%83%89DFSBFS%ED%83%80%EA%B2%9F-%EB%84%98%EB%B2%84</guid>
            <pubDate>Thu, 23 Jan 2025 02:19:49 GMT</pubDate>
            <description><![CDATA[<h3 id="📘-문제">📘 문제</h3>
<p>n개의 음이 아닌 정수들이 있습니다. 이 정수들을 순서를 바꾸지 않고 적절히 더하거나 빼서 타겟 넘버를 만들려고 합니다. 예를 들어 [1, 1, 1, 1, 1]로 숫자 3을 만들려면 다음 다섯 방법을 쓸 수 있습니다.</p>
<blockquote>
<p>-1+1+1+1+1 = 3
+1-1+1+1+1 = 3
+1+1-1+1+1 = 3
+1+1+1-1+1 = 3
+1+1+1+1-1 = 3</p>
</blockquote>
<p>사용할 수 있는 숫자가 담긴 배열 numbers, 타겟 넘버 target이 매개변수로 주어질 때 숫자를 적절히 더하고 빼서 타겟 넘버를 만드는 방법의 수를 return 하도록 solution 함수를 작성해주세요.</p>
<h4 id="입출력-예">입출력 예</h4>
<table>
<thead>
<tr>
<th align="left">numbers</th>
<th>target</th>
<th>return</th>
</tr>
</thead>
<tbody><tr>
<td align="left">[1, 1, 1, 1, 1]</td>
<td>3</td>
<td>5</td>
</tr>
<tr>
<td align="left">[4, 1, 2, 1]</td>
<td>4</td>
<td>2</td>
</tr>
<tr>
<td align="left">[1, 2, 3, 4]</td>
<td>7</td>
<td>1</td>
</tr>
</tbody></table>
<hr>
<h3 id="📑-풀이">📑 풀이</h3>
<pre><code>class Solution {
    public int answer = 0; // 타겟 넘버를 만드는 방법의 수

    public int solution(int[] numbers, int target) {
        dfs(numbers, 0 , 0 , target);
        return answer;
    }

    // 깊이 우선 탐색
    public void dfs(int[] numbers, int index, int currentSum, int target){
        if(index == numbers.length){
            if(currentSum == target){
                answer++;
            }
            return; // 종료
        }

        // 현재 숫자 더하기
        dfs(numbers, index+1, currentSum+numbers[index], target);
        // 현재 숫자 빼기
        dfs(numbers, index+1, currentSum-numbers[index], target);
    }
}</code></pre><hr>
<h3 id="👀-문제-출처">👀 <a href="https://school.programmers.co.kr/learn/courses/30/lessons/43165">문제 출처</a></h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[해시_베스트 앨범에 들어갈 노래 번호 구하기]]></title>
            <link>https://velog.io/@s2__heee/%ED%95%B4%EC%8B%9C%EB%B2%A0%EC%8A%A4%ED%8A%B8-%EC%95%A8%EB%B2%94</link>
            <guid>https://velog.io/@s2__heee/%ED%95%B4%EC%8B%9C%EB%B2%A0%EC%8A%A4%ED%8A%B8-%EC%95%A8%EB%B2%94</guid>
            <pubDate>Wed, 22 Jan 2025 04:47:12 GMT</pubDate>
            <description><![CDATA[<h3 id="📘-문제">📘 문제</h3>
<p>스트리밍 사이트에서 장르 별로 가장 많이 재생된 노래를 두 개씩 모아 베스트 앨범을 출시하려 합니다. 노래는 고유 번호로 구분하며, 노래를 수록하는 기준은 다음과 같습니다.</p>
<blockquote>
<p>속한 노래가 많이 재생된 장르를 먼저 수록합니다.
장르 내에서 많이 재생된 노래를 먼저 수록합니다.
장르 내에서 재생 횟수가 같은 노래 중에서는 고유 번호가 낮은 노래를 먼저 수록합니다.</p>
</blockquote>
<p>노래의 장르를 나타내는 문자열 배열 genres와 노래별 재생 횟수를 나타내는 정수 배열 plays가 주어질 때, 베스트 앨범에 들어갈 노래의 고유 번호를 순서대로 return 하도록 solution 함수를 완성하세요</p>
<hr>
<h3 id="📑-풀이">📑 풀이</h3>
<pre><code>import java.util.*;

class Solution {
    public int[] solution(String[] genres, int[] plays) {
        Map&lt;String, Integer&gt; genrePlayCount = new HashMap&lt;&gt;(); // 각 장르에 대한 재생횟수
        Map&lt;String, List&lt;int[]&gt;&gt; genreSongList = new HashMap&lt;&gt;(); 
        // 장르별 재생횟수와 인덱스 값 저장

        // HashMap에 장르별 재생 횟수 총합 계산
        for (int i = 0; i &lt; genres.length; i++) {
            genrePlayCount.put(genres[i], genrePlayCount.getOrDefault(genres[i], 0) + plays[i]);

            // 각 장르에 해당하는 노래 정보 없으면 새로 만듦 [인덱스값, 재생횟수]
            if (!genreSongList.containsKey(genres[i])) {
                genreSongList.put(genres[i], new ArrayList&lt;&gt;());
            }
            // 장르와 인덱스 값(i), 재생횟수 저장
            genreSongList.get(genres[i]).add(new int[]{i, plays[i]}); 
        }

        // {&quot;pop&quot;, &quot;classic&quot;} 형태로 장르 반환
        List&lt;String&gt; genreList = new ArrayList&lt;&gt;(genrePlayCount.keySet()); 

        // 장르별 총 재생 횟수를 기준으로 내림차순 정렬
        genreList.sort((g1, g2) -&gt; genrePlayCount.get(g2) - genrePlayCount.get(g1));

        // 결과 저장 리스트 생성
        List&lt;Integer&gt; result = new ArrayList&lt;&gt;();

        // 각 장르별로 가장 많이 재생된 상위 2곡 추출
        for (String genre : genreList) { // genreList는 {&quot;pop&quot;, &quot;classic&quot;}
            List&lt;int[]&gt; songs = genreSongList.get(genre);
            songs.sort((s1, s2) -&gt; s2[1] - s1[1]); // 재생횟수를 기준으로 내림차순 정렬

            // 가장 많이 재생된 2곡만 선택
            int count = 0;
            for (int[] song : songs) {
                if (count &gt;= 2) break;
                result.add(song[0]); // 인덱스만 저장
                count++;
            }
        }

        // 결과를 리스트에서 int[] 배열로 반환
        return result.stream().mapToInt(i -&gt; i).toArray();
    }
}</code></pre><p>장르와 노래 재생 횟수, 고유번호인 인덱스값 3가지가 필요하므로, 먼저</p>
<p>HashMap에 각 장르의 재생횟수 총합을 구하고, 또 다른 하나의 키 장르에 고유번호와 재생횟수 2개의 값을 갖는 HashMap을 만든다.</p>
<p>✨<strong>HashMap 자체는 정렬되지않으므로, Map을 리스트로 변환하는 작업</strong>이 필요하다.
정렬을 위해 리스트를 생성하여 키 값인 장르를 넣고, 그 키를 기준으로 장르별 재생횟수를 내림차순으로 정렬 후 저장한다. &gt;&gt;  노래가 많이 재생된 장르 구함</p>
<p>장르 내에서 많이 재생된 노래를 먼저 수록하기 위해,</p>
<p>새로 생성된 노래 리스트에
하나의 키 장르에 고유번호와 재생횟수 2개의 값이 저장된 genreSongList 맵을 이용하여
넣고 그 값들을 내림차순 후, 결과 리스트에 상위 2곡의 인덱스(고유번호)만 저장한다.</p>
<p><code>&quot;pop&quot; = [{0,200}.[3.150}..] &gt;&gt; 1개의 장르 키와 2개의 값 형태</code></p>
<p>리스트를 Int배열로 반환하기 위해,
결과 리스트를 스트림으로 바꾸고, 스트림의 각 요소를 int로 변환 후(Integer -&gt; int), 배열로 변환한다.
<code>return result.stream().mapToInt(i -&gt; i).toArray();</code></p>
<hr>
<h3 id="👀-문제-출처">👀 <a href="https://school.programmers.co.kr/learn/courses/30/lessons/42579">문제 출처</a></h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[해시 Hash]]></title>
            <link>https://velog.io/@s2__heee/%ED%95%B4%EC%8B%9C-Hash</link>
            <guid>https://velog.io/@s2__heee/%ED%95%B4%EC%8B%9C-Hash</guid>
            <pubDate>Wed, 22 Jan 2025 04:38:15 GMT</pubDate>
            <description><![CDATA[<h2 id="📘-해시">📘 해시</h2>
<p>데이터구조에서 데이터를 빠르게 저장하고 검색하는 방법</p>
<hr>
<h3 id="📚-hashmap-메소드">📚 HashMap 메소드</h3>
<p>key와 value 2개의 값을 쌍으로 데이터 저장, 관리하는 자료 구조</p>
<p>❗❗ 정렬된 결과가 필요할 때, 
해시테이블을 사용해서 데이터 저장 &gt;&gt; 삽입 순서는 유지 / 키나 값의 순서 보장X
따라서, 새로 <strong>리스트를 생성하여 정렬 후 저장</strong>한다.</p>
<hr>
<h4 id="1-기본-메소드">1. 기본 메소드</h4>
<ul>
<li><p>put(key, value)</p>
<ul>
<li>key와 value를 HashMap에 추가</li>
<li>이미 key가 존재하는 경우, 그 값을 덮어씀</li>
</ul>
</li>
<li><p>get(key)</p>
<ul>
<li>key에 해당하는 값 반환</li>
<li>존재하지 않으면 null 반환</li>
</ul>
</li>
<li><p>remove(key)</p>
<ul>
<li>key에 해당하는 값 삭제</li>
<li>삭제된 값은 반환됨</li>
</ul>
</li>
<li><p>size()</p>
<ul>
<li>HashMap에 저장된 키-값 쌍의 수 반환
<code>int size = map.size();</code></li>
</ul>
</li>
<li><p>containValue(value)</p>
<ul>
<li>HashMap에 value 있으면, true 반환
<code>boolean exists = map.containValue(10);</code></li>
</ul>
</li>
<li><p>isEmpty()</p>
<ul>
<li>HashMap이 비어있으면 true / false
<code>boolean isEmpty = map.isEmpty(10);</code></li>
</ul>
</li>
<li><p>clear()</p>
<ul>
<li>HashMap 모든 항목 삭제
<code>map.clear()</code></li>
</ul>
<hr>
<h4 id="2-조회-메소드">2. 조회 메소드</h4>
</li>
<li><p>keySet()</p>
<ul>
<li>HashMap에 저장된 모든 key 반환하는 set 반환
<code>Set&lt;K&gt; keys = map.keySet();</code></li>
</ul>
</li>
<li><p>values()</p>
<ul>
<li>HashMap에 저장된 모든 value 반환하는 collection(객체들의 집합) 반환
<code>Collection&lt;V&gt; values = map.values();</code></li>
</ul>
</li>
<li><p>entrySet()</p>
<ul>
<li>HashMap에 저장된 모든 key-value 쌍 반환하는 Set&lt;Map.Entry&lt;k,V&gt;&gt;을 </li>
<li>key와 value값 동시 처리
<code>Set&lt;Map,Entry&lt;k,v&gt;&gt; entrySet = map.entrySet();</code></li>
</ul>
</li>
</ul>
<hr>
<h3 id="📚-hashset-메소드">📚 HashSet 메소드</h3>
<p>HashMap에서 value만 사용, key가 중복되지않은 특성을 가진 집합(Set) 자료구조</p>
<ul>
<li><p>add(c)</p>
<ul>
<li>요소 추가(중복X)</li>
</ul>
</li>
<li><p>contains(c)</p>
<ul>
<li>요소가 집합에 존재하는지 확인</li>
</ul>
</li>
<li><p>remove(c)</p>
<ul>
<li>요소를 집합에서 제거</li>
</ul>
</li>
<li><p>size()</p>
<ul>
<li>요소의 개수를 반환</li>
</ul>
</li>
<li><p>isEmpty()</p>
<ul>
<li>집합이 비었는지 확인</li>
</ul>
</li>
<li><p>clear()</p>
<ul>
<li>집합의 모든 요소 제거</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[해시_서로 다른 옷의 조합의 수]]></title>
            <link>https://velog.io/@s2__heee/%ED%95%B4%EC%8B%9C%EC%9D%98%EC%83%81</link>
            <guid>https://velog.io/@s2__heee/%ED%95%B4%EC%8B%9C%EC%9D%98%EC%83%81</guid>
            <pubDate>Wed, 22 Jan 2025 02:27:42 GMT</pubDate>
            <description><![CDATA[<h3 id="📘-문제">📘 문제</h3>
<p>코니는 매일 다른 옷을 조합하여 입는것을 좋아합니다.</p>
<p>예를 들어 코니가 가진 옷이 아래와 같고, 오늘 코니가 동그란 안경, 긴 코트, 파란색 티셔츠를 입었다면 다음날은 청바지를 추가로 입거나 동그란 안경 대신 검정 선글라스를 착용하거나 해야합니다.</p>
<table>
<thead>
<tr>
<th align="left">이름</th>
<th>종류</th>
</tr>
</thead>
<tbody><tr>
<td align="left">동그란 안경</td>
<td>얼굴</td>
</tr>
<tr>
<td align="left">검정 선글라스</td>
<td>얼굴</td>
</tr>
<tr>
<td align="left">파란색 티셔츠</td>
<td>상의</td>
</tr>
<tr>
<td align="left">청바지</td>
<td>하의</td>
</tr>
<tr>
<td align="left">긴 코트</td>
<td>겉옷</td>
</tr>
</tbody></table>
<p>코니는 각 종류별로 최대 1가지 의상만 착용할 수 있습니다. 예를 들어 위 예시의 경우 동그란 안경과 검정 선글라스를 동시에 착용할 수는 없습니다.
착용한 의상의 일부가 겹치더라도, 다른 의상이 겹치지 않거나, 혹은 의상을 추가로 더 착용한 경우에는 서로 다른 방법으로 옷을 착용한 것으로 계산합니다.
코니는 하루에 최소 한 개의 의상은 입습니다.</p>
<p>코니가 가진 의상들이 담긴 2차원 배열 clothes가 주어질 때 <strong>서로 다른 옷의 조합의 수</strong>를 return 하도록 solution 함수를 작성해주세요.</p>
<hr>
<h3 id="📑-풀이-hashmap-이용">📑 풀이 (HashMap 이용)</h3>
<pre><code>import java.util.*;

class Solution {
    public int solution(String[][] clothes) {
        int result = 1; // 곱셈을 위한 기본값 1

        // HashMap 생성
        Map&lt;String,Integer&gt; clothesCount = new HashMap();

        // HashMap에 clothes 배열의 의상 종류별 개수 저장
        for(int i=0;i&lt;clothes.length;i++){
            String Category = clothes[i][1]; // 의상 종류 key
            clothesCount.put(Category, clothesCount.getOrDefault(Category,0)+1);
        }

        // 의상 조합 수 계산
        for(int c:clothesCount.values()){
            result *= c+1; // 각 의상종류 별 선택하지 않은 경우
        }

        // 아무것도 선택하지 않은 경우 제외
        result -= 1;

        return result;
    }
}</code></pre><p>의상 이름은 필요하지 않으므로, 의상종류에 대한 개수만 구함.</p>
<p>예를 들어, 
모자가 2개면 각 1개씩 선택하는 경우와 모자를 하나도 선택 안하는 경우,</p>
<blockquote>
<p>2+1 = 3개</p>
</blockquote>
<p>바지가 3개면, 각 1개씩 선택하는 경우 3개와, 바지 하나도 선택 안 하는 경우,</p>
<blockquote>
<p>3+1 =  4개</p>
</blockquote>
<p>두 의상 종류 조합하면,</p>
<blockquote>
<p>3 * 4 = 12개</p>
</blockquote>
<p>아무것도 선택하지 않는 경우 1개 제외</p>
<blockquote>
<p>12 -1 = 11개</p>
</blockquote>
<hr>
<h3 id="👀-문제-출처">👀 <a href="https://school.programmers.co.kr/learn/courses/30/lessons/42578">문제 출처</a></h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[contains( )와 startsWith( )]]></title>
            <link>https://velog.io/@s2__heee/contains-%EC%99%80-startsWith</link>
            <guid>https://velog.io/@s2__heee/contains-%EC%99%80-startsWith</guid>
            <pubDate>Wed, 22 Jan 2025 00:28:54 GMT</pubDate>
            <description><![CDATA[<h3 id="📘-contains">📘 contains()</h3>
<ul>
<li>문자열이 다른 문자열(전체) 안에 포함되어있는지 확인</li>
<li>반환값 : true / false</li>
</ul>
<pre><code>String str = &quot;Hello, World&quot;;
boolean result = str.contains(&quot;World&quot;); // true</code></pre><hr>
<h3 id="📘-startswith">📘 startsWith()</h3>
<ul>
<li>문자열이 특정 문자열로 시작하는지 확인</li>
<li>접두어 확인</li>
</ul>
<pre><code>String str = &quot;Hello, World&quot;;
boolean result = str.startsWith(&quot;World&quot;); // false</code></pre><hr>
<h3 id="📘-차이점">📘 차이점</h3>
<ul>
<li>contains()는 문자열이 전체 문자열 어디에든 <strong>포함</strong>되어있는지 여부를 확인</li>
<li>startsWith( )는 시작 부분을 비교</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[해시_전화번호 목록]]></title>
            <link>https://velog.io/@s2__heee/%ED%95%B4%EC%8B%9C%EC%A0%84%ED%99%94%EB%B2%88%ED%98%B8-%EB%AA%A9%EB%A1%9D</link>
            <guid>https://velog.io/@s2__heee/%ED%95%B4%EC%8B%9C%EC%A0%84%ED%99%94%EB%B2%88%ED%98%B8-%EB%AA%A9%EB%A1%9D</guid>
            <pubDate>Wed, 22 Jan 2025 00:16:46 GMT</pubDate>
            <description><![CDATA[<h3 id="📘-문제">📘 문제</h3>
<p>전화번호부에 적힌 전화번호 중, 한 번호가 다른 번호의 접두어인 경우가 있는지 확인하려 합니다.
전화번호가 다음과 같을 경우, 구조대 전화번호는 영석이의 전화번호의 접두사입니다.</p>
<p>구조대 : 119
박준영 : 97 674 223
지영석 : 11 9552 4421
전화번호부에 적힌 전화번호를 담은 배열 phone_book 이 solution 함수의 매개변수로 주어질 때, 어떤 번호가 다른 번호의 접두어인 경우가 있으면 false를 그렇지 않으면 true를 return 하도록 solution 함수를 작성해주세요.</p>
<hr>
<h3 id="📑-첫번째-풀이">📑 첫번째 풀이</h3>
<pre><code>import java.util.*;

class Solution {
    public boolean solution(String[] phone_book) {
        boolean answer = true;

        // 접두어 찾기
        for(int i=0;i&lt;phone_book.length;i++){
            for(int j=0;j&lt;phone_book.length;j++){
                if(i!=j &amp;&amp; phone_book[j].startsWith(phone_book[i])){
                    answer = false; // 있으면
                    break;
                }
            }
            if(!answer) break;
        }

        return answer;
    }
}</code></pre><p>모든 배열 값에 대해 for문으로 돌면서 startsWith 메소드로 phone_book[j]가 phone_book[i]로 시작하는지 비교했는데, 정확성은 맞지만, 효율성 테스트 시, 시간이 오래걸려 다시 풀어보았다(시간복잡도 O(n^2))</p>
<hr>
<h3 id="📑-두번째-풀이">📑 두번째 풀이</h3>
<pre><code>import java.util.*;

class Solution {
    public boolean solution(String[] phone_book) {
        boolean answer = true;

        // 오름차순(사전순)으로 정렬
        Arrays.sort(phone_book);

        // 접두어 찾기
        for(int i=0;i&lt;phone_book.length-1;i++){ // 마지막은 비교대상이 없으므로
            if(phone_book[i+1].startsWith(phone_book[i])){
                answer = false; // 있으면
                break;
            }
        }

        return answer;
    }
}</code></pre><p>시간복잡도를 줄이기 위해, Arrays.sort()를 사용 &gt; 시간복잡도 O(NlogN)</p>
<ol>
<li>전화번호 배열을 사전순으로 정렬</li>
<li>앞 뒤 두개의 전화번호를 비교 &gt; 접두어 확인함</li>
<li>마지막 값은 비교대상이 없으므로 그 앞까지만 비교함</li>
</ol>
<hr>
<h3 id="📘-startswith-메소드">📘 startsWith 메소드</h3>
<p>A.startsWith(B) &gt; A가 B로 시작하는지 확인 하는 메소드(접두어 확인) </p>
<ul>
<li>반환값 : true / false</li>
</ul>
<hr>
<h3 id="👀-문제-출처">👀 <a href="https://school.programmers.co.kr/learn/courses/30/lessons/42577">문제 출처</a></h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[해시_완주하지 못한 선수]]></title>
            <link>https://velog.io/@s2__heee/%ED%95%B4%EC%8B%9C%EC%99%84%EC%A3%BC%ED%95%98%EC%A7%80-%EB%AA%BB%ED%95%9C-%EC%84%A0%EC%88%98</link>
            <guid>https://velog.io/@s2__heee/%ED%95%B4%EC%8B%9C%EC%99%84%EC%A3%BC%ED%95%98%EC%A7%80-%EB%AA%BB%ED%95%9C-%EC%84%A0%EC%88%98</guid>
            <pubDate>Tue, 21 Jan 2025 07:25:16 GMT</pubDate>
            <description><![CDATA[<h3 id="📘-문제-설명">📘 문제 설명</h3>
<p>수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.</p>
<p>마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.</p>
<hr>
<h3 id="📑-첫번째-풀이-정렬-이용">📑 첫번째 풀이 (정렬 이용)</h3>
<pre><code>import java.util.*;

class Solution {
    public String solution(String[] participant, String[] completion) {
        String answer = &quot;&quot;;

        // 두 배열을 정렬 (사전순)
        Arrays.sort(participant);
        Arrays.sort(completion);

        // 원소값 비교하여 없는 원소값 찾음
        for(int i=0;i&lt;completion.length;i++){
            if(!participant[i].equals(completion[i])){
                answer = participant[i];
                break;
            }
        }
        // 마지막 원소값이 미완주자인 경우
        if(answer.equals(&quot;&quot;)) //true
            answer = participant[participant.length-1];

        return answer;
    }
}</code></pre><p>먼저, 두 배열을 똑같이 사전순으로 정렬을 하고, 두 배열을 비교하여 completion 완주자 배열에 없는 원소값을 찾는다(미완주자)</p>
<p>마지막 원소값이 미완주자라면, answer 문자열이 빈 문자열인지 확인(true)하고, 참가자 배열의 마지막 인덱스값을 answer에 저장한다.</p>
<hr>
<h3 id="📑-두번째-풀이-hashmap-이용">📑 두번째 풀이 (HashMap 이용)</h3>
<pre><code>import java.util.*;

class Solution {
    public String solution(String[] participant, String[] completion) {

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

        // 참가자 배열을 순회하며 해시맵에 각 참가자의 이름과 수를 기록
        for(String num:participant){
            map.put(num, map.getOrDefault(num, 0) + 1);
        }

        // 완주자 배열을 순회하며 해시맵에서 각 완주자의 이름을 찾아 수를 하나씩 감소
        for (String c : completion) {
            map.put(c, map.get(c) - 1);
        }

        // 해시맵에서 값이 1인 키를 찾아 그 이름이 완주하지 못한 선수
        for (String key : map.keySet()) {
            if (map.get(key) == 1) {
                return key; // 완주하지 못한 선수
            }
        }

        return &quot;&quot;;
    }
}</code></pre><hr>
<h3 id="❗❗-map-인터페이스의-메서드">❗❗ Map 인터페이스의 메서드</h3>
<h4 id="1-mapputkey-value">1. map.put(key, value)</h4>
<ul>
<li>키와 값을 맵에 추가하거나 업데이트 // 키에 값을 저장</li>
<li>키가 이미 맵에 존재하면 해당 기존값 반환</li>
<li>키가 없으면, null 반환</li>
</ul>
<h4 id="2-mapgetkey">2. map.get(key)</h4>
<ul>
<li>키에 해당하는 값을 반환</li>
<li>없으면, null 반환</li>
</ul>
<hr>
<h3 id="👀-문제-출처">👀 <a href="https://school.programmers.co.kr/learn/courses/30/lessons/42576">문제 출처</a></h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[해시_폰켓몬(HashSet)]]></title>
            <link>https://velog.io/@s2__heee/%ED%95%B4%EC%8B%9C%ED%8F%B0%EC%BC%93%EB%AA%AC</link>
            <guid>https://velog.io/@s2__heee/%ED%95%B4%EC%8B%9C%ED%8F%B0%EC%BC%93%EB%AA%AC</guid>
            <pubDate>Tue, 21 Jan 2025 05:20:44 GMT</pubDate>
            <description><![CDATA[<p>프로그래머스 폰켓몬 종류 번호 개수 구하는 문제</p>
<h3 id="📑-풀이">📑 풀이</h3>
<pre><code>import java.util.HashSet;

class Solution {
    public int solution(int[] nums) {
        int length = nums.length; // 폰켓몬 종류 번호 담긴 배열의 길이
        int count = length/2; // 가질 수 있는 폰캣몬 수

        // 중복 제거해주는 HashSet 선언
        HashSet&lt;Integer&gt; ponketmon = new HashSet&lt;&gt;();

        // 중복 제거해서 HashSet에 추가
        for(int num:nums){
            ponketmon.add(num);
        } 

        // 폰켓몬 종류 번호의 개수 구하기
        return Math.min(ponketmon.size(),count);
    }
}</code></pre><p>같은 번호를 가진 폰켓몬 중복 없애기위해 HashSet 사용</p>
<hr>
<h3 id="📘-hashset">📘 HashSet</h3>
<ul>
<li>자바의 컬렉션 프레임워크에 속하는 객체</li>
<li>집합을 표현하는 자료 구조</li>
<li>중복 허용하지 않음</li>
</ul>
<hr>
<h3 id="👀-문제-출처">👀 <a href="https://school.programmers.co.kr/learn/courses/30/lessons/1845">문제 출처</a></h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[정렬 (H-index)]]></title>
            <link>https://velog.io/@s2__heee/%EC%A0%95%EB%A0%AC</link>
            <guid>https://velog.io/@s2__heee/%EC%A0%95%EB%A0%AC</guid>
            <pubDate>Tue, 21 Jan 2025 00:51:53 GMT</pubDate>
            <description><![CDATA[<p>프로그래머스 알고리즘 고득점 문제 중 Level 2
H-index 문제</p>
<hr>
<h3 id="📘-h-index-공식">📘 H-index 공식</h3>
<ol>
<li>연구자가 발표한 논문들(배열)을 인용 횟수에 따라 내림차순 or 오름차순 정렬</li>
<li>인용 횟수와 순위를 비교</li>
<li>인용 횟수가 순위보다 크거나 같은지(&gt;=) 확인</li>
<li>h번째 논문의 인용횟수가 h번 이상이면, 그 연구자의 H-index는 h로 설정</li>
</ol>
<hr>
<h3 id="📑-나의-풀이-int-배열-이용">📑 나의 풀이 (int 배열 이용)</h3>
<pre><code>import java.util.Arrays;

class Solution {
    public int solution(int[] citations) {
        int answer = 0;
        int j = 0;

        // 오름차순 정렬
        Arrays.sort(citations);

        // H-index 값 계산 
        for(int i=citations.length-1;i&gt;=0;i--){
            if(citations[i]&gt;=j+1){
                answer++;
            }
            j++;
        }
        return answer;
    }
}</code></pre><p>먼저, <strong>Arrays.sort() 메소드</strong>는 기본적으로 오름차순 정렬이며, int는 primitive type(원시타입)이라 comparaotr 같은 객체 기반 메소드가 적용되지 않기 때문에, 내림차순 정렬 후, 뒤에 인덱스부터 뒷 순위와 하나씩 비교하여 H-index를 구함.</p>
<h3 id="📑-나의-풀이-integer-객체-배열-이용">📑 나의 풀이 (Integer 객체 배열 이용)</h3>
<pre><code>import java.util.*;

class Solution {
    public int solution(int[] citations) {
        int answer = 0;

        // Integer 객체 배열로 변환
        Integer[] arr = new Integer[citations.length];

        for(int i=0;i&lt;citations.length;i++){
            arr[i] = citations[i];
        }

        // 내림차순 정렬
        Arrays.sort(arr, Comparator.reverseOrder());

        // H-index 계산
        for(int i=0;i&lt;arr.length;i++){
            if(arr[i]&gt;=i+1){
                answer++;
            }else break;
        }
        return answer;
    }
}</code></pre><p>내림차순 정렬을 사용해보기위해, Integer 객체 배열로 변환하여 다시 풀어보았다.
Integer 객체 배열을 사용했을 때는 기본형인 int를 객체로 감싸는 작업인 boxing과, 객체에서 기본형값을 꺼내는 unboxing 작업이 필요했다.</p>
<p>따라서, 이런 작업이 필요없는 int[] 배열을 사용했을 때, 속도와 메모리 측면에서 훨씬 효율적이었다.</p>
<p>Integer[] 배열을 사용하는 이유는 null값을 저장할 수 있기 때문에 값이 없거나 초기화되지 않은 상태를 표현하기위해서는 Integer[]를 사용해야한다.</p>
<h3 id="❗❗-comparatorreverseorder-와-collectionreverseorder-차이">❗❗ Comparator.reverseOrder() 와 collection.reverseOrder() 차이?</h3>
<p>두 메소드 다 내림차순 정렬시 사용하지만,comparator.reverseOrder() 주로 배열에 사용되며, collection.reverseOrder()는 리스트에서 주로 사용된다.</p>
<h3 id="👀-문제-출처">👀 <a href="https://school.programmers.co.kr/learn/courses/30/lessons/42747">문제 출처</a></h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[.d.ts 파일]]></title>
            <link>https://velog.io/@s2__heee/.d.ts-%ED%8C%8C%EC%9D%BC</link>
            <guid>https://velog.io/@s2__heee/.d.ts-%ED%8C%8C%EC%9D%BC</guid>
            <pubDate>Mon, 04 Nov 2024 01:45:48 GMT</pubDate>
            <description><![CDATA[<h2 id="📘-typescript에서-dts">📘 TypeScript에서 .d.ts</h2>
<ul>
<li>타입 정의 파일</li>
<li>특정 모듈이나 라이브러리 타입 정보를 정의하는데 사용</li>
<li>JavaScript 코드에 대한 타입 정보를 제공 &gt;&gt; TypeScript 컴파일러가 코드의 타입을 이해하고 타입 검사를 수행할 수 있도록 도와줌</li>
<li>타입스크립트 코드에서 해당 모듈을 사용할 때, .d.ts 파일에 정의된 타입 정보를 기반으로 타입 추론이 이루어짐</li>
</ul>
<hr>
<h2 id="📘-dts-파일의-역할">📘 .d.ts 파일의 역할</h2>
<h4 id="1-타입-정보-제공">1. 타입 정보 제공</h4>
<p>: 외부 라이브러리의 함수, 클래스, 인터페이스 등에 대한 타입 정보를 정의</p>
<h4 id="2-타입-추론-지원">2. 타입 추론 지원</h4>
<p>: JavaScript로 작성된 코드에 대한 타입 추론을 지원하여, TypeScript로 작성된 코드에서 해당 라이브러리를 안전하게 사용할 수 있게 함</p>
<hr>
<h2 id="📘-dts-파일-만드는-방법">📘 .d.ts 파일 만드는 방법</h2>
<h4 id="1-타입-정의">1. 타입 정의</h4>
<pre><code>// myLibrary.d.ts
declare function greet(name: string): string;</code></pre><ul>
<li><code>declare function</code> :이 함수가 어디선가 정의되어 있다</li>
<li><code>greet(name: string): greet</code> :  함수는 name이라는 매개변수를 받고, 이 매개변수의 타입이 string이라는 걸 알려줌</li>
<li><code>: string</code>: 이 부분은 greet 함수가 문자열을 반환한다는 걸 의미</li>
</ul>
<h4 id="2-모듈-정의">2. 모듈 정의</h4>
<pre><code>// myLibrary.d.ts
declare module &quot;my-library&quot; {
    export function greet(name: string): string;
}</code></pre><h4 id="3-인터페이스와-타입-정의">3. 인터페이스와 타입 정의</h4>
<pre><code>// shapes.d.ts
interface Rectangle {
    width: number;
    height: number;
}

declare function calculateArea(rect: Rectangle): number;</code></pre><hr>
<h2 id="📌-정리">📌 정리</h2>
<ul>
<li>.d.ts 파일은 여러 함수, 모듈, 인터페이스, 클래스 등에 대한 타입 정보를 한 곳에서 모아서 정의해주는 역할을 한다. </li>
<li>이를 통해 코드를 사용할 때 안전성과 편리함을 높일 수 있다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[제네릭(Generics)]]></title>
            <link>https://velog.io/@s2__heee/%EC%A0%9C%EB%84%A4%EB%A6%ADGenerics</link>
            <guid>https://velog.io/@s2__heee/%EC%A0%9C%EB%84%A4%EB%A6%ADGenerics</guid>
            <pubDate>Fri, 01 Nov 2024 00:40:44 GMT</pubDate>
            <description><![CDATA[<h2 id="📘-제네릭generics">📘 제네릭(Generics)</h2>
<ul>
<li>함수나 클래스가 <strong>여러 타입을 받을 수 있게</strong> 해주는 방법
: 예를 들어, 숫자를 담는 배열과 문자열을 담는 배열을 만드려고 할때, 제네릭을 사용하면 하나의 함수 or 클래스를 만들어 어떤 타입의 배열이든 처리 가능!</li>
<li>제네릭을 사용하면 코드를 더 유연하고 재사용 가능해짐</li>
</ul>
<pre><code>function printArray&lt;T&gt;(items: T[]) {
    items.forEach(item =&gt; console.log(item));
}</code></pre><ul>
<li>&lt;T&gt;<ul>
<li>변수 이름 바로 뒤에 &lt;T&gt; 붙임</li>
<li>타입 매개변수</li>
<li>T는 나중에 어떤 타입이든 대체할 수 있는 자리표시자</li>
</ul>
</li>
</ul>
<hr>
<h2 id="📘-map">📘 Map</h2>
<pre><code>const stock = new Map&lt;string, number&gt;(); //Map 객체 생성 
stock.set(&#39;g001&#39;, 1);
stock.set(&#39;g002&#39;, 2);
console.log(stock.get(&#39;g001&#39;));
console.log(stock.get(&#39;g002&#39;));</code></pre><ul>
<li>Map은 키(key)로는 문자열(string), 값(value)으로는 숫자(number)를 가지는 자료구조, 자바스크립트에서 제공하는 특별한 객체</li>
<li>stock.set(&#39;g001&#39;, 1);
: 키 &#39;g001&#39;에 대해 값 1을 추가</li>
</ul>
<hr>
<h2 id="📘-set">📘 Set</h2>
<ul>
<li>고유한 값의 집합을 나타내는 객체</li>
<li>중복된 요소 추가 불가능, 동일한 값이 추가되면 무시</li>
<li>값이 삽입된 순서를 기억</li>
<li>다양한 타입 저장 가능</li>
<li>빠른 조회 가능</li>
<li>타입을 지정하지 않으면 Set 안에 숫자, 문자열 등 다양한 타입의 값을 모두 포함할 수 있음</li>
<li>배열과 비슷하지만 수학에서 집합에 해당하는 자료구조<pre><code>const mySet =  new Set&lt;number&gt;(); // 타입을 생성자에서 지정
</code></pre></li>
</ul>
<p>// 값 추가
mySet.add(1);
mySet.add(2);
mySet.add(3);
mySet.add(2); // 중복이므로 무시됨</p>
<p>console.log(mySet); // Set(3) { 1, 2, 3 }</p>
<p>// 값 조회
console.log(mySet.has(2)); // true
console.log(mySet.has(4)); // false</p>
<p>// 값 삭제
mySet.delete(2);
console.log(mySet); // Set(2) { 1, 3 }</p>
<p>// Set의 크기
console.log(mySet.size); // 2</p>
<p>// Set 순회
mySet.forEach(value =&gt; {
    console.log(value); // 1, 3
});</p>
<pre><code>
- 타입 지정 안 하는 경우
:  Set 안에 숫자, 문자열 등 다양한 타입의 값을 모두 포함</code></pre><p>const mixedSet = new Set();</p>
<p>mixedSet.add(1);          // 숫자
mixedSet.add(&quot;hello&quot;);   // 문자열
mixedSet.add(true);      // 불리언
mixedSet.add({ key: &quot;value&quot; }); // 객체</p>
<p>console.log(mixedSet); // Set(4) { 1, &quot;hello&quot;, true, { key: &quot;value&quot; } }</p>
<pre><code></code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[keyof와 typeof 연산자]]></title>
            <link>https://velog.io/@s2__heee/keyof%EC%99%80-typeof-%EC%97%B0%EC%82%B0%EC%9E%90</link>
            <guid>https://velog.io/@s2__heee/keyof%EC%99%80-typeof-%EC%97%B0%EC%82%B0%EC%9E%90</guid>
            <pubDate>Thu, 31 Oct 2024 08:43:58 GMT</pubDate>
            <description><![CDATA[<h2 id="📘-keyof와-typeof-연산자">📘 keyof와 typeof 연산자</h2>
<ul>
<li>타입스크립트에서 타입을 <strong>추론하고 조합</strong>하는 데 유용하게 사용되는 기능</li>
</ul>
<hr>
<h2 id="📘-typeof-연산자">📘 typeof 연산자</h2>
<ul>
<li>이미 선언된 변수나 객체의 타입을 가져오는 데 사용</li>
<li>런타임 객체의 타입을 컴파일타임 타입으로 변환</li>
<li>변수의 타입을 가져와서 새로운 타입을 정의</li>
<li>코드가 변경되더라도 타입이 자동으로 업데이트되기 때문에, 코드의 안전성과 유지보수성을 높이는 데 큰 도움이 됨!</li>
</ul>
<pre><code>const person = {
    name: &quot;Alice&quot;,
    age: 30
};

/// person 변수가 가지는 타입을 가져옴
// 새로운 타입으로 정의
type PersonType = typeof person; // { name: string; age: number; }</code></pre><hr>
<h2 id="📘-keyof-연산자">📘 keyof 연산자</h2>
<ul>
<li>객체의 속성 이름을 타입으로 가져올 수 있음</li>
<li>속성 이름을 나타내는 문자열 리터럴 타입을 정의</li>
<li>문자열 리터럴 타입으로, 타입들 중 하나의 값을 가지면 됨
😀 즉, PersonKeys는 &quot;name&quot; 또는 &quot;age&quot;라는 두 개의 문자열 값을 가짐!<pre><code>type PersonKeys = keyof PersonType; // &quot;name&quot; | &quot;age&quot;</code></pre></li>
</ul>
<pre><code>const car = {
    make: &quot;Toyota&quot;,
    model: &quot;Camry&quot;,
    year: 2020
};

// 1. car 객체의 타입을 정의
type CarType = typeof car; 
// { make: string; model: string; year: number; }

// 2. CarType의 키를 가져옴
type CarKeys = keyof CarType; 
// &quot;make&quot; | &quot;model&quot; | &quot;year&quot;

// 3. 속성 값을 가져오는 함수 정의
function getCarValue(key: CarKeys) {
    return car[key]; // car 객체의 속성에 접근
}

// 4. 함수 호출
console.log(getCarValue(&quot;make&quot;));  // &quot;Toyota&quot;
console.log(getCarValue(&quot;model&quot;)); // &quot;Camry&quot;
console.log(getCarValue(&quot;year&quot;));  // 2020</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[인터섹션 타입 (Intersection Type)]]></title>
            <link>https://velog.io/@s2__heee/%EC%9D%B8%ED%84%B0%EC%84%B9%EC%85%98-%ED%83%80%EC%9E%85-Intersection-Type</link>
            <guid>https://velog.io/@s2__heee/%EC%9D%B8%ED%84%B0%EC%84%B9%EC%85%98-%ED%83%80%EC%9E%85-Intersection-Type</guid>
            <pubDate>Thu, 31 Oct 2024 08:13:43 GMT</pubDate>
            <description><![CDATA[<h2 id="📘-인터섹션-타입-intersection-type">📘 인터섹션 타입 (Intersection Type)</h2>
<ul>
<li>여러 타입을 결합하여 모든 속성을 포함. type A = B &amp; C;</li>
<li>두 개 이상의 타입을 결합하여, 모든 타입의 속성을 포함하는 새로운 타입을 정의할 때 사용
😀 즉, 두개의 타입을 결합&gt; 하나의 타입 EmployeePerson으로 새로 정의해서 사용<pre><code>interface Person {
  name: string;
  age: number;
}
</code></pre></li>
</ul>
<p>interface Employee {
    employeeId: number;
}</p>
<p>type EmployeePerson = Person &amp; Employee;</p>
<p>let employee: EmployeePerson = {
    name: &quot;Alice&quot;,
    age: 30,
    employeeId: 12345
}; // 올바른 값</p>
<pre><code>
## 📘 타입을 여러 개로 나누고 인터섹션 타입을 사용하는 이유?

🖐🏻 타입을 하나로 합쳐서 사용하면 될거같은데, 왜 굳이 두개의 타입을 결합해서 새로운 타입을 만들어 사용할까?

#### 1. 모듈화와 재사용성
타입을 별개로 정의하면, 그 타입들을 다른 곳에서 재사용 가능!

#### 2. 유지보수
타입을 개별적으로 정의하면, 나중에 변경이 필요할 때 더 쉽게 수정 가능

#### 3. 명확한 의도
각 타입이 무엇을 의미하는지를 명확히 구분가능하여, 코드의 가독성 향상

#### 4. 타입 안전성
인터섹션을 사용하면 서로 다른 타입의 조합을 명확히 정의, 오류 더 잘 잡아낼 수 있음

---------
## 📘 리터럴 타입과 객체타입의 교집합

- 리터럴 타입: 교집합은 두 타입에서 공통적으로 포함된 값만 가능.</code></pre><p>type A = &#39;바나나&#39; | &#39;바닐라&#39;;
type B = &#39;바나나&#39; | &#39;딸기&#39;;
type C = A &amp; B; // C는 &#39;바나나&#39;만 가능</p>
<pre><code>
- 객체 타입: 교집합은 두 타입의 모든 속성을 포함</code></pre><p>interface Person {
    name: string;
    age: number;
}</p>
<p>interface Employee {
    employeeId: number;
}</p>
<p>type EmployeePerson = Person &amp; Employee;
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[유니온 타입(Union Type)]]></title>
            <link>https://velog.io/@s2__heee/%EC%9C%A0%EB%8B%88%EC%98%A8-%ED%83%80%EC%9E%85Union-Type</link>
            <guid>https://velog.io/@s2__heee/%EC%9C%A0%EB%8B%88%EC%98%A8-%ED%83%80%EC%9E%85Union-Type</guid>
            <pubDate>Thu, 31 Oct 2024 08:04:38 GMT</pubDate>
            <description><![CDATA[<h2 id="📘-유니온-타입union-type">📘 유니온 타입(Union Type)</h2>
<ul>
<li>여러 타입 중 하나를 허용하는 타입을 정의할 때 사용</li>
<li>변수나 매개변수가 여러 타입 중 하나의 값을 가질 수 있도록 함</li>
<li>유니온 타입을 사용하면 변수가 어떤 값으로 초기화되든지, 그 값이 정의된 타입 중 하나여야 함
😀 즉 아래 코드에는 타입이 문자열이거나 숫자이면 됨!</li>
</ul>
<pre><code>type StringOrNumber = string | number;

let value: StringOrNumber;

value = &quot;Hello&quot;; // 올바른 값
value = 42;     // 올바른 값
value = true;   
// 오류: Type &#39;boolean&#39; is not assignable to type &#39;StringOrNumber&#39;</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[리터럴 타입]]></title>
            <link>https://velog.io/@s2__heee/%EB%A6%AC%ED%84%B0%EB%9F%B4-%ED%83%80%EC%9E%85</link>
            <guid>https://velog.io/@s2__heee/%EB%A6%AC%ED%84%B0%EB%9F%B4-%ED%83%80%EC%9E%85</guid>
            <pubDate>Thu, 31 Oct 2024 07:34:36 GMT</pubDate>
            <description><![CDATA[<h2 id="📘-리터럴-타입">📘 리터럴 타입</h2>
<ul>
<li>특정한 값만을 허용하는 타입</li>
<li>문자열, 숫자, 불리언과 같은 기본 타입을 기반으로 하여, 특정 값만을 갖도록 제한할 수 있음</li>
<li>더 강력한 타입 체크가 가능해지며, 의도한 값만 사용하게 되어 코드의 품질이 향상</li>
</ul>
<h4 id="1-문자열-리터럴-타입">1. 문자열 리터럴 타입</h4>
<pre><code>type Direction = &quot;up&quot; | &quot;down&quot; | &quot;left&quot; | &quot;right&quot;;

let move: Direction;

move = &quot;up&quot;;    // 올바른 값
move = &quot;down&quot;;  // 올바른 값
move = &quot;left&quot;;  // 올바른 값
move = &quot;right&quot;; // 올바른 값
move = &quot;forward&quot;; 
// 오류: Type &#39;&quot;forward&quot;&#39; is not assignable to type &#39;Direction&#39;</code></pre><h4 id="2-숫자-리터럴-타입">2. 숫자 리터럴 타입</h4>
<pre><code>type StatusCode = 200 | 404 | 500;

let code: StatusCode;

code = 200; // 올바른 값
code = 404; // 올바른 값
code = 500; // 올바른 값
code = 300; // 오류: Type &#39;300&#39; is not assignable to type &#39;StatusCode&#39;</code></pre><ul>
<li>200 , 404, 500은 초기화값이자 타입,</li>
<li>타입스크립트는 자동으로 이 값들이 숫자 타입임을 인식</li>
</ul>
<h4 id="3-불리언-리터럴-타입">3. 불리언 리터럴 타입</h4>
<pre><code>type IsEnabled = true | false;

let enabled: IsEnabled;

enabled = true;  // 올바른 값
enabled = false; // 올바른 값
enabled = null;  // 오류: Type &#39;null&#39; is not assignable to type &#39;IsEnabled&#39;</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[enum]]></title>
            <link>https://velog.io/@s2__heee/enum</link>
            <guid>https://velog.io/@s2__heee/enum</guid>
            <pubDate>Thu, 31 Oct 2024 07:23:04 GMT</pubDate>
            <description><![CDATA[<h2 id="📘-enum">📘 enum</h2>
<ul>
<li><p>타입스크립트에서 특정 값들의 집합을 정의하는데 사용되는 데이터 구조</p>
</li>
<li><p>관련된 상수 값들의 집합</p>
</li>
<li><p>기본적으로 숫자 값을 자동으로 할당</p>
</li>
<li><p>초기화 시, 이름을 붙여주면 코드의 의미를 명확하게 전달 및 잘못된 값을 넣을 위험 방지 </p>
</li>
<li><p>코드의 가독성을 높이고, 유지보수를 쉽게 하며, 오류를 방지하고, 타입 안전성을 보장</p>
</li>
</ul>
<h3 id="1-기본-enum">1. 기본 Enum</h3>
<pre><code>enum Direction {
    Up,    // 0
    Down,  // 1
    Left,  // 2
    Right  // 3
}

let move: Direction = Direction.Up;

console.log(move); // 1</code></pre><ul>
<li>초기화값에 이름을 주는 방식으로 각 값을 정의</li>
</ul>
<h3 id="2-문자열-enum">2. 문자열 Enum</h3>
<pre><code>enum Color {
    Red = &quot;RED&quot;,
    Green = &quot;GREEN&quot;,
    Blue = &quot;BLUE&quot;
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[함수의 타입 정의]]></title>
            <link>https://velog.io/@s2__heee/%ED%95%A8%EC%88%98%EC%9D%98-%ED%83%80%EC%9E%85-%EC%A0%95%EC%9D%98</link>
            <guid>https://velog.io/@s2__heee/%ED%95%A8%EC%88%98%EC%9D%98-%ED%83%80%EC%9E%85-%EC%A0%95%EC%9D%98</guid>
            <pubDate>Thu, 31 Oct 2024 07:03:05 GMT</pubDate>
            <description><![CDATA[<h2 id="📘-기본적인-함수-타입-정의">📘 기본적인 함수 타입 정의</h2>
<ul>
<li>함수의 매개변수와 반환값의 타입을 직접 지정하는 방법<pre><code>function greet(name: string): string {
  return `Hello, ${name}!`;
}
</code></pre></li>
</ul>
<p>const message: string = greet(&quot;Alice&quot;); // &quot;Hello, Alice!&quot;</p>
<pre><code>- (name: string) : 매개변수의 타입
- : string : 반환값의 타입

---------

## 📘 인터페이스를 사용한 함수 타입 정의

- 여러 개의 함수를 동일한 타입으로 묶을 때 유용</code></pre><p>interface Greet { // ❗❗ 함수 인터페이스
    (name: string): string; // 앞은 매개변수타입, 뒤 반환값의 타입
}</p>
<p>const greet: Greet = (name) =&gt; {
    return <code>Hello, ${name}!</code>;
};</p>
<p>const message = greet(&quot;Charlie&quot;); // &quot;Hello, Charlie!&quot;</p>
<pre><code>- const greet: Greet = (name) =&gt; 
: greet이라는 변수를 선언하여, Greet라는 인터페이스를 타입으로 가짐, (name)이라는 문자열을 매개변수로 받아, 문자열를 반환함

----
## 📘 타입 별칭을 사용한 함수 타입 정의
</code></pre><p>type GreetFunction = (name: string) =&gt; string;</p>
<p>const greet: GreetFunction = (name) =&gt; {
    return <code>Hello, ${name}!</code>;
};</p>
<p>const message = greet(&quot;Bob&quot;); // &quot;Hello, Bob!&quot;</p>
<pre><code>- type 키워드를 사용하여 함수 타입을 별칭으로 정의
- GreetFunction 이라는 이름의 타입 별칭을 정의
- (name: string) : 매개변수의 타입 정의
- =&gt; string : 반환값의 타입 정의 </code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[타입스크립트의 기본형]]></title>
            <link>https://velog.io/@s2__heee/%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%9D%98-%EA%B8%B0%EB%B3%B8%ED%98%95</link>
            <guid>https://velog.io/@s2__heee/%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%9D%98-%EA%B8%B0%EB%B3%B8%ED%98%95</guid>
            <pubDate>Thu, 31 Oct 2024 06:23:12 GMT</pubDate>
            <description><![CDATA[<h2 id="📘-타입스크립트의-기본형primitive-types">📘 타입스크립트의 기본형(Primitive Types)</h2>
<ol>
<li>number : 모든 숫자를 나타냄</li>
<li>string : 문자열, 작은따옴표(&#39;), 큰따옴표(&quot;), 백틱(```)을 사용해 생성 가능</li>
<li>boolean : 참 or 거짓을 나타냄</li>
<li>null : 의도적으로 값이 없음(내가 주는 값 / 수를 초기화할 때 null을 할당하면, 그 변수는 &quot;현재는 값이 없다&quot;는 의미)</li>
<li>undefined : 변수 선언되었으나, 초기화 하지 않아 값이 할당되지 않은 상태</li>
<li>void : 주로 함수에서 반환 값이 없음을 나타냄.<pre><code>function logMessage(message: string): void {
 console.log(message);
}</code></pre></li>
<li>symbol : 고유하고 변경 불가능한 값, 주로 객체의 고유한 프로퍼티 키 만들 때 사용<pre><code>let uniqueId: symbol = Symbol(&quot;id&quot;);</code></pre></li>
<li>bigint : 큰 정수를 나타내는 타입, number 타입의 범위를 초과하는 정수<pre><code>let bigNumber: bigint = 1234567890123456789012345678901234567890n;</code></pre></li>
</ol>
<hr>
<h2 id="📘-배열과-튜플">📘 배열과 튜플</h2>
<h3 id="1-배열-array">1. 배열 (Array)</h3>
<ul>
<li>동일한 타입의 요소를 순차적으로 저장하는 자료 구조</li>
<li>배열은 크기가 없다(빈 배열로 해도 오류X)<pre><code>// 숫자 배열
let numbers: number[] = [1, 2, 3, 4, 5];
</code></pre></li>
</ul>
<p>// 문자열 배열
let fruits: string[] = [&quot;apple&quot;, &quot;banana&quot;, &quot;cherry&quot;];</p>
<p>// 여러 타입을 포함하는 배열 (any 사용)
let mixed: any[] = [1, &quot;apple&quot;, true];</p>
<pre><code>
### 2. 튜플 (Tuple)
- 고정된 수의 요소를 가진 배열
-  각 요소는 서로 다른 타입</code></pre><p>// 튜플: 문자열과 숫자를 포함하는 고정된 길이의 배열
let person: [string, number] = [&quot;Alice&quot;, 30];</p>
<p>// 튜플의 요소 접근
console.log(person[0]); // &quot;Alice&quot;
console.log(person[1]); // 30</p>
<p>// 잘못된 타입의 요소 할당 시 오류 발생
// person[0] = 123; 
// 오류: Type &#39;number&#39; is not assignable to type &#39;string&#39;</p>
<pre><code>
----------

## 📘 객체타입
### 1. 인터페이스 (Interface)
- 객체의 구조를 정의하는 방법(설명서)으로, 속성과 타입을 명시</code></pre><p>interface Person {
    name: string;
    age: number;
    isStudent?: boolean; // 선택적 속성
}</p>
<p>// 객체 생성
const user: Person = {
    name: &quot;Alice&quot;,
    age: 30,
};</p>
<p>// 선택적 속성 사용
const student: Person = {
    name: &quot;Bob&quot;,
    age: 20,
    isStudent: true, // 선택적으로 추가
};</p>
<pre><code>
### 2. 타입 별칭 (Type Alias)
- 객체의 구조를 정의하는 또 다른 방법으로, type 키워드를 사용
- 인터페이스와 비슷하지만, 더 다양한 형태의 타입을 정의</code></pre><p>type Car = {
    brand: string;
    model: string;
    year: number;
};</p>
<p>const myCar: Car = {
    brand: &quot;Toyota&quot;,
    model: &quot;Camry&quot;,
    year: 2022,
};</p>
<pre><code>-------

## 📘 any
- 타입스크립트에서 가장 유연한 타입으로, 어떤 값이든 허용할 수 있는 타입
- 타입오류가 사라짐
- 필요한 경우에만 사용하고, 가능한 구체적인 타입을 지정하는 것이 좋다
(기존 자바스크립트 코드에서 타입스크립트를 도입할 때 유용하게 사용할 수 있어. 처음에는 any로 타입을 지정한 후, 점차적으로 더 구체적인 타입으로 변경 등)</code></pre><p>let value: any;</p>
<p>// 다양한 타입의 값 할당 가능
value = 42;                // 숫자
value = &quot;Hello, world!&quot;;  // 문자열
value = true;             // 불리언
value = { name: &quot;Alice&quot; }; // 객체</p>
<pre><code></code></pre>]]></description>
        </item>
    </channel>
</rss>