<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>on-n-on-turtle.log</title>
        <link>https://velog.io/</link>
        <description>몇 번을 넘어져도 앞으로 계속 나아가자</description>
        <lastBuildDate>Sun, 23 Oct 2022 07:03:13 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>on-n-on-turtle.log</title>
            <url>https://velog.velcdn.com/images/on-n-on-turtle/profile/b3d8a848-3b8c-4811-b94b-d7ef3b6272e6/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. on-n-on-turtle.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/on-n-on-turtle" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[😶‍🌫️ [엉짧식] 문자열의 첫 글자가 숫자인지 문자인지 알아보았다]]></title>
            <link>https://velog.io/@on-n-on-turtle/%EC%97%89%EC%A7%A7%EC%8B%9D-%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%98-%EC%B2%AB-%EA%B8%80%EC%9E%90%EA%B0%80-%EC%88%AB%EC%9E%90%EC%9D%B8%EC%A7%80-%EB%AC%B8%EC%9E%90%EC%9D%B8%EC%A7%80-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0</link>
            <guid>https://velog.io/@on-n-on-turtle/%EC%97%89%EC%A7%A7%EC%8B%9D-%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%98-%EC%B2%AB-%EA%B8%80%EC%9E%90%EA%B0%80-%EC%88%AB%EC%9E%90%EC%9D%B8%EC%A7%80-%EB%AC%B8%EC%9E%90%EC%9D%B8%EC%A7%80-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0</guid>
            <pubDate>Sun, 23 Oct 2022 07:03:13 GMT</pubDate>
            <description><![CDATA[<h3 id="💟-span-stylecolorredstringcharat-과-아스키코드를-사용하면-된다span">💟 <span style="color:red;"><code>String.charAt()</code> 과 아스키코드를 사용하면 된다.</span></h3>
<h3 id="💟-span-stylecolorred문자-char-09-는-int-4857-이다span">💟 <span style="color:red;">문자 <code>char</code> <code>0~9</code> 는 <code>int</code> <code>48~57</code> 이다.</span></h3>
<h3 id="💟-span-stylecolorred문자-char-az는-int-6590-이다span">💟 <span style="color:red;">문자 <code>char A~Z</code>는 <code>int 65~90</code> 이다.</span></h3>
<h3 id="💟-span-stylecolorred문자-char-az는-int-97122-이다span">💟 <span style="color:red;">문자 <code>char a~z</code>는 <code>int 97~122</code> 이다.</span></h3>
<h3 id="💟-그러므로-span-stylecolorred-stringcharat0--48--stringcharat0--57-이면-문자열의-첫-글자는-숫자이다span">💟 그러므로 <span style="color:red;"> <code>String.charAt(0) &gt;= 48 &amp;&amp; String.charAt(0) &lt;= 57</code> 이면 문자열의 첫 글자는 숫자이다.</span></h3>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/7c0956ef-5e96-47d8-b82e-988fa538c08f/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[😶‍🌫️ [엉짧식] JAVA로 첫 글자만 대문자화 해보았다]]></title>
            <link>https://velog.io/@on-n-on-turtle/%EC%97%89%EC%A7%A7%EC%8B%9D-JAVA%EB%A1%9C-%EC%B2%AB-%EA%B8%80%EC%9E%90%EB%A7%8C-%EB%8C%80%EB%AC%B8%EC%9E%90%ED%99%94-%ED%95%B4%EB%B3%B4%EC%95%98%EB%8B%A4</link>
            <guid>https://velog.io/@on-n-on-turtle/%EC%97%89%EC%A7%A7%EC%8B%9D-JAVA%EB%A1%9C-%EC%B2%AB-%EA%B8%80%EC%9E%90%EB%A7%8C-%EB%8C%80%EB%AC%B8%EC%9E%90%ED%99%94-%ED%95%B4%EB%B3%B4%EC%95%98%EB%8B%A4</guid>
            <pubDate>Sun, 09 Oct 2022 11:00:24 GMT</pubDate>
            <description><![CDATA[<h1 id="java로-첫-글자만-대문자화--strsubstring01touppercase--strsubstring1">JAVA로 첫 글자만 대문자화 : str.substring(0,1).toUpperCase() + str.substring(1);</h1>
<p><br><br></p>
<hr>
<p><br><br></p>
<h3 id="string-str--moon"><code>String str = &quot;mOoN&quot;;</code></h3>
<br>

<h3 id="🌟-전체-소문자화-⬇️">🌟 전체 소문자화 ⬇️</h3>
<h3 id="strtolowercase"><code>str.toLowerCase()</code>;</h3>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/b3a94a6e-b01f-4c6f-9724-b8b4606f25ce/image.png" alt=""></p>
<br>

<h3 id="🌟-전체-대문자화-⬇️">🌟 전체 대문자화 ⬇️</h3>
<h3 id="strtouppercase"><code>str.toUpperCase()</code>;</h3>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/66904333-87c9-4340-a72a-5958fed00d86/image.png" alt=""></p>
<br>

<h3 id="🌟-첫-글자만-대문자화-⬇️">🌟 첫 글자만 대문자화 ⬇️</h3>
<h3 id="strsubstring01touppercase--strsubstring1"><code>str.substring(0,1).toUpperCase() + str.substring(1);</code></h3>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/20b88873-7831-4396-b48f-f9100f5325b3/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바의 정석 완독 시리즈 목차 ]]></title>
            <link>https://velog.io/@on-n-on-turtle/%EC%9E%90%EB%B0%94%EC%9D%98-%EC%A0%95%EC%84%9D-%EC%99%84%EB%8F%85-%EC%8B%9C%EB%A6%AC%EC%A6%88-%EB%AA%A9%EC%B0%A8</link>
            <guid>https://velog.io/@on-n-on-turtle/%EC%9E%90%EB%B0%94%EC%9D%98-%EC%A0%95%EC%84%9D-%EC%99%84%EB%8F%85-%EC%8B%9C%EB%A6%AC%EC%A6%88-%EB%AA%A9%EC%B0%A8</guid>
            <pubDate>Sun, 09 Oct 2022 02:49:07 GMT</pubDate>
            <description><![CDATA[<h1 id="🟪-변수">🟪 변수</h1>
<h1 id="🟪-객체지향-프로그래밍-i">🟪 객체지향 프로그래밍 I</h1>
<h1 id="🟪-객체지향-프로그래밍-ii">🟪 객체지향 프로그래밍 II</h1>
<h1 id="🟪-예외처리">🟪 예외처리</h1>
<h1 id="🟪-javalang패키지와-유용한-클래스">🟪 java.lang패키지와 유용한 클래스</h1>
<h1 id="🟪-컬렉션-프레임웍">🟪 컬렉션 프레임웍</h1>
<h1 id="🟪-지네릭스-열거형-애너테이션">🟪 지네릭스, 열거형, 애너테이션</h1>
<h1 id="🟪-쓰레드">🟪 쓰레드</h1>
<h1 id="🟪-람다와-스트림">🟪 람다와 스트림</h1>
<h1 id="🟪-입출력">🟪 입출력</h1>
<h1 id="🟪-네트워킹">🟪 네트워킹</h1>
]]></description>
        </item>
        <item>
            <title><![CDATA[👝 나의 첫 코바늘 파우치 🌹]]></title>
            <link>https://velog.io/@on-n-on-turtle/%EB%82%98%EC%9D%98-%EC%B2%AB-%EC%BD%94%EB%B0%94%EB%8A%98-%ED%8C%8C%EC%9A%B0%EC%B9%98</link>
            <guid>https://velog.io/@on-n-on-turtle/%EB%82%98%EC%9D%98-%EC%B2%AB-%EC%BD%94%EB%B0%94%EB%8A%98-%ED%8C%8C%EC%9A%B0%EC%B9%98</guid>
            <pubDate>Thu, 06 Oct 2022 10:54:37 GMT</pubDate>
            <description><![CDATA[<p>요즘 코바늘에 빠졌다
코바늘을 하면 걱정도 덜어주고 집중력도 높아지는 느낌이다.
그래서 요즘 마음도 더욱 안정되고 공부도 더욱 잘 되어가고 있다.</p>
<p>가을의 맑은 하늘처럼 내 마음도 맑아졌으면 좋겠다.
이 파우치가 완성 된 것 처럼 나의 우테코 준비도 잘 완성되었으면 좋겠다.
내년에는 우테코에 참여할 수 있었으면 좋겠다.</p>
<p>이 파우치에 행운이 가득 담겨서 내 바람이 이루어졌으면 좋겠다.
(앗, 구멍 송송 네트 무늬인데... 행운이 다 빠져나가는 건...ㅎ)</p>
<p>💓 코바늘 파우치 완성 과정 ⬇️ 💓</p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/3383c8a4-a3f6-4ae6-90e3-aeea9dfec666/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/bf55204f-e271-49c5-b558-8a1be3aaa7dd/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/99272cc3-d922-45af-b42e-37a5dc6ecaa9/image.jpg" alt=""></p>
<p>처음 만들어본 거라서 그런지 여기저기 엉성한 부분이 많다 헤헤 😉</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[😶‍🌫️ [엉짧식] LRU를 알아보았다]]></title>
            <link>https://velog.io/@on-n-on-turtle/%EC%97%89%EC%A7%A7%EC%8B%9D-LRU%EB%A5%BC-%EC%95%8C%EC%95%84%EB%B3%B4%EC%95%98%EB%8B%A4</link>
            <guid>https://velog.io/@on-n-on-turtle/%EC%97%89%EC%A7%A7%EC%8B%9D-LRU%EB%A5%BC-%EC%95%8C%EC%95%84%EB%B3%B4%EC%95%98%EB%8B%A4</guid>
            <pubDate>Tue, 04 Oct 2022 14:46:46 GMT</pubDate>
            <description><![CDATA[<p>--</p>
<h1 id="🟪-cache-hit">🟪 <code>Cache Hit</code></h1>
<p><span style="background-color:yellow; color:black;"><strong>메모리가 캐시에 존재하고 있을 경우</strong></span> <code>Cache Hit</code>라고 한다.</p>
<h1 id="🟪-cache-miss">🟪 <code>Cache Miss</code></h1>
<p><span style="background-color:yellow; color:black;"><strong>메모리가 캐시에 존재하지 않을 때</strong></span> <code>Cache Miss</code>라고 한다.</p>
<h1 id="🟪-least-recently-used">🟪 <code>Least Recently Used</code></h1>
<p><span style="color:red;"><strong>가장 오랫동안 &quot;참조&quot;되지 않은 페이지를 교체하는 방식</strong></span>이다. <span style="color:red;"><strong>캐시가 가득 찼을때, 가장 오랫동안 참조되지 않은 페이지를 찾아서 없애는 과정</strong></span>이 필요하다.
사용된지 가장 오래된 페이지는 앞으로도 사용될 확률이 낮다는 가설에 의해 만들어진 알고리즘이다.</p>
<h2 id="💟-원리">💟 원리</h2>
<p><span style="background-color:yellow; color:black;"><strong>가장 오랫동안 참조되지 않은 페이지를 찾아서 없애는 과정</strong></span></p>
<ul>
<li><p><span style="background-color:yellow; color:black;"><strong>페이지를 새로 참조할 때마다 연결리스트의 맨 앞에 페이지번호를 추가</strong></span>한다.<br>그러면 맨 뒤에 있는 페이지번호가 가장 오랫동안 참조되지 않은 페이지번호가 된다.</p>
</li>
<li><p><span style="background-color:yellow; color:black;"><strong><code>Doubly Linked List</code> 를 사용하고 <code>head</code> 에 가까운 <code>node</code> 일수록 가장 최근에 참조된 페이지, <code>tail</code> 에 가까운 <code>node</code> 일수록 가장 오랫동안 참조되지 않는 페이지이다.</strong></span></p>
<ul>
<li><code>hit</code> 일 때 : 기존 페이지 삭제 후 맨 앞에 다시 추가</li>
<li><code>miss</code> 일 때 : 맨 앞에 추가</li>
<li><code>cache size</code> 를 넘어서게 될 때 : <code>tail</code> 에 가장 가까운 페이지 삭제 후 맨 앞에 다시 추가</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/fb35df24-8bc1-49f9-b68d-9b9f21552f72/image.png" alt=""></p>
<p>캐시의 크기는 3이다.
새로운 참조값은 맨 앞에 추가한다.
이미 3개의 참조값이 캐시에 들어있다면 맨 뒤에 있는 참조값을 제거하고 새로운 참조값을 맨 앞에 추가한다.
새로운 참조값이 이미 캐시에 들어있는 값이라면 기존 위치에서 제거하고 다시 맨 앞에 추가한다.</p>
<blockquote>
</blockquote>
<ul>
<li>캐시 리스트의 크기는 <code>3</code> 이다.<br></li>
<li><code>참조값 1</code> 이 캐시 리스트의 맨 앞에 추가된다.
↳ <code>miss</code> , <code>참조값 1</code>은 캐시리스트에 없는 값이므로.<br></li>
<li><code>참조값 2</code> 가 캐시 리스트의 맨 앞에 추가된다.
↳ <code>miss</code> , <code>참조값 2</code>는 캐시리스트에 없는 값이므로.<br></li>
<li><code>참조값 1</code> 이 캐시 리스트의 맨 앞에 추가된다.
↳ <span style="background-color:yellow; color:black;"><strong><code>hit</code> , <code>참조값 1</code>은 캐시리스트에 있던 값이므로 기존 위치에서 지워지고 다시 맨 앞에 추가 된다.</strong></span>`<br></li>
<li><code>참조값 3</code> 이 캐시 리스트의 맨 앞에 추가된다.
↳ <code>miss</code> , <code>참조값 3</code>는 캐시리스트에 없는 값이므로.<br></li>
<li><code>참조값 4</code> 가 캐시 리스트의 맨 앞에 추가된다.
↳ <code>miss</code> , <code>참조값 4</code>는 캐시리스트에 없는 값이므로.
: <span style="background-color:yellow; color:black;"><strong>캐시리스트가 가득 찼으므로 리스트의 맨 뒤에 있는 = 가장 오랫동안 참조되지 않은 <code>참조값 2</code>가 삭제되고, <code>참조값 4</code>가 캐시리스트의 맨 앞에 추가된다.</strong></span><br></li>
<li><code>참조값 1</code> 이 캐시 리스트의 맨 앞에 추가된다.
↳ <code>hit</code> , <code>참조값 1</code>은 캐시리스트에 있던 값이므로 기존 위치에서 지워지고 다시 맨 앞에 추가 된다.<br></li>
<li><code>참조값 5</code> 가 캐시 리스트의 맨 앞에 추가된다.
↳ <code>miss</code> , <code>참조값 5</code>는 캐시리스트에 없는 값이므로.
: 캐시리스트가 가득 찼으므로 리스트의 맨 뒤에 있는 = 가장 오랫동안 참조되지 않은 <code>참조값 3</code>이 삭제되고, <code>참조값 5</code>가 캐시리스트의 맨 앞에 추가된다.<br></li>
<li><code>참조값 4</code> 가 캐시 리스트의 맨 앞에 추가된다.
↳ <code>hit</code> , <code>참조값 4</code>는 캐시리스트에 있던 값이므로 기존 위치에서 지워지고 다시 맨 앞에 추가 된다.</li>
</ul>
<p><br><br><br><br><br><br></p>
<hr>
<h1 id="🦄-출처--이-글의-모든-내용과-사진들은-사과개발자의-일상-블로그의-lru-알고리즘-least-recentely-used-개념-및-구현방법-게시물에서-가져온-것입니다">🦄 출처 : <a href="https://dailylifeofdeveloper.tistory.com/355">이 글의 모든 내용과 사진들은 <code>사과개발자의 일상</code> 블로그의 <code>LRU 알고리즘 (Least Recentely Used) 개념 및 구현방법</code> 게시물에서 가져온 것입니다.</a></h1>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/f5171df9-3cc8-4c40-babf-7c3b6802ec33/image.png" alt=""></p>
<p>: <code>티스토리</code> 사이트의 <code>daily_D</code>님의 <code>사과개발자의 일상</code> 블로그의 <code>LRU 알고리즘 (Least Recentely Used) 개념 및 구현방법</code> 게시물</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 레벨2 캐시]]></title>
            <link>https://velog.io/@on-n-on-turtle/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%97%B0%EC%8A%B5-%EF%BD%9C-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%A0%88%EB%B2%A82-%EC%BA%90%EC%8B%9C</link>
            <guid>https://velog.io/@on-n-on-turtle/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%97%B0%EC%8A%B5-%EF%BD%9C-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%A0%88%EB%B2%A82-%EC%BA%90%EC%8B%9C</guid>
            <pubDate>Mon, 03 Oct 2022 16:49:07 GMT</pubDate>
            <description><![CDATA[<hr>
<h1 id="🟪-문제-바로가기">🟪 <a href="https://school.programmers.co.kr/learn/courses/30/lessons/17680">문제 바로가기</a></h1>
<p>이 글은 문제를 정리하고 저의 풀이를 보여드리는 거예요. 실제로 문제를 보고 풀어보세요. 클릭! 클릭! 해보세요! 🖱️</p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/1f99a43b-d60f-42d1-8fc2-c426272eaf11/image.png" alt=""></p>
<h1 id="🟪-문제-설명">🟪 문제 설명</h1>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/131a7fbc-a08f-45f1-9358-3f2df86d998b/image.png" alt=""></p>
<p>지도에서 도시 이름을 검색하면 해당 도시와 관련된 맛집 게시물들을 데이터베이스에서 읽어 보여주는 서비스를 개발하고 있다.</p>
<p>이 프로그램의 테스팅 업무를 담당하고 있는 어피치는 서비스를 오픈하기 전 각 로직에 대한 성능 측정을 수행하였는데
데이터베이스에서 게시물을 가져오는 부분의 실행시간이 너무 오래 걸린다는 것을 알게 되었다.</p>
<p>DB 캐시를 적용하여 성능 개선을 시도하고 있지만 캐시 크기를 얼마로 해야 효율적인지 몰라 난감한 상황이다.</p>
<p><strong>DB 캐시를 적용할 때 캐시 크기에 따른 실행시간 측정 프로그램을 작성하시오.</strong></p>
<h2 id="💟-입력-형식">💟 입력 형식</h2>
<ul>
<li>캐시 크기(<code>cacheSize</code>)와 도시이름 배열(<code>cities</code>)을 입력받는다.</li>
<li><code>cacheSize</code>는 정수이며, 범위는 <code>0 ≦ cacheSize ≦ 30</code> 이다.</li>
<li><code>cities</code>는 도시 이름으로 이뤄진 문자열 배열로, 최대 도시 수는 100,000개이다.</li>
<li>각 도시 이름은 공백, 숫자, 특수문자 등이 없는 영문자로 구성되며, 대소문자 구분을 하지 않는다. 도시 이름은 최대 20자로 이루어져 있다.</li>
</ul>
<h2 id="💟-출력-형식">💟 출력 형식</h2>
<p><strong>입력된 도시이름 배열을 순서대로 처리할 때, &quot;총 실행시간&quot;을 출력한다.</strong></p>
<h2 id="💟-조건">💟 조건</h2>
<ul>
<li>캐시 교체 알고리즘은 <code>LRU(Least Recently Used)</code>를 사용한다.</li>
<li><code>cache hit</code>일 경우 실행시간은 1이다.</li>
<li><code>cache miss</code>일 경우 실행시간은 5이다.</li>
</ul>
<h2 id="💟-입출력-예제">💟 입출력 예제</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/2eb9fce3-8962-4eb5-b676-f1309127c765/image.png" alt=""></p>
<h2 id="💟-추가-해설">💟 추가 해설</h2>
<p><strong>LRU 캐시 교체 알고리즘을 구현하는 문제</strong>이고,
검색해봤다면 잘 구현된 LRU 알고리즘 코드는 많이 찾을 수 있습니다.</p>
<p>단, 이 문제에는 입출력 예제에 캐시 사이즈 0이 포함되어 있습니다. 공개된 대부분의 <strong>LRU 구현 코드는 0일 때의 비정상적인 상황은 가정</strong>하지 않고 있기 때문에 생각 없이 그냥 가져와 붙인다면 에러가 나서 많이 고생했을 거 같네요. </p>
<p><strong>사이즈 0을 처리하는 예외 처리</strong> 자체는 어렵지 않게 구현할 수 있으므로 입출력 예제가 왜 자꾸 틀리는지를 유심히 살펴봤다면 쉽게 풀 수 있는 문제입니다.</p>
<h1 id="🟪-나의-로직">🟪 나의 로직</h1>
<h2 id="💟-lru--캐시-교체-알고리즘">💟 <a href="https://velog.io/@on-n-on-turtle/%EC%97%89%EC%A7%A7%EC%8B%9D-LRU%EB%A5%BC-%EC%95%8C%EC%95%84%EB%B3%B4%EC%95%98%EB%8B%A4"><code>LRU</code>  캐시 교체 알고리즘</a></h2>
<h2 id="💟-linkedlist-자료구조">💟 <a href="https://velog.io/@on-n-on-turtle/JAVA-ArrayList-vs-LinkedList">LinkedList 자료구조</a></h2>
<ul>
<li>주어진 도시이름 배열 <code>cities</code> 을 읽을 때마다 캐시 교체시간이 생기고 그 교체시간들을 전부 더 하면 총 실행시간이 나온다. </li>
<li><code>LinkedList.contains()</code> : <code>cache hit</code> 과 <code>cache miss</code> 을 구별</li>
<li><code>cache hit</code> : 기존 데이터 지우고 맨 앞에 새로 추가한다.
<code>LinkedList.remove()</code> ➡️ <code>LinkedList.addFirst()</code></li>
<li><code>cache miss</code> : 맨 앞에 새로 추가한다.
<code>LinkedList.addFirst()</code> </li>
<li><code>cache miss</code> &amp;&amp; 캐시가 가득 찼을 때 : 맨 뒤의 데이터를 지우고 맨 앞에 새로 추가한다.
<code>LinkedList.removeLast()</code> ➡️ <code>LinkedList.addFirst()</code> </li>
</ul>
<h2 id="❗-도시이름-대소문자-구분하지-않는-처리하기">❗ 도시이름 대소문자 구분하지 않는 처리하기</h2>
<p>&quot; 각 도시 이름은 공백, 숫자, 특수문자 등이 없는 영문자로 구성되며, 대소문자 구분을 하지 않는다. &quot;고 문제에는 되어있다.</p>
<p>그러므로 만약 <code>도시 이름 문자열 배열 - cities</code> 가 <code>[Daegu, daegu]</code> 이렇다면 첫 번째 <code>Deagu</code> 는 <code>cache miss</code> 이고 두 번째 <code>daegu</code> 는 이미 앞에 <code>Daegu</code> 와 같은 페이지이므로 <code>cache hit</code> 이 되는 것이다.</p>
<p>이렇게 되기 위해서는 <code>cache hit</code> 또는 <code>cache miss</code> 하기 전에 미리 도시 이름을 *<em><code>toUpperCase() / toLowerCase()</code> *</em>처리하면 된다.</p>
<h2 id="❗cachesize가-0일때-예외-처리하기">❗<code>cacheSize</code>가 0일때 예외 처리하기</h2>
<p><code>cacheSize</code> 가 0일때는 캐시에 도시이름을 담아둘 수가 없으므로 <code>cash hit</code> 경우는 아예 없게 되고, 모든 경우가 <code>cash miss</code> 가 된다.</p>
<p>도시 이름 페이지가 추가될 때마다, 같은 도시 이름이 연속 2번 추가 되더라도, 늘 <code>cash miss</code> 다. </p>
<p>모든 경우가 <code>cache miss</code> 이므로 <strong><code>도시이름 갯수 * cache miss 실행시간</code></strong> 을 하면 총 실행시간을 구할 수 있다.</p>
<h2 id="💟-구현">💟 구현</h2>
<ul>
<li><p>총 실행시간 : <code>int runtime</code></p>
</li>
<li><p>캐시 : <code>LinkedList&lt;String&gt; cache</code></p>
</li>
<li><p><code>cacheSize</code> 가 0일 때 : <strong>모든 경우가 <code>cache miss</code> 이므로 도시이름 갯수 * <code>cache miss</code> 실행시간을 하면 총 실행시간을 구할 수 있다.</strong>
<code>if (cacheSize == 0) runtime = cities.length * cacheMiss</code></p>
</li>
<li><p><code>for</code>문 : 캐시 LRU 교체 알고리즘으로 총 실행시간 <code>runtime</code> 을 계산한다.
<code>for (int idx = 0; idx &lt; cities.length; idx++)</code></p>
<ul>
<li><p><strong>시티이름을 미리 대문자화 시켜 대소문자가 다른 시티이름이 같은 문자열로 취급될 수 있게 한다.</strong>
<code>String city = cities[idx].toUpperCase()</code></p>
</li>
<li><p><code>if(cache.contains(city))</code> : <code>cache hit</code></p>
<ul>
<li><code>runtime++</code> : <code>cache hit</code> 일 경우 실행시간은 1이다.</li>
<li><code>cache.remove(city)</code> : 기존 위치 지우고</li>
<li><code>cache.addFirst(city)</code> : 맨 앞에 다시 추가한다.</li>
</ul>
</li>
<li><p><code>else</code> : <code>cache miss</code></p>
<ul>
<li><code>runtime += 5</code> : <code>cache miss</code>일 경우 실행시간은 5이다.</li>
<li><code>if(cache.size() == cacheSize)</code> : 캐시가 꽉 찼을 때
<code>cache.removeLast()</code> : 맨 뒤를 지우고
<code>cache.addFirst(city)</code> : 맨 앞에 추가한다.</li>
<li><code>else</code> : 캐시에 자리가 있을 때
<code>cache.addFirst(city)</code> : 맨 앞에 추가한다.</li>
</ul>
</li>
<li><p><code>for</code>문이 끝나면 총 실행시간 <code>runtime</code>이 계산되어 졌다. 이것을 <code>return runtime</code> 함으로써 끝낸다.</p>
</li>
</ul>
</li>
</ul>
<h1 id="🟪-나의-코드">🟪 나의 코드</h1>
<pre><code class="language-java">public static int solution(int cacheSize, String[] cities) {
    int runtime = 0;
    int cacheHit = 1;
    int cacheMiss = 5;
    LinkedList&lt;String&gt; cache = new LinkedList&lt;&gt;();

    if (cacheSize == 0) {
        runtime = cities.length * cacheMiss;
        return runtime;
    }

    for (int idx = 0; idx &lt; cities.length; idx++) {
        String city = cities[idx].toUpperCase();
        if (cache.contains(city)) {
            runtime += cacheHit;
            cache.remove(city);
            cache.addFirst(city);
        } else {
            runtime += cacheMiss;
            if (cache.size() &gt;= cacheSize) {
                cache.removeLast();
                cache.addFirst(city);
            } else
                cache.addFirst(city);
        }
    }
    return runtime;
}</code></pre>
<h1 id="🟪-결과--성공-💞">🟪 결과 : 성공 💞</h1>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/cff65766-7ecd-42ae-8a14-8194aa8f58e7/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/da028771-cee0-4419-adf2-109a01ddd239/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/35315b4e-0511-4c1a-b109-8c9e92c1ac0a/image.png" alt=""></p>
<h2 id="🥶❓만약-런타임-에러가-난다면❗">🥶❓만약 런타임 에러가 난다면❗</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/ffce2650-deec-4bd2-a068-1efc66fe4de0/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/19b4f4ce-dda8-4503-8bc1-5e3ac79a4d71/image.png" alt=""></p>
<p>필요한 패키지는 꼭 임포트 해야한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 레벨2 최댓값과 최솟값]]></title>
            <link>https://velog.io/@on-n-on-turtle/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%97%B0%EC%8A%B5-%EF%BD%9C-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%A0%88%EB%B2%A82-%EC%B5%9C%EB%8C%93%EA%B0%92%EA%B3%BC-%EC%B5%9C%EC%86%9F%EA%B0%92</link>
            <guid>https://velog.io/@on-n-on-turtle/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%97%B0%EC%8A%B5-%EF%BD%9C-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%A0%88%EB%B2%A82-%EC%B5%9C%EB%8C%93%EA%B0%92%EA%B3%BC-%EC%B5%9C%EC%86%9F%EA%B0%92</guid>
            <pubDate>Sun, 02 Oct 2022 13:26:06 GMT</pubDate>
            <description><![CDATA[<hr>
<h1 id="🟪-문제-바로-가기">🟪 <a href="https://school.programmers.co.kr/learn/courses/30/lessons/12939">문제 바로 가기</a></h1>
<p>이 글은 문제를 정리하고 저의 풀이를 보여드리는 거예요. 실제로 문제를 보고 풀어보세요. 클릭! 클릭! 해보세요! 🖱️</p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/9f41d002-9c3e-45fd-8ac6-a8d6975a81d2/image.png" alt=""></p>
<h1 id="🟪-문제-설명">🟪 문제 설명</h1>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/e74a8e55-199f-47f1-abac-91598e960296/image.png" alt=""></p>
<blockquote>
<ul>
<li>문자열 s에는 공백으로 구분된 숫자들이 저장되어 있습니다. </li>
</ul>
</blockquote>
<ul>
<li>문자열 s에 나타나는 숫자 중 최소값과 최대값을 찾아 </li>
<li>이를 &quot;(최소값) (최대값)&quot;형태의 문자열을 반환하는 함수, solution을 완성하세요.</li>
<li>문자열 s에는 둘 이상의 정수가 공백으로 구분되어 있습니다.</li>
</ul>
<h2 id="💟-입출력-예시">💟 입출력 예시</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/1cd40613-519f-4187-9f02-3afb32a3078d/image.png" alt=""></p>
<h1 id="🟪-나의-로직">🟪 나의 로직</h1>
<h2 id="💟-선택-정렬">💟 <a href="https://velog.io/@on-n-on-turtle/%EB%88%84%EA%B5%AC%EB%82%98-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0%EC%99%80-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%84%A0%ED%83%9D%EC%A0%95%EB%A0%AC-%EB%B9%85%EC%98%A4%EC%9D%98-%EC%83%81%EC%88%98%EB%AC%B4%EC%8B%9C%ED%95%98%EA%B8%B0-%EA%B7%9C%EC%B9%99">선택 정렬</a></h2>
<ul>
<li>선택 정렬로 주어진 문자열s을 문자열 배열에 대입한다.</li>
<li>문자열 배열을 정수 리스트에 대입한다.</li>
<li>정수 리스트를 선택정렬 알고리즘을 이용하여 정렬시킨다. </li>
<li>정렬된 리스트의 첫 인덱스의 값과 마지막 인덱스의 값을
String.format(&quot;%d %d&quot;)를 이용해서 
&quot;(최소값) (최대값)&quot;형태의 문자열을 반환할 것이다.</li>
</ul>
<h2 id="💟-구현">💟 구현</h2>
<ul>
<li>주어진 문자열 s를 배열<code>String[] array</code>로 대입<ul>
<li><code>String[] array = s.split(&quot; &quot;)</code></li>
</ul>
</li>
<li><code>String[] array</code>를 <code>ArrayList&lt;Integer&gt; orderedArrList</code>로 대입<ul>
<li><code>for(String num : array) orderedArrList.add(Integer.parseInt(num))</code></li>
</ul>
</li>
<li><code>for</code>문 2개로 선택정렬 구현<ul>
<li>첫번째 <code>for</code> 문 == 패스스루<ul>
<li>범위 :  <code>인덱스0</code>에서 <code>마지막인덱스 바로 전</code>까지 <code>orderedArrList.size()-2</code>
(선택정렬은 배열의 마지막인덱스 바로 전의 인덱스가 되면 마지막 패스스루가 되기 때문이다.)</li>
<li><code>for(int startIdxOfPassThrogh=0; startIdxOfPassThrogh&lt;orderedArrList.size()-1; startIdxOfPassThrogh++)</code></li>
<li><code>최솟값의 인덱스-minmumValueIdx</code> 를 <code>패스스루의 시작인덱스-startIdxOfPassThrogh</code> 로 초기화 시킨다.
(패스스루가 처음 시작될 때는 시작인덱스의 값이 곧 최솟값이므로)</li>
<li><code>minmumValueIdx = startIdxOfPassThrogh</code></li>
</ul>
</li>
<li>두번째 <code>for</code> 문 == 현재 최솟값과 각각의 값들을 비교하여 최종 최솟값을 정한다<ul>
<li>범위 : <code>패스스루의 시작인덱스-startIdxOfPassThrogh의 바로 다음 인덱스</code>부터 <code>마지막 인덱스</code>까지</li>
<li><code>for(nowIdx=startIdxOfPassThrogh+1; nowIdx&lt;orderedArrList.size(); nowIdx++)</code></li>
<li>최솟값과 다음값을 비교한다.</li>
<li>최솟값보다 더 작은 값이 나오면 최솟값을 바꾼다.</li>
<li><code>if(orderedArrList[nowIdx]&lt;orderedArrList[minmumValueIdx]) minmumValueIdx = nowIdx</code></li>
</ul>
</li>
<li>두번째 <code>for</code> 문이 끝나면 <ul>
<li><code>패스스루의 시작인덱스-startIdxOfPassThrogh</code>와 <code>패스스루에서 최종적으로 결정된 최솟값의 인덱스-minmumValueIdx</code>를 교환한다.</li>
<li><code>if(startIdxOfPassThrogh != minmumValueIdx)</code>
<code>int temp = orderedArrList[minmumValueIdx]</code>
<code>orderedArrList[minmumValueIdx] = orderedArrList[startIdxOfPassThrogh]</code>
<code>orderedArrList[startIdxOfPassThrogh] = temp</code></li>
</ul>
</li>
<li><code>for</code>문이 끝나면 최소값과 최대값을 &quot;(최소값) (최대값)&quot;형태의 문자열로 반환한다.<ul>
<li><code>return String.format(&quot;%d %d&quot;, orderedArrList.get(0), orderedArrList.get(orderedArrList.size()-1))</code></li>
</ul>
</li>
</ul>
</li>
</ul>
<h1 id="🟪-나의-코드">🟪 나의 코드</h1>
<pre><code class="language-java">public static String solution(String s) {
    String[] array = s.split(&quot; &quot;);
    ArrayList&lt;Integer&gt; orderedArrList = new ArrayList&lt;&gt;();

    for (String num : array)
        orderedArrList.add(Integer.parseInt(num));

    for (int startIdxOfPassThrogh = 0; startIdxOfPassThrogh &lt; orderedArrList.size()-1; startIdxOfPassThrogh++) {
        int minmumValueIdx = startIdxOfPassThrogh;

        for (int nowIdx = startIdxOfPassThrogh + 1; nowIdx &lt; orderedArrList.size(); nowIdx++) {
            if (orderedArrList.get(nowIdx) &lt; orderedArrList.get(minmumValueIdx))
                minmumValueIdx = nowIdx;
        }

        if (startIdxOfPassThrogh != minmumValueIdx) {
            int temp = orderedArrList.get(minmumValueIdx);
            orderedArrList.set(minmumValueIdx, orderedArrList.get(startIdxOfPassThrogh));
            orderedArrList.set(startIdxOfPassThrogh, temp);
        }
    }

    return String.format(&quot;%d %d&quot;, orderedArrList.get(0), orderedArrList.get(orderedArrList.size()-1));
}</code></pre>
<h1 id="🟪-결과--성공💕">🟪 결과 : 성공💕</h1>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/4d9e7369-fe62-4fd1-88aa-011e9b96ca29/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/c44fff9c-db01-4e34-871a-a22a947f4c9f/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/e941dec0-c2cb-403e-a6ce-dcfd89ae4191/image.png" alt=""></p>
<h2 id="🥶❓만약-런타임-에러가-난다면❗">🥶❓만약 런타임 에러가 난다면❗</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/c802cf7b-8f95-4f2b-a5fc-e86160b9a3d2/image.png" alt=""></p>
<blockquote>
<p>필요한 패키지 임포트를 하지 않았기 때문입니다! </p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/84f96038-80da-4f32-bc58-57507c3d9562/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[🛴 제한하지 말고 최대한 넓게 넓게 탐험해보는 게 어떨까?]]></title>
            <link>https://velog.io/@on-n-on-turtle/%EC%A0%9C%ED%95%9C%ED%95%98%EC%A7%80-%EB%A7%90%EA%B3%A0-%EC%B5%9C%EB%8C%80%ED%95%9C-%EB%84%93%EA%B2%8C-%EB%84%93%EA%B2%8C-%ED%83%90%ED%97%98%ED%95%B4%EB%B3%B4%EB%8A%94-%EA%B2%8C-%EC%96%B4%EB%96%A8%EA%B9%8C</link>
            <guid>https://velog.io/@on-n-on-turtle/%EC%A0%9C%ED%95%9C%ED%95%98%EC%A7%80-%EB%A7%90%EA%B3%A0-%EC%B5%9C%EB%8C%80%ED%95%9C-%EB%84%93%EA%B2%8C-%EB%84%93%EA%B2%8C-%ED%83%90%ED%97%98%ED%95%B4%EB%B3%B4%EB%8A%94-%EA%B2%8C-%EC%96%B4%EB%96%A8%EA%B9%8C</guid>
            <pubDate>Mon, 26 Sep 2022 05:45:28 GMT</pubDate>
            <description><![CDATA[<p>어차피 결국 한자리에 모이는 거라고 느껴져서 
지금은 제한하지 말고 최대한 넓게 이것 저것 많이 탐험해보다가
나중에 전문성을 갖도록 몇 가지만 파고 &lt;- 이 때 제한하고
그러다가 결국은 한자리에 모여서 
무엇이 클린 코드인지 고민하게 되는 거 아닐까?</p>
<p>그러니까 지금 주니어 개발자도 아닌 그저 취준생인 나인데
어떤 언어든지 배워서 이것 저것 배워보는 게 좋지 않을까?
어플도 만들어 보고, 서버도 만들어 보고, css도 써보고, shell도 써보고 이런식으로 말이야 </p>
<p>모든 시간을 이렇게 탐험하겠다는 것은 아니고</p>
<blockquote>
<p>탐험 하는 시간이 이때까지는 전혀 없었으니까 
가끔씩 조금씩 이렇게 탐험해보자는 거얌
왜냐면 나는 산만하고 새로운 것을 좋아하니까!
이러한 탐험 시간이 생기면 활기와 재미가 더해져서
개발직을 더욱 사랑하고 몰두할 수 있을 것 같아!</p>
</blockquote>
<hr>
<p>사진 출처</p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/0366bb12-d012-49e6-b5e5-eef03982f335/image.gif" alt=""></p>
<p><a href="https://525oio.tistory.com/134?category=924628"><code>티스토리</code>사이트의 <code>525</code>님의 <code>525의 일상</code>블로그의 <code>상어와 함께 자란 소년은 수영을 배울 필요가 없다</code>게시물을 보러가 보아요!</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[누구나 자료구조와 알고리즘] 선택정렬, 빅오의 상수무시하기 규칙]]></title>
            <link>https://velog.io/@on-n-on-turtle/%EB%88%84%EA%B5%AC%EB%82%98-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0%EC%99%80-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%84%A0%ED%83%9D%EC%A0%95%EB%A0%AC-%EB%B9%85%EC%98%A4%EC%9D%98-%EC%83%81%EC%88%98%EB%AC%B4%EC%8B%9C%ED%95%98%EA%B8%B0-%EA%B7%9C%EC%B9%99</link>
            <guid>https://velog.io/@on-n-on-turtle/%EB%88%84%EA%B5%AC%EB%82%98-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0%EC%99%80-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%84%A0%ED%83%9D%EC%A0%95%EB%A0%AC-%EB%B9%85%EC%98%A4%EC%9D%98-%EC%83%81%EC%88%98%EB%AC%B4%EC%8B%9C%ED%95%98%EA%B8%B0-%EA%B7%9C%EC%B9%99</guid>
            <pubDate>Thu, 11 Aug 2022 19:59:36 GMT</pubDate>
            <description><![CDATA[<h1 id="🟪-선택-정렬">🟪 선택 정렬</h1>
<ul>
<li>선택 정렬 = <span style="color:red;"><strong><code>selection sort</code></strong></span></li>
</ul>
<h2 id="🔶-방법">🔶 방법</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/df8e1bf9-6a60-43e2-a132-ec6c6fc40ff2/image.png" alt=""></p>
<blockquote>
</blockquote>
<ul>
<li><strong><span style="color:black;"><code>인덱스0</code>까지에서 정해진 최솟값 = 2 (유일한 값이므로)</span></strong><blockquote>
</blockquote>
</li>
<li><strong><span style="color:black;">↳ <code>인덱스0</code>까지에서 정해진 최솟값 <code>2</code>는 <code>인덱스1</code>의 값 <code>6</code>보다 작으므로 최솟값이 <code>2</code>로 결정됐다.</span></strong><blockquote>
</blockquote>
</li>
<li><strong><span style="color:black;"><code>인덱스1</code>까지에서 정해진 최솟값 = 2 </span></strong><blockquote>
</blockquote>
</li>
<li><strong><span style="color:black;">↳ <code>인덱스2</code>의 값 <code>1</code>이 <code>인덱스1</code>까지에서 정해진 최솟값 <code>2</code>보다 작으므로 최솟값이 <code>1</code>로 결정됐다.</span></strong><blockquote>
</blockquote>
</li>
<li><strong><span style="color:black;"><code>인덱스2</code>까지에서 정해진 최솟값 = 1 </span></strong><blockquote>
</blockquote>
</li>
<li><strong><span style="color:black;">↳ <code>인덱스2</code>까지에서 정해진 최솟값 <code>1</code>이 <code>인덱스3</code>의 값 <code>3</code>보다 작으므로 최솟값이 <code>1</code>로 결정됐다.</span></strong><blockquote>
</blockquote>
</li>
<li><strong><span style="color:black;">↳ 이번 패스스루에서 정해진 최솟값 <code>1</code>의 인덱스인 <code>인덱스2</code>와 이번 패스스루의 시작 인덱스인 <code>인덱스0</code>을 교환한다.</span></strong></li>
<li><em>( <span style="color:grey;"><code>마지막 인덱스</code>까지에서 정해진 최솟값은 <code>1</code>이고 비교할 오른쪽 셀이 없으므로 이 최솟값이 이번 패스스루의 최솟값이 된다.</span> )*</em></li>
</ul>
<p><span style="background-color:LightCyan; color:black;  ">1단계</span> : <span style="color:red;"><strong>현재 최솟값과 오른쪽 셀의 값을 비교하여 최솟값을 정한다.</strong></span></p>
<p><span style="color:red;"><strong>현재 최솟값 : 지금 가리키고 있는 인덱스 까지 에서 정해진 최솟값</strong></span></p>
<p><strong>첫번째 패스스루의 첫 단계에서는 <code>인덱스0</code>과 <code>인덱스1</code>을 비교하여 최솟값을 정한다.</strong></p>
<p><strong>정해진 최솟값의 인덱스를 변수에 저장한다.</strong></p>
<p><strong>변수에 들어 있는 값보다 작은 값이 들어 있는 셀을 만나면 변수가 새 인덱스를 가리키도록 값을 대체한다.</strong>  </p>
<p><span style="background-color:LightCyan; color:black;  ">2단계</span> : <span style="color:red;">** 배열의 끝에 도달하면 최솟값의 인덱스와 패스스루의 시작인덱스를 교환한다.<strong></span> **최솟값의 인덱스와 시작인덱스가 같은 위치면 교환이 일어나지 않으므로 이 단계 또한 일어나지 않는다.</strong></p>
<p>패스스루를 시작했을 때 인덱스는 첫 패스스루에서는 인덱스 0이고, 두 번째 패스스루에서는 인덱스 1이다.</p>
<p><span style="background-color:LightCyan; color:black;  ">3단계</span> : 매 패스스루는 1, 2 단계로 이뤄진다. <span style="color:red;"><strong>패스스루의 시작인덱스가 배열의 마지막인덱스가 되기 전 까지 패스스루(1~2단계)를 반복한다.</strong></span> <span style="color:red;"><strong>즉 패스스루의 시작인덱스가 배열의 마지막인덱스 바로 전의 인덱스가 되면 마지막 패스스루가 된다는 뜻이다.</strong></span> *<em>왜냐하면 패스스루가 끝나면 패스스루의 시작인덱스까지 올바르게 정렬된다. 그러므로 마지막 패스스루에서는 마지막 셀을 제외한 모든 셀이 올바르게 정렬이 되므로 이는 곧 전체 배열이 올바르게 정렬되는 것이기 때문이다. *</em></p>
<h2 id="🔶-4-2-7-1-3-정렬-해보기">🔶 <code>{4, 2, 7, 1, 3}</code> 정렬 해보기</h2>
<h3 id="🔵-첫-번째-패스스루">🔵 첫 번째 패스스루</h3>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/7679cbd0-9534-47f5-8c78-c57f0f068d61/image.png" alt=""></p>
<p><span style="background-color:LightCyan; color:black;  ">1단계</span> : <code>인덱스0</code>에 들어 있는 값 <code>4</code>가 현재 최솟값이므로 이 인덱스를 변수에 저장한다. 그리고 현재 최솟값과 오른쪽 값 <code>2</code>를 비교하여 최솟값을 정한다. 오른쪽 값이 더 작으므로 결정된 최솟값은 <code>2</code>가 된다.</p>
<p><span style="background-color:LightCyan; color:black;  ">2단계</span> : 여기까지 정해진 현재 최솟값은 <code>2</code>이다. 다음 값인 <code>7</code>이 더 크므로 <code>2</code>가 최솟값으로 유지된다.</p>
<p><span style="background-color:LightCyan; color:black;  ">3단계</span> : 현재 최솟값 <code>2</code>와 다음 값 <code>1</code>을 비교한다. 오른쪽 값이 더 크므로 최솟값은 <code>1</code>로 새롭게 결정된다.</p>
<p><span style="background-color:LightCyan; color:black;  ">4단계</span> : <code>인덱스 3</code>을 가리키고 있을 때 현재 최솟값은 <code>1</code>이다. 다음 값 <code>3</code>과 비교했을 때 여전히 최솟값이다. 배열의 끝 값과 비교했을 때 제일 작은 수를 알아냈으므로 전체 배열의 최솟값은 <code>1</code>로 결정됐다.</p>
<p><span style="background-color:LightCyan; color:black;  ">5단계</span> : 이번 패스스루에서 결정된 최솟값 <code>1</code>의 <code>안덱스3</code>과 이번 패스스루의 시작 인덱스인 <code>인덱스0</code>을 교환한다. </p>
<h3 id="🔵-두-번째-패스스루">🔵 두 번째 패스스루</h3>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/73d0d493-67de-48f8-827c-16fab92c6aa9/image.png" alt=""></p>
<p><span style="background-color:LightCyan; color:black;  ">6단계</span> : <code>인덱스0</code>은 첫 번째 패스스루에서 이미 정렬된 값이므로 두 번째 패스스루는 다음 인덱스인 <code>인덱스1</code>부터 시작한다. <code>인덱스1</code>의 값 <code>2</code>가 현재 최소값이므로 이 인덱스를 변수에 저장한다. 현재 최솟값과 오른쪽 값 <code>7</code>을 비교하여 결정된 최솟값은 <code>2</code>이므로 변수는 그대로 유지된다.</p>
<p><span style="background-color:LightCyan; color:black;  ">7단계</span> : 현재 최솟값 <code>2</code>와 오른쪽 값 <code>4</code>를 비교하여 결정된 최솟값은 <code>2</code>이므로 변수는 그대로 유지된다.</p>
<p><span style="background-color:LightCyan; color:black;  ">8단계</span> : 현재 최솟값 <code>2</code>와 오른쪽 값 <code>3</code>을 비교하여 결정된 최솟값은 <code>2</code>이므로 변수는 그대로 유지된다. 마지막 인덱스까지 비교가 끝났으므로 이제 교환을 할 차례이다. 이번 패스스루의 최솟값 <code>2</code>의 인덱스인 <code>인덱스1</code>과 이번 패스스루의 시작인덱스인 <code>인덱스1</code>이 같은 위치이므로 교환은 일어나지 않고 두 번째 패스스루가 끝난다.</p>
<h3 id="🔵-세-번째-패스스루">🔵 세 번째 패스스루</h3>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/734e0b91-07fa-41b7-8aa0-a3985af8c470/image.png" alt=""></p>
<p><span style="background-color:LightCyan; color:black;  ">9단계</span> : <code>인덱스0</code>과 <code>인덱스1</code>은 이때까지의 패스스루에서 이미 정렬된 값이므로 세 번째 패스스루는 <code>인덱스2</code>가 시작인덱스가 된다. <code>인덱스2</code>의 값<code>7</code>이 현재 최솟값이므로 이 인덱스를 변수에 저장한다. 현재 최솟값과 오른쪽 값<code>4</code>를 비교하여 결정된 최솟값은 <code>4</code>이므로 변수에 저장되는 값도 <code>7</code>에서 <code>4</code>로 바뀐다.</p>
<p><span style="background-color:LightCyan; color:black;  ">10단계</span> : 마지막 인덱스와 비교를 하므로 이 단계에서 정해지는 최솟값이 이번 패스스루의 최솟값이 된다. 현재 최솟값 <code>4</code>와 오른쪽 값 <code>3</code>을 비교한다. 이 때 오른쪽 값이 더 작으므로 결정되는 최솟값은 <code>3</code>이 된다. 변수에 저장되는 값도 <code>4</code>에서 <code>3</code>으로 바뀐다.</p>
<p><span style="background-color:LightCyan; color:black;  ">11단계</span> : 마지막 인덱스를 가리키게 되었으니 이번 패스스루의 최솟값과 시작인덱스를 교환하면 패스스루가 종료된다. 이번 패스스루의 최솟값 <code>3</code>의 인덱스인 <code>인덱스4</code>와 이번 패스스루의 시작인덱스인 <code>인덱스2</code>를 교환하고 패스스루는 종료된다. 이번 패스스루로 인하여 이번 패스스루의 시작인덱스까지, <code>인덱스0</code>부터 <code>인덱스2</code>까지 정렬이 되었다.  </p>
<h3 id="🔵-네-번째-패스스루">🔵 네 번째 패스스루</h3>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/f94b9034-c0e0-4bf0-a9a1-22a3b7b1655b/image.png" alt=""></p>
<p><span style="background-color:LightCyan; color:black;  ">12단계</span> :  이때까지의 패스스루에서 <code>인덱스0</code> ~ <code>인덱스2</code>까지는 이미 정렬됐으므로 <code>인덱스3</code>이 이번 네 번째 패스스루의 시작인덱스가 된다.  마지막 인덱스와 비교를 하므로 이 단계에서 정해지는 최솟값이 이번 패스스루의 최솟값이 된다. 시작인덱스의 값 <code>4</code>가 현재 최솟값이 된다. 현재 최솟값 <code>4</code>와 다음 인덱스의 값 <code>7</code>을 비교하여 결정된 최솟값은 <code>4</code>가 된다. 이번 패스스루의 최솟값의 인덱스인 <code>인덱스3</code>과 이번 패스스루의 시작인덱스인 <code>인덱스3</code>은 같은 위치이므로 교환이 일어나지 않는다. 그러므로 다음 단계 없이 여기서 패스스루가 끝난다. 이번 패스스루의 시작인덱스(<code>인덱스3</code>)가 배열의 마지막인덱스(<code>인덱스4</code>)의 바로 전 인덱스이므로 이번 패스스루가 마지막 패스스루가 되며 선택정렬이 완전히 종료된다. </p>
<h2 id="span-stylebackground-colorblack-colororange--❕코드-구현-❗span"><span style="background-color:black; color:orange;  "><strong>❕코드 구현 ❗</strong></span></h2>
<blockquote>
</blockquote>
<ul>
<li><span style="color:blue;"><strong>각 패스스루를 나타내는 <code>for</code>루프를 시작한다.</strong></span>
<span style="color:blue;"><strong>루프는 변수<code>startIndexOfPassThrough</code>를 통해 배열의 각 인덱스를 가리키며 배열의 마지막인덱스 바로 전까지 살펴본다.</strong></span><blockquote>
</blockquote>
</li>
<li><span style="color:blue;"><strong>변수<code>lowestNumberIndex</code>에 현재 최솟값의 인덱스를 저장한다.</strong></span><blockquote>
</blockquote>
</li>
<li><span style="color:blue;"><strong>각 패스스루에서는 <code>for</code>루프를 이용해 현재 최솟값과 다음 인덱스를 마지막인덱스까지 비교한다.</strong></span>
(중첩 <code>for</code>루프가 된다)<blockquote>
</blockquote>
</li>
<li><span style="color:blue;"><strong>각 패스스루에서는 현재최솟값과 다음인덱스의 값을 비교하여 현재 최솟값보다 더 작은 값인지 확인한다. 더 작은 값이라면 변수<code>lowestNumberIndex</code>를 다음인덱스로 다시 저장한다.</strong></span><blockquote>
</blockquote>
</li>
<li><span style="color:blue;"><strong>패스스루의 최솟값과 패스스루의 시작인덱스를 비교했을 때 같지 않다면 교환한다.</strong></span><blockquote>
</blockquote>
</li>
<li><span style="color:blue;"><strong>끝으로 정렬된 배열을 반환한다.</strong></span></li>
</ul>
<pre><code class="language-java">public static int[] selectionSort(int[] array) {
    for (int startIndexOfPassThrough = 0; startIndexOfPassThrough &lt; array.length - 1; startIndexOfPassThrough++) {
        int lowestNumberIndex  = startIndexOfPassThrough;

        for (int nextIndex = startIndexOfPassThrough+1; nextIndex &lt; array.length; nextIndex++) {
            if (array[nextIndex] &lt; array[lowestNumberIndex])
                lowestNumberIndex = nextIndex;
        }

        if (lowestNumberIndex != startIndexOfPassThrough) {
            int temp = array[startIndexOfPassThrough];
            array[startIndexOfPassThrough] = array[lowestNumberIndex];
            array[lowestNumberIndex] = temp;
        }
    }

    return array;
}</code></pre>
<p><span style="background-color:black; color:orange;  ">** main 출력 테스트 통과 **</span></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/5e7f4a74-d72c-46ff-b328-a92accba9474/image.png" alt=""></p>
<h2 id="🔶-효율성--on²">🔶 효율성 : <code>O(N²)</code></h2>
<p>선택 정렬은 비교와 교환, 두 종류의 단계를 포함한다. </p>
<ul>
<li>비교 : 각 패스스루 내에서 각 값을 현재까지 찾은 최솟값과 비교한다.</li>
<li>교환 : 그렇게 결정된 최종 최솟값을 패스스루의 시작 인덱스와 교환한다. </li>
</ul>
<h3 id="🔵-4-2-7-1-3-정렬-예제를-보면은">🔵 {4, 2, 7, 1, 3} 정렬 예제를 보면은</h3>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/ba963da8-f593-4beb-a75b-909e80c20d4d/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/32e3757b-c1e4-4ef5-97d3-1d50c50c3800/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/990382f9-262a-4ddb-907a-eacd5888e679/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/cc4d20a1-6a8b-4b73-8b28-d09c66799dde/image.png" alt=""></p>
<p>{4, 2, 7, 1, 3} 정렬 예제를 보면은 총 4번의 패스스루에 총 10번의 비교를 교환은 두 번 일어났다.</p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/57336a72-7e3c-4c87-bf5c-c598bb916ced/image.png" alt=""></p>
<p>배열의 크기가 5인데 교환은 총 (5 - 1) + (5 - 2) + (5 - 3) + 1 = 10번이 일어났다.</p>
<h3 id="🔵-모든-크기의-배열에-적용되도록-생각해보면은">🔵 모든 크기의 배열에 적용되도록 생각해보면은</h3>
<p><span style="background-color:yellow; color:black;"><strong>배열에 원소 N개가 있을 때</strong></span> </p>
<ul>
<li><span style="background-color:yellow; color:black;"><strong>비교 : (N - 1) + (N - 2) + (N - 3)  …  + 1</strong></span></li>
<li><span style="background-color:yellow; color:black;"><strong>교환 : 한 패스스루당 최대 한 번</strong></span> 
(배열이 역순으로 정렬된 최악의 시나리오에서는 각 패스스루마다 빠짐없이 교환을 한 번씩 해야한다.)</li>
</ul>
<h3 id="🔵-버블정렬과-선택정렬의-단계수를-비교하면은">🔵 버블정렬과 선택정렬의 단계수를 비교하면은</h3>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/4666fee0-8613-4ebb-84e3-8a3e300a2f9d/image.png" alt=""></p>
<p><span style="background-color:yellow; color:black;"><strong>선택정렬은 버블 정렬보다 단계 수가 반 정도(÷2) 적다. 즉, 선택 정렬이 두 배 더 빠르다.</strong></span></p>
<blockquote>
<p><strong>하지만 선택정렬의 효율성은 버블정렬과 똑같이 O(N²)으로 나타낸다. 왜일까? 그 이유는 빅 오의 상수 무시하기 법칙 때문이다.</strong></p>
</blockquote>
<h1 id="🟪-빅-오의-상수-무시하기-법칙">🟪 빅 오의 &lt;상수 무시하기&gt; 법칙</h1>
<blockquote>
<p>왜 선택정렬이 버블정렬보다 2배 더 빠름에도 불구하고 빅 오는  똑같이 O(N²)으로 효율성이 표기 되는 걸까?
➡️ 빅오의 상수 무시하기 법칙 때문이다.</p>
</blockquote>
<p><span style="background-color:yellow; color:black;"><strong>빅 오 표기법은 데이터 원소가 N개일 때 얼마나 많은 단계 수가 필요한가라는 질문에 답하는 것이다.</strong></span></p>
<p>선택 정렬에서는 데이터 원소가 N개일 때 N²/2단계가 걸린다.
선택 정렬은 대략 N²의 반 단계 정도가 걸리므로 O(N²/2)로 효율성을 표기하는 것이 맞는 것 같다.
하지만 선택 정렬의 효율성은 O(N²)이다. 이유는 다음의 빅 오 규칙 때문이다. </p>
<h3 id="❗span-stylebackground-coloryellow-colorblack빅-오-표기법은-상수를-무시한다span❗">❗<span style="background-color:yellow; color:black;"><strong>빅 오 표기법은 상수를 무시한다</strong></span>❗</h3>
<h3 id="span-stylebackground-coloryellow-colorblack상수--수식에서-변하지-않는-값span"><span style="background-color:yellow; color:black;"><strong>상수 : 수식에서 변하지 않는 값</strong></span></h3>
<p>↳ <code>N + 2</code> 에서 <code>N</code>은 변하는 값이지만 <code>2</code>는 절대 변하지 않으므로 상수이다.</p>
<p>↳ <code>N/3 + 6</code>에서 <code>N</code>은 그 때 그 때 계속 변하는 값이지만 <code>3</code>과 <code>6</code>은 어떤 상황에서도 절대 변하지 않으므로 상수이다.</p>
<blockquote>
<h3 id="❓-지수가-아닌-수">❓ 지수가 아닌 수</h3>
<p>이해하지 못한 문장들 ↓</p>
</blockquote>
<p>빅 오 표기법은 지수가 아닌 수는 포함하지 않는다는 것을 단순히 수학적으로 표현한 문장이다. 
표현식에서 이러한 수는 그냥 버린다.</p>
<ul>
<li>지수 : 제곱되는 수를 &quot;밑&quot;, 제곱하는 횟수가 &quot;지수&quot;이다.</li>
<li>지수가 아닌 수가 상수라는 말인가.....?
<img src="https://velog.velcdn.com/images/on-n-on-turtle/post/ad5916db-3a0a-458b-80b2-b090f64b23cd/image.png" alt=""><blockquote>
<p>오키에 질문해봤다. 답글을 보고 의미를 유추해보면 
<img src="https://velog.velcdn.com/images/on-n-on-turtle/post/a7f371a4-a79b-4a35-b00b-fc3503187462/image.png" alt=""></p>
</blockquote>
</li>
</ul>
<p>이러한 빅 오의 상수무시하기 법칙 때문에 </p>
<ul>
<li><code>N/2</code> 단계가 필요한 알고리즘은 <code>O(N)</code>으로 표현한다.</li>
<li><code>N²+10</code> 단계가 필요한 알고리즘은 지수가 없는 <code>10</code>을 버리고  <code>O(N²)</code>으로 표현한다.</li>
<li><code>2N</code> 단계가 필요한 알고리즘은 상수 <code>2</code>를 버리고 <code>O(N)</code>으로 표현한다.</li>
<li><code>O(N)</code>보다 100배나 느린 <code>O(100N)</code>이라 해도  결국 <code>O(N)</code>으 알고리즘 효율성이 표기된다.</li>
</ul>
<p><span style="background-color:yellow; color:black;"><strong>빅 오의 상수무시하기 법칙에 의해서 빅 오로는 정확히 똑같이 표현하는 두 알고리즘이지만 실제로는 한쪽이 다른 한쪽보다 100배나 빠를 수도 있다.</strong></span></p>
<p>이것의 완벽한 예시가 선택 정렬과 버블 정렬이다.
선택 정렬과 버블 정렬이 빅 오로는 O(N²)이지만 실제로는 선택 정렬이 N²/2단계의 알고리즘이고 버블 정렬이 N²단계의 알고리즘이므로 선택정렬이 버블정렬보다 2배 더 빠르다.</p>
<p>여기까지 왜 선택 정렬이 버블 정렬보다 2배 더 빠름에도 불구하고 둘 다 똑같은 빅 오로 표기되는지 알아보았다. → 빅 오의 상수 무시하기 법칙 때문에.</p>
<blockquote>
<p>상수무시하기가 무엇인지 이제는 알겠다. 이것때문에 N²/2이나 N²이나 같은 알고리즘 단계수로 표현 되는 것도 이제는 알겠다.</p>
<p>그런데 </p>
<p>왜 빅 오는 상수를 무시할까?
➡️ 일반적인 카테고리로만 분류해도 현저한 차이를 나타내기 충분하기 때문이다. 빅 오는 일반적인 카테고리만 나타내기 위한 표기법이기 때문이다. </p>
</blockquote>
<h1 id="🟪-빅-오-카테고리---상수-무시하기-법칙의-이유">🟪 빅 오 카테고리 - 상수 무시하기 법칙의 이유</h1>
<h2 id="🔶-루프의-실행-횟수에-더-초점을-맞추게-된다">🔶 루프의 실행 횟수에 더 초점을 맞추게 된다.</h2>
<p>아래는 주어진 숫자까지의 양의 정수에서 짝수만 찾아내 프린트 하는 함수이다.</p>
<pre><code class="language-java">public void printEvenNumbers (int upperLimit) {
    int number = 2;

    while (number &lt;= upperLimit) {
        if (number % 2)
            System.out.prinln(number);        
        number++;
    }
}</code></pre>
<p>upperLimit이 N일 때 루프가 N번 실행되고, 출력은 N과 상관없이 1번 되는 알고리즘이다.
따라서 알고리즘은 O(N+1)이라고 할 수 있고, 이는 상수 무시하기 법칙에 따라 결국엔 O(N)으로 표시된다.</p>
<p>이렇게 <span style="background-color:yellow; color:black;"><strong>상수를 제거함으로써 루프 안에서 정확히 무슨 일이 일어나는지 보다는 실질적으로 루프가 실행되는 횟수에 더 초점을 맞추게 된다.</strong></span></p>
<h2 id="🔶-건물을-분류하는데-층수까지-표시할-필요는-없다">🔶 건물을 분류하는데 층수까지 표시할 필요는 없다</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/7da8d994-e197-4557-8dc9-5bcac01c705e/image.png" alt=""></p>
<p>건물에 비유해서 「빅 오 카테고리」를 설명해보면,
건물의 종류는 매우 다양하다. 고층건물, 상가건물, 아파트, 공장 등등이 있다.</p>
<blockquote>
<p>하나는 단독 주택이고 하나는 고층건물인 두 건물을 비교할 때 굳이 각각이 몇 층인지 언급할 이유가 없다.</p>
</blockquote>
<p>두 건물의 크기와 기능이 현저히 달라서 &quot;이 건물은 2층짜리 단독주택이고, 저 건물은 100층짜리 고층 건물이다.&quot;라고 말 할 필요가 없는 것이다. 
그냥 하나는 집이고 하나는 고층 건물이라고 부르면 된다. </p>
<h2 id="🔶-일반적인-카테고리로만-분류해도-현저한-차이를-나타내기-충분하다">🔶 일반적인 카테고리로만 분류해도 현저한 차이를 나타내기 충분하다.</h2>
<blockquote>
<p><span style="color:red;"><strong>이러한 맥락으로 알고리즘의 효율성 역시 일반적인 카테고리의 알고리즘 속도만 고려하는 것이다.</strong></span> </p>
</blockquote>
<p> <code>O(N)</code> 알고리즘과 <code>O(N²)</code> 알고리즘을 비교할 때 두 효율성 간 차이가 너무 커서 <code>O(N)</code>이 실제로 <code>O(2N)</code> 이든 <code>O(N/2)</code> 이든 <code>O(100N)</code> 이든 별로 중요하지가 않는 것이다.</p>
<p><span style="background-color:yellow; color:black;"><strong>빅 오 표기법은 단지 알고리즘에 필요한 단계 수만 의미하지 않는다. 데이터가 늘어날 때 알고리즘 단계 수가 장기적으로 어떤 궤적을 그리는지가 중요하다.</strong></span> </p>
<p><span style="background-color:yellow; color:black;"><strong>O(N)은 직선 성장<code>straight growth</code>을 보여준다.</strong></span>
즉 단계 수가 데이터에 일정 비율로 비례해 직선을 그리며 증가한다.</p>
<p><span style="background-color:yellow; color:black;"><strong>O(N²)은 지수 성장<code>exponential growth</code>의 하나다.</strong></span></p>
<p><span style="background-color:yellow; color:black;"><strong>지수 성장은 어떤 형태의 O(N)-직선성장과도 비교되지 않는 완전히 다른 카테고리다.</strong></span>
O(N)에 어떤 수를 곱하든 데이터가 커지다 보면 언젠가 결국 O(N²)이 더 느려지기 때문이다.</p>
<p><span style="color:red;"><strong>O(2N)과 O(N²/50)을 비교하는 것은 2층 주택과 50층 고층건물을 비교하는 것과 다를 바 없다.</strong></span> 
<span style="color:red;"><strong>간단명료하게 O(N)과 O(N²)으로 비교하면 된다. 단독주택과 고층건물로 두 건물을 비교하면 되는 것과 마찬가지로.</strong></span></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/26d90d56-6016-4208-9050-af89f2c74d5d/image.png" alt=""></p>
<blockquote>
<p>주택끼리, 고층건물끼리 비교하는 것도 아니고 
주택과 고층건물 이 두 가지 다른 카테고리를 비교할 때는
주택이 몇 층이고 고층건물이 몇 층인지까지 언급할 필요가 없는 것 처럼 
빅 오 또한 서로 다른 카테고리 일 때는 실제 어떤 상수가 곱해져 있고 더해져 있는지 상관없이 카테고리 자체로만 나타내고 비교하면 되는 것이다.
O(139N+11) -&gt; O(N)
그래서 빅 오는 카테고리로만 표기하기 위해서 상수무시하기 법칙이 있는 것이다.</p>
</blockquote>
<br>


<h2 id="🔶-정리">🔶 정리</h2>
<blockquote>
<p><span style="background-color:yellow; color:black;">** O(1), O(logN), O(N), O(2N), O(2ⁿ), O(N²) 등과 같은 빅 오 유형은 서로 차이가 큰 일반적인 빅 오 카테고리다.**</span></p>
</blockquote>
<p><span style="background-color:yellow; color:black;"><strong>지수가 아닌 수로 단계 수를 곱하거나 나누거나 더한다고 카테고리가 바뀌지 않는다.</strong></span>
<span style="background-color:yellow; color:black;"><strong>각각의 카테고리 간의 차이가 너무 커서 특정 카테고리에 속하는 어떤 알고리즘이 실제로는 <code>O(N²/2)</code> 이든 <code>O(logN+9)</code> 이든 별로 중요하지가 않아진다.</strong></span>
<span style="background-color:yellow; color:black;"><strong>그래서 <code>O(N/2)</code> 이든 <code>O(100N)</code> 이든 같은 <code>O(N)</code> 카테고리로 분류하고, <code>O(4)</code>이든 <code>O(1000)</code>이든 같은 <code>O(1)</code>카테고리로 분류하는 것이다.</strong></span></p>
<blockquote>
</blockquote>
<p>그렇기 때문에</p>
<blockquote>
</blockquote>
<p><span style="background-color:yellow; color:black;"><strong>빅 오에서 서로 다른 카테고리에 속하는 두 효율성을 비교할 때 일반적인 카테고리로 분류하는 것으로 충분하다.</strong></span> </p>
<blockquote>
</blockquote>
<p><span style="background-color:yellow; color:black;"><strong>빅 오 표기법은 일반적인 카테고리의 알고리즘 속도만 고려할 뿐만 아니라.</strong></span>
<span style="background-color:yellow; color:black;"><strong>일반적인 카테고리로만 분류해도 현저한 차이를 나타내기 충분하기 때문이다.</strong></span></p>
<blockquote>
</blockquote>
<p>그렇기 때문에 
빅오의 상수무시하기 법칙이 있는 것이다.</p>
<h2 id="🔶-두-알고리즘이-같은-카테고리에-속할-때는">🔶 두 알고리즘이 같은 카테고리에 속할 때는</h2>
<p>하지만 두 알고리즘이 같은 카테고리에 속하더라도 서로 처리 속도가 다를 수 있다.</p>
<p>앞에서 계속 예시로 들었듯이 버블 정렬과 선택 정렬은 둘 다 같은 O(N²) 카테고리에 속하지만 실제로 더욱 깊게 비교해보면 버블 정렬은 선택 정렬보다 두 배 느리다.</p>
<p>따라서  <span style="background-color:yellow; color:black;"><strong>빅오에서 서로 다른 카테고리에 속하는 알고리즘을 대조할 때는 빅 오가 완벽한 도구지만 같은 카테고리에 속하는 두 알고리즘이라면 어떤 알고리즘이 더 빠를지 알기 위해 더 분석 해야 한다.</strong></span> </p>
<h1 id="🟪-함수의-효율성-맞춰보기">🟪 함수의 효율성 맞춰보기</h1>
<h3 id="🔵-1">🔵 1.</h3>
<p>주어진 배열의 모든 수를 두 배로 만든 후 그 합을 반환하는 함수 </p>
<pre><code class="language-java">public int doubleThenSum (int[] array) {
    int[] doubledArray = new int[array.length];
    int sum = 0;

    for (int idx = 0; idx &lt; array.length; idx++) {
        doubledArray[idx] = array[idx] * 2;
    }

    for (int num : doubledArray)
        sum += num;

    return sum;
}</code></pre>
<p>: array의 원소 갯수가 N일 때 2개의 for루프가 모두 각각 N번씩 수행되므로 O(2N) ➡️ O(N)이다.</p>
<h3 id="🔵-2">🔵 2.</h3>
<p>문자열 배열을 받아 각 문자열을 다양한 형태로 출력하는 함수</p>
<pre><code class="language-java">public void multipleCases (String[] array) {
    for (String str : array) {
        System.out.println(str.toLowerCase());
        System.out.println(str.toUpperCase());
        System.out.println(str.substring(0,1).toUpperCase() + str.substring(1));
    }
}</code></pre>
<p>: array의 원소 갯수가 N일 때 출력이 3번씩 N번(for루프) 수행되므로 O(3N) ➡️ O(N)이다.</p>
<h3 id="🔵-3">🔵 3.</h3>
<p>주어진 배열의 인덱스가 짝수이면 배열 내 모든 수에 대해 그 인덱스의 수를 더해 출력하는 함수</p>
<pre><code class="language-java">public void everyOther(int[] array) {
    for (int idx = 0; idx &lt; array.length; idx++) {
        if (idx % 2 == 0) {
            for (int num : array)
                System.out.println(num + idx);
        }
    }
}</code></pre>
<p>: array의 원소 갯수가 N일 때 출력이 N번씩 N/2번(중첩 for루프) 수행되므로 O(N²/2) ➡️ O(N²)이다.</p>
<h1 id="🟦-출처">🟦 출처</h1>
<h2 id="🔷-그림1">🔷 그림1</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/8f6c8053-0079-403c-a609-226419298443/image.png" alt=""></p>
<p><a href="https://www.google.com/url?sa=i&amp;url=https%3A%2F%2Fkr.123rf.com%2Fphoto_979653_%25EC%2597%2590%25EC%258A%25A4%25ED%2594%2584%25EB%25A0%2588%25EC%2586%258C%25EC%2597%2590%25EC%2584%259C-%25ED%2598%2584%25EB%258C%2580%25EC%25A0%2581%25EC%259D%25B8-%25EA%25B3%25A0%25EC%25B8%25B5-%25EA%25B1%25B4%25EB%25AC%25BC%25EC%2597%2590-%25EC%259D%25B4%25EB%25A5%25B4%25EA%25B8%25B0%25EA%25B9%258C%25EC%25A7%2580-%25EB%258B%25A4%25EC%2596%2591%25ED%2595%259C-%25EC%25A2%2585%25EB%25A5%2598%25EC%259D%2598-%25EA%25B1%25B4%25EB%25AC%25BC.html&amp;psig=AOvVaw1x349y2LtgyFjtHgyxW3ym&amp;ust=1664184917664000&amp;source=images&amp;cd=vfe&amp;ved=0CAwQjRxqFwoTCOCS9YvSr_oCFQAAAAAdAAAAABBC"><code>123RF</code>사이트에서 <code>marcopolo</code>님의 <code>에스프레소에서 현대적인 고층 건물에 이르기까지 다양한 종류의 건물</code>게시물을 확인해보세요 </a></p>
<h2 id="🔷-글의-내용">🔷 글의 내용</h2>
<p>이 글 내용은 &#39;제인 웬그로우&#39;의 &#39;누구나 자료구조와 알고리즘 개정 2판&#39; 책을 100% 참고하여 작성하였습니다. 설명에 전문적인 용어보다는 일상적인 용어를 사용하고 그림으로 원리를 설명해주어 왕초보인 저가 이해하기에 아주 좋았습니다. 가격이 많이 나가는 편이지만 꼭 배워야 하는 내용이 모두 들어있고 그것을 제가 이해할 수 있는 수준으로 쓰여있어 전혀 아깝지 않은 소비였습니다. </p>
<p><img src="http://image.kyobobook.co.kr/images/book/xlarge/061/x9791160505061.jpg" alt="누구나 자료구조와 알고리즘 책 사진"></p>
<p><a href="http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&amp;ejkGb=KOR&amp;barcode=9791160505061">🖱 클릭! | &#39;제인 웬그로우&#39;의 &#39;누구나 자료구조와 알고리즘&#39; 책 구경하러 가보기</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[누구나 자료구조와 알고리즘] 버블정렬 , O(N²) , 이차문제 ,  이차시간, 정렬알고리즘]]></title>
            <link>https://velog.io/@on-n-on-turtle/%EB%88%84%EA%B5%AC%EB%82%98-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0%EC%99%80-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%B2%84%EB%B8%94%EC%A0%95%EB%A0%AC</link>
            <guid>https://velog.io/@on-n-on-turtle/%EB%88%84%EA%B5%AC%EB%82%98-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0%EC%99%80-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%B2%84%EB%B8%94%EC%A0%95%EB%A0%AC</guid>
            <pubDate>Fri, 05 Aug 2022 21:32:28 GMT</pubDate>
            <description><![CDATA[<h1 id="🟪-정렬-알고리즘">🟪 정렬 알고리즘</h1>
<blockquote>
<p><span style="color:red;"><strong>정렬되지 않은 배열이 주어졌을 때, 어떻게 오름차순/내림차순으로 정렬할 수 있을까?</strong></span></p>
</blockquote>
<p>정렬 알고리즘은 컴퓨터 과학 분야에서 폭넓게 연구된 주제이며, 지난 수년간 수십 개의 정렬 알고리즘이 개발돼 왔다. 이러한 알고리즘 모두 &quot;정렬되지 않은 배열이 주어졌을 때, 어떻게 오름차순/내림차순으로 정렬할 수 있을까?&quot;라는 문제를 해결한다.</p>
<p>버블 정렬, 힙 정렬, 퀵 정렬, 트리 정렬 등 모두 정렬 알고리즘 중 하나이다.</p>
<h1 id="🟪-🌟버블-정렬🌟">🟪 🌟버블 정렬🌟</h1>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/117cfad5-018a-4407-8e2e-e8286c88dd30/image.png" alt=""></p>
<p><span style="background-color:LightCyan; color:black;  ">1단계 :</span> <span style="color:red;"><strong>배열 내 연속된 두 항목을 비교한다.</strong></span>
처음에는 배열의 첫 번째 원소부터 시작하므로 첫 번째 항목과 두 번째 항목을 비교한다.</p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/a5814dfd-4566-4b25-96fa-4a2ece1210dc/image.png" alt=""></p>
<p><span style="background-color:LightCyan; color:black;  ">2단계 :</span> <span style="color:red;"><strong>왼쪽 값이 오른쪽 값보다 크면 두 항목을 교환<code>swap</code>한다.</strong></span>
만약 순서가 올바르다면 아무것도 하지 않고 그 다음 항목으로 넘어간다.</p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/8f04cbf3-6e9a-4940-a7e0-d2d445075502/image.png" alt=""></p>
<p><span style="background-color:LightCyan; color:black;  ">3단계 :</span> <span style="color:red;"><strong>&quot;포인터&quot;를 오른쪽으로 한 셀씩 옮긴다.</strong></span></p>
<p><span style="background-color:LightCyan; color:black;  ">4단계 :</span> <span style="color:red;"><strong>배열의 끝까지 또는 이미 정렬된 값까지 1단계부터 3단계를 반복한다.</strong></span><span style="color:red;">** ➡️ <code>이미 정렬된 값</code> : 각 패스스루마다 정렬되지 않은 값 중 가장 큰 값 &quot;버블&quot;이 올바른 위치로 가게 된다.**</span></p>
<p>이것이 배열의 첫  <span style="background-color:yellow; color:black;"><strong>패스스루<code>pass-through</code></strong></span>가 끝난 것이다. 
즉 <span style="background-color:yellow; color:black;"><strong>배열 끝까지(정렬된 값까지) 값을 하나하나 가리키며 배열을 &quot;통과&quot;</strong></span>한 것이다.</p>
<p><span style="background-color:LightCyan; color:black;  ">5단계 :</span> <span style="color:red;"><strong>이제 두 포인터를 다시 배열의 처음 두 값으로 옮겨서 1단계부터 4단계를 다시 실행함으로써 새로운 패스스루를 실행한다.</strong></span>
<span style="color:red;"><strong>교환이 일어나지 않는 패스스루가 생길 때까지 반복한다.</strong></span> <span style="color:red;">** ➡️ 패스스루에서 교환이 한 번이라도 수행되었다면 다음 패스스루도 수행해야 한다.**</span>
교환할 항목이 없다는 것은 배열이 완전히 정렬됐다는 뜻이다.</p>
<h3 id="🔵-4-2-7-1-3-정렬-해보기">🔵 {4, 2, 7, 1, 3} 정렬 해보기</h3>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/ac1c09dc-5a14-492c-a0ef-712ce7dc0b5a/image.png" alt=""></p>
<ul>
<li><p><span style="background-color:LightCyan; color:black;  ">첫 번째 패스스루</span></p>
<ul>
<li><p><span style="background-color:LightCyan; color:black;  ">1단계</span> : 먼저 <code>4</code>와 <code>2</code>를 비교한다.</p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">2단계</span> : 왼쪽값 &gt; 오른쪽값 이므로 둘을 교환한다.</p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">3단계</span> : 다음으로 <code>4</code>와 <code>7</code>를 비교한다. 순서가 올바르므로 교환하지 않고 다음 포인터로 넘어간다.</p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">4단계</span> : 다음으로 <code>7</code>와 <code>1</code>를 비교한다. </p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">5단계</span> : 왼쪽값 &gt; 오른쪽값 이므로 둘을 교환한다.</p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">6단계</span> : 다음으로 <code>7</code>와 <code>3</code>를 비교한다. </p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">7단계</span> : 왼쪽값 &gt; 오른쪽값 이므로 둘을 교환한다.</p>
</li>
</ul>
</li>
</ul>
<p><span style="background-color:yellow; color:black;"><strong>첫 번째 패스스루가 끝났으므로 정렬되지 않은 값 중 가장 큰 값 &quot;버블<code>7</code>&quot;이 확실히 올바른 위치에 있게 되었다.</strong></span></p>
<p><span style="background-color:yellow; color:black;"><strong>이번 패스스루에서 교환을 한 번 이상 하였으므로 다음 패스스루도 수행해야 한다.</strong></span></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/77431820-b5c4-426d-bbe6-2b4d284949c0/image.png" alt=""></p>
<ul>
<li><p><span style="background-color:LightCyan; color:black;  ">두 번째 패스스루</span></p>
<ul>
<li><p><span style="background-color:LightCyan; color:black;  ">8단계</span> : 먼저 <code>2</code>와 <code>4</code>를 비교한다. 순서가 올바르므로 교환하지 않고 다음 포인터로 넘어간다.</p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">9단계</span> : 다음으로 <code>4</code>와 <code>1</code>를 비교한다. </p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">10단계</span> : 왼쪽값 &gt; 오른쪽값 이므로 둘을 교환한다.</p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">11단계</span> : 다음으로 <code>4</code>와 <code>3</code>를 비교한다. </p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">12단계</span> : 왼쪽값 &gt; 오른쪽값 이므로 둘을 교환한다.</p>
</li>
</ul>
</li>
</ul>
<p><span style="background-color:yellow; color:black;"><strong>첫 번째 패스스루로 인해 <code>7</code>이 올바른 위치에 있으므로 <code>4</code>와 <code>7</code>은 비교할 필요가 없다.</strong></span></p>
<p><span style="background-color:yellow; color:black;"><strong>두 번째 패스스루가 끝났으므로 정렬되지 않은 값 중 가장 큰 값 &quot;버블<code>4</code>&quot;가 확실히 올바른 위치에 있게 되었다.</strong></span></p>
<p><span style="background-color:yellow; color:black;"><strong>이번 패스스루에서 교환을 한 번 이상 하였으므로 다음 패스스루도 수행해야 한다.</strong></span></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/826916fb-8375-4a28-95d7-61dcd847ee8a/image.png" alt=""></p>
<ul>
<li><p><span style="background-color:LightCyan; color:black;  ">세 번째 패스스루</span></p>
<ul>
<li><p><span style="background-color:LightCyan; color:black;  ">13단계</span> : 먼저 <code>2</code>와 <code>1</code>를 비교한다. </p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">14단계</span> : 왼쪽값 &gt; 오른쪽값 이므로 둘을 교환한다.</p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">15단계</span> : 다음으로 <code>2</code>와 <code>3</code>를 비교한다. 순서가 올바르므로 교환하지 않는다.</p>
</li>
</ul>
</li>
</ul>
<p><span style="background-color:yellow; color:black;"><strong>이때까지의 패스스루로 인해 <code>4</code>와 <code>7</code>이 올바른 위치에 있으므로 <code>3</code>과 <code>4</code>는 비교할 필요가 없다.</strong></span></p>
<p><span style="background-color:yellow; color:black;"><strong>세 번째 패스스루가 끝났으므로 정렬되지 않은 값 중 가장 큰 값 &quot;버블<code>3</code>&quot;이 확실히 올바른 위치에 있게 되었다.</strong></span></p>
<p><span style="background-color:yellow; color:black;"><strong>이번 패스스루에서 교환을 한 번 이상 하였으므로 다음 패스스루도 수행해야 한다.</strong></span></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/750c08d5-201b-4578-b19e-0835ef85bc23/image.png" alt=""></p>
<ul>
<li><p><span style="background-color:LightCyan; color:black;  ">네 번째 패스스루</span></p>
<ul>
<li><span style="background-color:LightCyan; color:black;  ">16단계</span> : 먼저 <code>1</code>와 <code>2</code>를 비교한다. 순서가 올바르므로 교환하지 않는다.</li>
</ul>
</li>
</ul>
<p><span style="background-color:yellow; color:black;"><strong>이때까지의 패스스루로 인해 <code>3</code>과 <code>4</code>와 <code>7</code>이 올바른 위치에 있으므로 <code>2</code>와 <code>3</code>은 비교할 필요가 없다.</strong></span></p>
<p><span style="background-color:yellow; color:black;"><strong>네 번째 패스스루가 끝났으므로 정렬되지 않은 값 중 가장 큰 값 &quot;버블<code>2</code>&quot;가 확실히 올바른 위치에 있게 되었다.</strong></span></p>
<p><span style="background-color:yellow; color:black;"><strong>이번 패스스루에서는 어떤 교환도 하지 않았으므로 패스스루를 더 이상 수행하지 않고 종료한다. 이제 이 배열은 완전히 정렬되었다.</strong></span></p>
<h3 id="🔵-9-1-5-2-1-6-정렬-해보기">🔵 {9, 1, 5, 2, 1, 6} 정렬 해보기</h3>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/bd70432f-668c-4571-b835-c99b4bdf48ba/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/3d95506d-ee2d-44c9-932f-d6a9fc33f193/image.png" alt=""></p>
<ul>
<li><p><span style="background-color:LightCyan; color:black;  ">첫 번째 패스스루</span></p>
<ul>
<li><p><span style="background-color:LightCyan; color:black;  ">1단계</span> : 먼저 <code>9</code>와 <code>1</code>을 비교한다.</p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">2단계</span> : 왼쪽값 &gt; 오른쪽값 이므로 둘을 교환한다.</p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">3단계</span> : 다음으로 <code>9</code>와 <code>5</code>를 비교한다.</p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">4단계</span> : 왼쪽값 &gt; 오른쪽값 이므로 둘을 교환한다.</p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">5단계</span> : 다음으로 <code>9</code>와 <code>2</code>를 비교한다.</p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">6단계</span> : 왼쪽값 &gt; 오른쪽값 이므로 둘을 교환한다.</p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">7단계</span> : 다음으로 <code>9</code>와 <code>1</code>를 비교한다.</p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">8단계</span> : 왼쪽값 &gt; 오른쪽값 이므로 둘을 교환한다.</p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">9단계</span> : 다음으로 <code>9</code>와 <code>6</code>를 비교한다.</p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">10단계</span> : 왼쪽값 &gt; 오른쪽값 이므로 둘을 교환한다.</p>
</li>
</ul>
</li>
</ul>
<p><span style="background-color:yellow; color:black;"><strong>첫 번째 패스스루가 끝났으므로 정렬되지 않은 값 중 가장 큰 값 &quot;버블<code>9</code>&quot;가 확실히 올바른 위치에 있게 되었다.</strong></span></p>
<p><span style="background-color:yellow; color:black;"><strong>이번 패스스루에서 교환을 한 번 이상 하였으므로 다음 패스스루도 수행해야 한다.</strong></span></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/53642ec5-7dc3-4250-98a1-2f83b7eca1f3/image.png" alt=""></p>
<ul>
<li><p><span style="background-color:LightCyan; color:black;  ">두 번째 패스스루</span></p>
<ul>
<li><p><span style="background-color:LightCyan; color:black;  ">11단계</span> : 먼저 <code>1</code>과 <code>5</code>를 비교한다. 순서가 올바르므로 교환하지 않고 다음 포인터로 넘어간다.</p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">12단계</span> : 다음으로 <code>5</code>와 <code>2</code>를 비교한다. </p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">13단계</span> : 왼쪽값 &gt; 오른쪽값 이므로 둘을 교환한다.</p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">14단계</span> : 다음으로 <code>5</code>와 <code>1</code>을 비교한다. </p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">15단계</span> : 왼쪽값 &gt; 오른쪽값 이므로 둘을 교환한다.</p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">16단계</span> : 다음으로 <code>5</code>와 <code>6</code>을 비교한다. 순서가 올바르므로 교환하지 않는다.</p>
</li>
</ul>
</li>
</ul>
<p><span style="background-color:yellow; color:black;"><strong>첫 번째 패스스루로 인해 <code>9</code>가 올바른 위치에 있으므로 <code>6</code>과 <code>9</code>는 비교할 필요가 없다.</strong></span></p>
<p><span style="background-color:yellow; color:black;"><strong>두 번째 패스스루가 끝났으므로 정렬되지 않은 값 중 가장 큰 값 &quot;버블<code>6</code>&quot;이 확실히 올바른 위치에 있게 되었다.</strong></span></p>
<p><span style="background-color:yellow; color:black;"><strong>이번 패스스루에서 교환을 한 번 이상 하였으므로 다음 패스스루도 수행해야 한다.</strong></span></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/30ab3dbe-297a-4ff7-9925-d19f389456a5/image.png" alt=""></p>
<ul>
<li><p><span style="background-color:LightCyan; color:black;  ">세 번째 패스스루</span></p>
<ul>
<li><p><span style="background-color:LightCyan; color:black;  ">17단계</span> : 먼저 <code>1</code>과 <code>2</code>를 비교한다. 순서가 올바르므로 교환하지 않고 다음 포인터로 넘어간다.</p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">18단계</span> : 다음으로 <code>2</code>와 <code>1</code>을 비교한다.</p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">19단계</span> : 왼쪽값 &gt; 오른쪽값 이므로 둘을 교환한다.</p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">20단계</span> : 다음으로 <code>2</code>와 <code>5</code>를 비교한다. 순서가 올바르므로 교환하지 않는다.</p>
</li>
</ul>
</li>
</ul>
<p><span style="background-color:yellow; color:black;"><strong>이때까지의 패스스루로 인해 <code>6</code>과 <code>9</code>가 올바른 위치에 있으므로 <code>5</code>와 <code>6</code>은 비교할 필요가 없다.</strong></span></p>
<p><span style="background-color:yellow; color:black;"><strong>세 번째 패스스루가 끝났으므로 정렬되지 않은 값 중 가장 큰 값 &quot;버블<code>5</code>&quot;가 확실히 올바른 위치에 있게 되었다.</strong></span></p>
<p><span style="background-color:yellow; color:black;"><strong>이번 패스스루에서 교환을 한 번 이상 하였으므로 다음 패스스루도 수행해야 한다.</strong></span></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/77f3dd55-09a8-44aa-93c8-6b093a849972/image.png" alt=""></p>
<ul>
<li><p><span style="background-color:LightCyan; color:black;  ">네 번째 패스스루</span></p>
<ul>
<li><p><span style="background-color:LightCyan; color:black;  ">21단계</span> : 먼저 <code>1</code>과 <code>1</code>을 비교한다. 순서가 올바르므로 교환하지 않는다.</p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">22단계</span> : 다음으로 <code>1</code>과 <code>2</code>를 비교한다. 순서가 올바르므로 교환하지 않는다.</p>
</li>
</ul>
</li>
</ul>
<p><span style="background-color:yellow; color:black;"><strong>이때까지의 패스스루로 인해 <code>5</code>와 <code>6</code>과 <code>9</code>가 올바른 위치에 있으므로 <code>2</code>와 <code>5</code>는 비교할 필요가 없다.</strong></span></p>
<p><span style="background-color:yellow; color:black;"><strong>네 번째 패스스루가 끝났으므로 정렬되지 않은 값 중 가장 큰 값 &quot;버블<code>2</code>&quot;가 확실히 올바른 위치에 있게 되었다.</strong></span></p>
<p><span style="background-color:yellow; color:black;"><strong>이번 패스스루에서는 어떤 교환도 하지 않았으므로 패스스루를 더 이상 수행하지 않고 종료한다. 이제 이 배열은 완전히 정렬되었다.</strong></span></p>
<h2 id="span-stylebackground-colorblack-colororange--❕코드-구현-❗span"><span style="background-color:black; color:orange;  "><strong>❕코드 구현 ❗</strong></span></h2>
<blockquote>
<ul>
<li><span style="color:blue;"><strong>함수는 정렬되지 않은 배열을 전달하여 사용한다.</strong></span></li>
</ul>
</blockquote>
<ul>
<li><span style="color:blue;"><strong>그러면 함수는 정렬된 배열을 반환한다.</strong></span><blockquote>
</blockquote>
</li>
<li><span style="color:blue;"><strong><code>unsortedUntilIndex</code> 변수 : 아직 정렬되지 않은 배열의 가장 오른쪽 인덱스를 기록한다.</strong></span>
( 알고리즘이 처음 시작할 때는 전체 배열의 마지막 인덱스로 변수를 초기화한다. ) <blockquote>
</blockquote>
</li>
<li><span style="color:blue;"><strong><code>sorted</code> 변수 : 배열의 정렬 여부를 기록한다.</strong></span>
(알고리즘이 처음 시작할 때는 정렬되지 않았으므로 <code>false</code>로 초기화한다.)<blockquote>
</blockquote>
</li>
<li><span style="color:blue;"><strong><code>while</code>루프</strong></span><ul>
<li>배열이 정렬될 때까지 실행한다.
↳  <code>while (!sorted) {}</code></li>
<li><span style="color:blue;"><strong>루프 한 번 실행이 배열의 한 패스스루에 해당한다.</strong></span><blockquote>
</blockquote>
⬇️ 루프안에서<blockquote>
</blockquote>
</li>
</ul>
</li>
<li><span style="color:blue;"><strong>각 패스스루 안에서는 교환이 일어나기 전까지 배열이 정렬되어 있다고 가정하고 교환이 일어났을 때 다시 <code>false</code>로 바꾸는 방식을 취한다.</strong></span>
↳  <code>sorted = true;</code><blockquote>
</blockquote>
</li>
<li><span style="color:blue;"><strong><code>for</code>루프 : 배열 내 모든 값 쌍을 가리킨다. <code>i</code>를 첫 포인터로 사용해 배열의 첫 인덱스부터 아직 정렬되지 않은 인덱스까지 수행한다.</strong></span>
↳  <code>for(int pointer = 0; pointer &lt; unsortedUntilIndex; pointer++) {}</code><ul>
<li><span style="color:blue;"><strong><code>for</code>루프 내에서는 모든 인접 값 쌍을 비교하고 왼쪽값 &gt; 오른쪽값이면 교환한다. ➡️ 교환이 일어났으므로 <code>sorted = false</code></strong></span><blockquote>
</blockquote>
</li>
</ul>
</li>
<li><span style="color:blue;"><strong>각 패스스루가 끝나면 버블이 이제 올바른 위치에 있게 된다. 즉 <code>unsortedUntilIndex</code>변수가 기존에 가리키고 있던 인덱스가 정렬된 상태이니 <code>unsortedUntilIndex</code>변수의 값을 1 감소 시킨다.</strong></span><blockquote>
</blockquote>
</li>
<li><span style="color:blue;"><strong><code>sorted</code>변수가 <code>true</code>인 채로 패스스루가 끝나면 <code>while</code>루프가 종료된다. 이 때 정렬된 배열을 반환한다.</strong></span></li>
</ul>
<pre><code class="language-java">public static ArrayList&lt;Integer&gt; bubbleSort(ArrayList&lt;Integer&gt; list) {
    int unsortedUntilIndex = list.size() - 1;
    boolean sorted = false;

    while (!sorted) {
        sorted = true;

        for (int pointer = 0; pointer &lt; unsortedUntilIndex; pointer++) {
            int thisValue = list.get(pointer);
            int nextValue = list.get(pointer+1);
            if (thisValue &gt; nextValue) {
                list.set(pointer, nextValue);
                list.set(pointer+1, thisValue);
                sorted = false;
            }
        }

        unsortedUntilIndex--;
    }

    return list;
}</code></pre>
<ul>
<li><strong>main 출력</strong> 테스트 통과!</li>
</ul>
<pre><code class="language-java">public static void main(String[] args) {
    ArrayList&lt;Integer&gt; list1 = new ArrayList&lt;&gt;(Arrays.asList(4, 2, 7, 1, 3));
    ArrayList&lt;Integer&gt; list2 = new ArrayList&lt;&gt;(Arrays.asList(9, 1, 5, 2, 1, 6));

    bubbleSort(list1);
    for (int i : list1)
        System.out.print(i +&quot; &quot;);

    System.out.println(&quot;\n --------&quot;);

    bubbleSort(list2);
    for (int i : list2)
        System.out.print(i +&quot; &quot;);
}</code></pre>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/7b96e809-3057-4459-8647-749a7b8511de/image.png" alt=""></p>
<h2 id="🔶-효율성--span-stylecolorredon²span">🔶 효율성 : <span style="color:red;"><strong><code>O(N²)</code></strong></span></h2>
<p>버블 정렬 알고리즘은 비교<code>comparison</code>과 교환<code>swap</code>의 두 가지 단계를 포함한다.</p>
<blockquote>
<p>원소가 5개인 정렬되지 않은 배열을 생각해보자.</p>
</blockquote>
<ul>
<li><p>비교 <code>comparison</code> </p>
<ul>
<li><p>첫 번째 패스스루에서는 비교를 4번 일어난다.</p>
</li>
<li><p>두 번째 패스스루에서는 비교를 3번 일어난다.</p>
</li>
<li><p>세 번째 패스스루에서는 비교를 2번 일어난다.</p>
</li>
<li><p>네 번째 패스스루에서는 비교를 1번 일어난다.</p>
</li>
<li><p>총 10번의 비교다.</p>
</li>
</ul>
<p>➡️ <span style="background-color:yellow; color:black;"><strong>배열의 원소가 N개일 때, (N-1) + (N-2) + (N-3) + … + 1 번의 &quot;비교&quot;를 수행한다.</strong></span></p>
</li>
</ul>
<ul>
<li><p>교환 <code>swap</code></p>
<ul>
<li><p>배열이 역순으로 정렬된 <span style="background-color:yellow; color:black;"><strong>최악의 시나리오라면 비교할 때마다 교환을 해야한다.</strong></span> </p>
</li>
<li><p>첫 번째 패스스루에서는 비교를 4번 했으니 교환도 4번 일어난다.</p>
</li>
<li><p>두 번째 패스스루에서는 비교를 3번 했으니 교환도 3번 일어난다.</p>
</li>
<li><p>세 번째 패스스루에서는 비교를 2번 했으니 교환도 2번 일어난다.</p>
</li>
<li><p>네 번째 패스스루에서는 비교를 1번 했으니 교환도 1번 일어난다.</p>
</li>
<li><p>총 10번의 교환이다.</p>
</li>
</ul>
<p>➡️ <span style="background-color:yellow; color:black;"><strong>배열의 원소가 N개일 때, (N-1) + (N-2) + (N-3) + … + 1 번의 &quot;교환&quot;을 수행한다.</strong></span></p>
</li>
</ul>
<p>원소 5개가 역순으로 된 배열에서는 4+3+2+1 = 10번의 비교와 4+3+2+1 = 10번의 교환이 일어나므로 총 20단계다.</p>
<p>원소 10개가 역순으로 된 배열에서는 9+8+7+6+5+4+3+2+1 = 45번의 비교와 45번의 교환이 일어나므로 총 90단계다.</p>
<p>원소 20개가 역순으로 된 배열에서는 19 + 18 + 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 = 190번의 비교와 교환이 일어나므로 총 380단계다. </p>
<p>원소 수가 증가할수록 단계 수가 기하급수적으로 늘어난다.</p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/1f1df3fe-3aef-4619-a802-d30e1ac05be0/image.png" alt=""></p>
<p><span style="color:red;"><strong>N이 증가할 때마다 단계 수가 대략  N²만큼 늘어남을 알 수 있다.</strong></span> </p>
<p><span style="color:red;"><strong>배열의 원소가 N개일 때 버블 정렬에는 N²단계가 필요하다. ➡️ O(N²)</strong></span></p>
<h1 id="🟪-on²">🟪 O(N²)</h1>
<h2 id="🔶-버블정렬과-중첩루프">🔶 버블정렬과 중첩루프</h2>
<p><span style="background-color:yellow; color:black;"><strong>버블정렬과 중첩루프가 대표적인 O(N²)알고리즘의 예시이다.</strong></span></p>
<p>버블정렬을 살펴보았고 중첩루프의 예시를 들겠다. </p>
<h3 id="🔵-중첩루프-예시">🔵 중첩루프 예시</h3>
<blockquote>
<p>주어진 배열의 모든 숫자 쌍의 최대곱<code>the greatest product</code>을 찾는다.</p>
</blockquote>
<pre><code class="language-java">public static int greatestProduct(int[] array) {
    int greatestProduct = array[0] * array[1];

    for (int i = 0; i &lt; array.length; i++) {
        for (int j = 0; j &lt; array.length; j++) {
            int nowProduct = array[i] * array [j];
            if (i != j &amp;&amp; ( nowProduct &gt; greatestProduct))
                greatestProduct = nowProduct;
        }
    }

    return greatestProduct;
}</code></pre>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/4acf7ebe-a55f-4637-9255-aa55430fade0/image.png" alt=""></p>
<h2 id="🔶-이차시간">🔶 이차시간</h2>
<p><span style="background-color:yellow; color:black;"><strong>O(N²)을 이차시간<code>quadratic time</code> 이라고도 부른다.</strong></span></p>
<h2 id="🔶-on²-vs-on-그래프">🔶 <code>O(N²) vs O(N)</code> 그래프</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/3da6a968-1709-4621-841a-28dea72ec489/image.png" alt=""></p>
<p>단순한 대각선을 그리는 O(N)과 대비되게 데이터가 늘어날수록 O(N²)의 단계 수가 매우 급격히 증가하고 있다. 그래서 O(N²)은 비효율적인 알고리즘으로 분류된다.  </p>
<h2 id="🔶-이차-문제">🔶 이차 문제</h2>
<p><span style="background-color:yellow; color:black;"><strong>느린 O(N²) 알고리즘을 빠른 O(N) 알고리즘으로 대체</strong></span>하고자 하는 것을 <span style="background-color:yellow; color:black;"><strong>이차문제</strong></span>라고 한다. </p>
<h3 id="🔵-중첩루프-문제와-선형-해결법">🔵 중첩루프 문제와 선형 해결법</h3>
<p>루프 내에 다른 루프를 중첩하는 알고리즘은 O(N²)이다.
(항상은 아니다.) </p>
<p>O(N²)은 상대적으로 느린 알고리즘이다.</p>
<p>느린 알고리즘을 마주할 때는 시간을 들여 더 빠른 속도의 알고리즘 대안은 없을 지 고민해 보는 것이 좋다. </p>
<p>대안 중 하나로 선형 해결법을 고려해볼 수 있다.</p>
<p>선형 해결법은 중첩 루프를 쓰지 않는 것을 의미한다. </p>
<h1 id="🟪-이차문제-연습">🟪 이차문제 연습</h1>
<h2 id="🔶-중복-값-확인하는-함수">🔶 중복 값 확인하는 함수</h2>
<blockquote>
<p>( 사용자가 제품에 대해 1부터 10사이로 매긴 평점을 분석하는 애플리케이션에서 평점 ) 배열에 중복 숫자가 들어 있는지 확인하는 함수</p>
</blockquote>
<p>예를 들어 배열 { 1, 5, 3, 9, 1, 4 } 에는 숫자 1이 중복되므로 <code>true</code>를 반환한다.</p>
<h3 id="🔵-중첩루프로-구현한다-➡️-on²">🔵 중첩루프로 구현한다. ➡️ O(N²)</h3>
<p>: 함수는 반복해서 <code>i</code>와 <code>j</code>를 비교한다. 최악의 시나리오는 배열에 중복 값이 없는 경우다. 배열에 N개가 있을 때 함수는 N²번의 비교를 수행한다. ➡️ O(N²)</p>
<pre><code class="language-java">public static boolean hasDuplicateValue(int[] array) {
    for (int i = 0; i &lt; array.length; i++) {
        for (int j = 0; j &lt;array.length; j++) {
            if (i != j &amp;&amp; array[i] == array[j])
                return true;
        }
    }
    return false;
}</code></pre>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/8e02288b-bec3-4a25-b07c-35565b82f51e/image.png" alt=""></p>
<h3 id="🔵-선형해결법으로-구현한다-➡️-on">🔵 선형해결법으로 구현한다. ➡️ O(N)</h3>
<p>: 단 하나의 루프에서 단지 배열에 있는 원소 수만큼 순회하기 때문에 배열에 N개의 원소가 있을 때 N단계가 걸린다. ➡️ O(N)</p>
<ul>
<li><strong><code>JS</code> 코드</strong><ul>
<li><code>existingNumbers</code>라는 빈 배열을 생성한다.</li>
<li><code>for</code>루프를 사용해 <code>array</code>의 각 숫자를 확인한다.</li>
<li>숫자가 나올 때마다 <code>existingNumbers</code>배열에 그 숫자 해당하는 <code>인덱스</code>에 임의의 값 <code>1</code>을 넣는다.<ul>
<li>예시) <code>{3, 5, 8}</code>배열에서 <code>3</code>이 나오면 <code>existingNumbers</code>배열의 <code>인덱스3</code>에 <code>1</code>을 대입한다.</li>
<li>그러면 <code>existingNumbers</code>배열은 이렇게 된다.
: { null , null , null , 1 }</li>
</ul>
</li>
<li>본질적으로 <code>existingNumbers</code>의 인덱스를 사용해 지금까지 <code>array</code>에서 어떤 숫자들이 나왔는지 알 수 있다.</li>
<li>해당 <code>인덱스</code>에 <code>1</code>을 저장하기 전에 이 <code>인덱스</code>의 값이 이미 1인지 확인한다.</li>
<li>해당 <code>인덱스</code>의 값이 1이면, 중복값이라는 뜻이므로 <code>true</code>를 반환한다.</li>
<li>루프 끝까지 갔다면 중복 값이 없다는 뜻이므로 <code>false</code>를 반환한다.</li>
</ul>
</li>
</ul>
<pre><code class="language-javascript">function hasDuplicateValue(array) {
  let existingNumbers = [];

  for(let i = 0; i &lt; array.length; i++) {
    if(existingNumbers[array[i]] === 1)
      return true;
    else
      existingNumbers[array[i]] = 1;
  }

  return false;
}</code></pre>
<ul>
<li><strong><code>Java</code> 코드</strong><ul>
<li><code>existingNumbers</code>라는 <code>ArrayList</code>을 생성한다.</li>
<li><span style="color:red;"><strong>❗<code>ArrayList</code>는 리스트의 끝으로만 추가할 수 있기 때문에</strong></span>, 
<code>array</code>의 값을 <code>인덱스</code>로 하여 임의의 값 <code>1</code>을 추가  할 수 없다. <ul>
<li><code>{3,5,8}</code>에서 <code>ArrayList.add(3, 1)</code>이렇게 하면
(인덱스는 {3,5,8}의 3, 값은 임의의 값 1)
<span style="color:red;">** <code>IndexOutOfBoundsException: Index: 3, Size: 0</code>라는 에러가 뜬다.**</span></li>
<li>그래서 그냥 <code>array</code>의 값을 넣는 식으로 해야한다.</li>
<li><code>{3,5,8}</code>에서 <code>ArrayList.add(3)</code>이런 식으로.</li>
</ul>
</li>
<li><code>for</code>루프를 사용해 <code>array</code>의 각 숫자를 확인한다.</li>
<li>숫자가 나올 때마다 <code>existingNumbers</code>배열에 그 숫자를 추가<code>add()</code>한다.<ul>
<li>예시) <code>{3, 5, 8}</code>배열에서 <code>3</code>이 나오면 <code>existingNumbers</code>배열에 <code>3</code>을 대입한다.
: <code>existingNumbers.add(3)</code></li>
<li>그러면 <code>existingNumbers</code>배열은 이렇게 된다.
: { 3 }</li>
</ul>
</li>
<li>해당 값을 <code>ArrayList</code>에 저장하기 전에 이미 있는 값인지 확인한다. 있으면 <code>true</code>를 반환한다. 
: <code>existingNumbers.contains(3)</code></li>
<li>루프 끝까지 갔다면 중복 값이 없다는 뜻이므로 <code>false</code>를 반환한다.</li>
</ul>
</li>
</ul>
<pre><code class="language-java">public static boolean hasDuplicateValue2(int[] array) {
    ArrayList&lt;Integer&gt; existingNumbers = new ArrayList&lt;&gt;();

    for (int value : array) {
        if (existingNumbers.contains(value))
            return true;
        else
            existingNumbers.add(value);
    }

    return false;
}</code></pre>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/51632ec8-e429-4c1d-aa86-4ab7d7a443a0/image.png" alt=""></p>
<h2 id="🔶-최댓값-찾는-함수">🔶 최댓값 찾는 함수</h2>
<blockquote>
<p>배열에서 가장 큰 수를 찾는 함수이다.</p>
</blockquote>
<h3 id="🔵-중첩루프로-구현한다-➡️-on²-1">🔵 중첩루프로 구현한다. ➡️ O(N²)</h3>
<ul>
<li>우선 첫번째 <code>for</code>루프로 나오는 숫자가 제일 크다고 가정한다 
: <code>isNumber1GreatestNumber = true</code></li>
<li>첫번째 <code>for</code>루프로 나오는 숫자가 두번째 <code>for</code>루프로 나오는 숫자보다 작으면 제일 큰 값이 아니게 된다.
: <code>isNumber1GreatestNumber = false</code></li>
<li>첫번째 <code>for</code>루프로 나오는 숫자가 두번째 <code>for</code>루프로 나오는 숫자들 모두 확인했는데도 제일 크면, 전체 배열에서 가장 큰 수 이므로 <code>return</code>한다.</li>
<li><code>java</code>에서는 <code>if</code>문에서 <code>return</code>하면 <code>else</code>문 또는 메소드 자체에서 <code>return</code>값이 있어야 하므로 <code>int failResult = 0;</code>을 선언하여 마지막에 <code>return failResult;</code>한다.</li>
</ul>
<pre><code class="language-java">public static int greatestNumber(int[] array) {
    int failResult = 0;
    for (int number1 : array) {
        boolean isNumber1GreatestNumber = true;
        for (int number2 : array) {
            if (number1 &lt; number2)
                isNumber1GreatestNumber = false;
        }
        if (isNumber1GreatestNumber)
            return number1;
    }
    return failResult;
}</code></pre>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/91c04303-1c1c-4b24-bbde-0005a1eebd98/image.png" alt=""></p>
<h3 id="🔵-선형해결법으로-구현한다-➡️-on-1">🔵 선형해결법으로 구현한다. ➡️ O(N)</h3>
<ul>
<li><code>greatestNumber</code>을 임의로 정해서 <code>for</code>루프로 나오는 숫자들과 비교하여 결과에 맞춰 <code>greatestNumber</code>값을 계속 바꾸다가 마지막에 <code>return</code>한다.</li>
</ul>
<pre><code class="language-java">public static int greatestNumber2(int[] array) {
    int greatestNumber = array[0];

    for (int number : array) {
        if (number &gt; greatestNumber)
            greatestNumber = number;
    }

    return greatestNumber;
}</code></pre>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/5d87dc3e-7439-404c-8d35-377fb5f506a6/image.png" alt=""></p>
<p><br><br><br></p>
<hr>
<p><br><br><br></p>
<h1 id="🟦-출처">🟦 출처</h1>
<h2 id="🔷-그림-1">🔷 그림 1</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/42e4f4dc-ee7d-4886-a3a0-fc68c4ceedc4/image.png" alt=""></p>
<p><a href="https://beccacatcheserrors.tistory.com/3">티스토리 사이트의 베카의에러뿌시기 블로그의 &#39;빅오표기법(Big O notation)&#39; 게시글 보러가기</a></p>
<h2 id="🔷-글의-내용">🔷 글의 내용</h2>
<p>이 글 내용은 &#39;제인 웬그로우&#39;의 &#39;누구나 자료구조와 알고리즘 개정 2판&#39; 책을 100% 참고하여 작성하였습니다. 설명에 전문적인 용어보다는 일상적인 용어를 사용하고 그림으로 원리를 설명해주어 왕초보인 저가 이해하기에 아주 좋았습니다. 가격이 많이 나가는 편이지만 꼭 배워야 하는 내용이 모두 들어있고 그것을 제가 이해할 수 있는 수준으로 쓰여있어 전혀 아깝지 않은 소비였습니다. </p>
<p><img src="http://image.kyobobook.co.kr/images/book/xlarge/061/x9791160505061.jpg" alt="누구나 자료구조와 알고리즘 책 사진"></p>
<p><a href="http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&amp;ejkGb=KOR&amp;barcode=9791160505061">🖱 클릭! | &#39;제인 웬그로우&#39;의 &#39;누구나 자료구조와 알고리즘&#39; 책 구경하러 가보기</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[누구나 자료구조와 알고리즘] O(N), O(1), O(logN), 로그 뜻, 빅오표기법, 상수시간, 로그시간]]></title>
            <link>https://velog.io/@on-n-on-turtle/%EB%88%84%EA%B5%AC%EB%82%98-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0%EC%99%80-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%B9%85%EC%98%A4%ED%91%9C%EA%B8%B0%EB%B2%95</link>
            <guid>https://velog.io/@on-n-on-turtle/%EB%88%84%EA%B5%AC%EB%82%98-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0%EC%99%80-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%B9%85%EC%98%A4%ED%91%9C%EA%B8%B0%EB%B2%95</guid>
            <pubDate>Sun, 31 Jul 2022 16:23:16 GMT</pubDate>
            <description><![CDATA[<h1 id="🟪--빅오-표기법이-필요한-이유">🟪  빅오 표기법이 필요한 이유</h1>
<p><span style="background-color:yellow; color:black;"><strong>&#39;알고리즘 수행에 필요한 단계 수&#39;가 알고리즘의 효율성을 결정하는 주된 요인이다.</strong></span> </p>
<p>그러나 단순히 알고리즘을 &quot;22단계의 알고리즘&quot;, &quot;400단계의 알고리즘&quot; 이라고 표시할 수는 없다. <span style="background-color:yellow; color:black;"><strong>이 단계 수라는 것을 하나의 수로 확정지을 수 없기 때문이다.</strong></span> </p>
<p>예를 들어 선형 검색에는 배열의 원소 개수 만큼 단계 수가 필요하다. 그래서 원소가 4개일 땐 4단계가, 100개일 땐 100단계가 필요하므로 그때 그때 마다 달라지는 것이다. </p>
<p>이러한 *<em>선형 검색의 효율성을 &#39;배열에 N개의 원소가 있을 때 N단계가 필요하다&#39;라고 표현하는 것이 몇 단계로 정량화 하는 것보다 훨씬 효과적이다. *</em></p>
<blockquote>
<p><strong>컴퓨터 과학자는 시간 복잡도를 쉽게 소통할 목적으로 자료 구조와 알고리즘의 효율성을 간결하고 일관된 언어로 설명하기 위해 수학적 개념을 차용했다.</strong></p>
</blockquote>
<p><strong>이러한 개념을 형식화한 표현을 빅 오 표기법이라고 부른다.</strong></p>
<p><strong>빅 오 표기법을 사용해 주어진 알고리즘의 효율성을 쉽게 분류할 수 있다.</strong></p>
<p><span style="background-color:yellow; color:black;"><strong>빅 오 표기법을 알면 일관되고 간결한 방법으로 어떤 알고리즘이든 분석할 수 있는 도구가 생긴 것이다.</strong></span> </p>
<h1 id="🟪-span-stylecolorred🌟빅-오의-본질🌟span">🟪 <span style="color:red;">🌟빅 오의 본질🌟</span></h1>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/f25ce623-d9f6-414d-9626-21bd03f4f180/image.png" alt=""></p>
<h2 id="🔶-데이터-원소-n개에-대한-알고리즘의-단계-수를-의미한다">🔶 데이터 원소 N개에 대한 알고리즘의 단계 수를 의미한다.</h2>
<p><span style="background-color:yellow; color:black;"><strong>빅 오 :  데이터 원소가 N개일 때 알고리즘에 몇 단계가 필요할까?</strong></span>
<span style="background-color:yellow; color:black;">*<em>↳  빅 오 표기법의 핵심질문이자 정의이다 ! *</em></span></p>
<p><span style="background-color:yellow; color:black;"><strong>핵심 질문에 대한 답은 빅 오 표현의 괄호 안에 들어있다.</strong></span><span style="background-color:yellow; color:black;"><strong>O(N)은 알고리즘에 N 단계가 필요하다</strong></span><span style="background-color:yellow; color:black;"><strong>는 핵심 질문에 대한 답을 나타낸다.</strong></span></p>
<p><span style="color:red;"><strong>❗빅 오는 데이터 원소가  N개일 대 알고리즘에 몇 단계가 필요한가에 대한 답이다. 데이터 원소 N개에 대한 알고리즘의 단계 수를 나타낸다.</strong></span></p>
<h2 id="🔶-데이터가-늘어날-때-단계-수가-어떻게-증가하는가를-의미한다">🔶 데이터가 늘어날 때 단계 수가 어떻게 증가하는가를 의미한다.</h2>
<h3 id="🔵-o3--o100--o1">🔵 <code>O(3) == O(100) == O(1)</code></h3>
<blockquote>
<p>데이터가 몇 개든 항상 3단계가 걸리는 알고리즘을 가정하자. 
즉 원소가 N개일 때 알고리즘에 항상 3단계가 필요하다. 
이를 빅 오로 어떻게 표현할까? </p>
</blockquote>
<p>O(3)일까? 아니다. O(1)이다.</p>
<blockquote>
</blockquote>
<p>이유는 빅오가 알고리즘에 필요한 단계 수를 알려주는 것 말고도 한 가지 더 역할을 한다는 것에 있다. </p>
<p>빅 오는 단순히 알고리즘에 필요한 단계 수 뿐만 아니라, <span style="color:red;"><strong>❗데이터가 늘어날 때 알고리즘의 단계 수가 어떻게 증가하는지, 성능이 어떻게 바뀌는지도 설명한다.</strong></span> </p>
<p>이러한 관점에서 보면  알고리즘이 O(1)이든 O(3)이든 별로 중요하지 않다. </p>
<p><span style="background-color:yellow; color:black;"><strong>O(1)과 O(3) 두 알고리즘 모두 데이터 증가에 영향을 받지 않는, 즉 단계 수가 변하지 않는 유형이므로 본질적으로 같은 알고리즘 유형이다. N이 얼마든 항상 상수 단계만 필요하다. 그래서 O(1) 알고리즘을 상수시간<code>constant time</code>을 갖는 알고리즘이라고도 표현한다.</strong></span> </p>
<p>둘 다 데이터에 관계없이 단계 수가 일정한 알고리즘이므로 둘을 구분할 필요가 없다.</p>
<h3 id="🔵-o1과--on에서-데이터-변화가-미치는-영향">🔵 <code>O(1)</code>과  <code>O(N)</code>에서 데이터 변화가 미치는 영향</h3>
<p>O(1)이 데이터 증가 또는 감소에 영향을 받지 않는 반면 <span style="background-color:yellow; color:black;"><strong>O(N) 알고리즘은 데이터 증가가 성능에 영향을 미친다. 데이터가 늘어날 때 정확히 그 데이터에 비례해 단계 수가 증가하는 알고리즘 유형이다. 알고리즘의 효율성과 데이터가 비례 관계이다.</strong></span> <span style="color:red;"><strong>데이터가 증가할 때 단계 수가 정확히 어떻게 증가하는지 설명한다.</strong></span> </p>
<h3 id="🔵-o1--on-그래프">🔵 <code>O(1) &amp; O(N)</code> 그래프</h3>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/c6da76c1-1788-4f2e-907e-f9a2d4142ce5/image.jpeg" alt=""></p>
<p>O(N)은 완벽한 대각선을 그린다. 데이터가 하나씩 추가될 때마다 알고리즘이 한 단계씩 더 걸리기 때문이다. 따라서 데이터가 많아질수록 알고리즘에 필요한 단계 수도 늘어난다. </p>
<p>O(1)은 완벽한 수평선을 그린다. 데이터의 증가나 감소에 영향 받지 않고 단계 수가 일정하다.</p>
<h3 id="🔵-o1알고리즘이-항상-on보다-빠를까-">🔵 O(1)알고리즘이 항상 O(N)보다 빠를까 ?</h3>
<blockquote>
<p>데이터 크기에 상관없이 항상 100단계가 걸리는 상수 시간 알고리즘이 있다면? 
이 알고리즘이 O(N) 알고리즘보다 성능이 우수한가?</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/5e784820-4038-4e96-b519-307ce2c7ed2c/image.png" alt=""></p>
<p>원소가 100개 이하인 데이터 세트에서는 100단계가 걸리는 O(1) 알고리즘보다 O(N) 알고리즘이 단계 수가 더 적다. </p>
<p>두 선이 교차하는 원소가 정확히 100개인 지점에서는 두 알고리즘의 단계 수가 동일하게 100단계이다. </p>
<p>100보다 큰 모든 배열에서는 O(N) 알고리즘이 100단계 O(1) 알고리즘보다 항상 더 많은 단계가 걸린다. 이것이 핵심이다. </p>
<p><span style="background-color:yellow; color:black;"><strong>변화가 생기는 일정량의 데이터가 있을 것이고 O(N)은 그 순간부터 무한대까지 더 많은 단계가 걸리므로 O(1) 알고리즘에 실제로 몇 단계가 걸리든 O(N)이 전반적으로 O(1)보다 덜 효율적이라 볼 수 있다.</strong></span> </p>
<h2 id="🔶-최악의-시나리오를-의미한다">🔶 최악의 시나리오를 의미한다.</h2>
<blockquote>
<p>선형 검색이 항상 O(N)은 아니다. 
검색값이 배열의 맨 처음에 있는 최선의 시나리오에서는 O(1)이고
검색값이 배열의 맨 끝에 있는 최악의 시나리오에서는 O(N)이다.</p>
</blockquote>
<p><span style="color:red;"><strong>빅 오 표기법은 일반적으로 최악의 시나리오를 의미한다.</strong></span></p>
<p>&quot;비관적인&quot; 접근이 유용한 도구일 수 있기 때문이다. </p>
<p><span style="background-color:yellow; color:black;"><strong>최악의 시나리오에서 알고리즘이 얼마나 비효율적인지 정확히 알면 최악을 대비함과 동시에 알고리즘의 선택에 중요한 영향을 미칠 수 있기 때문이다.</strong></span></p>
<h1 id="🟪-on">🟪 <code>O(N)</code></h1>
<p><span style="color:red;"><strong>데이터 원소가 N개일 때 N단계가 걸리는 알고리즘이다.</strong></span>
<span style="color:red;"><strong>데이터가 늘어날 때 정확히 그 데이터에 비례해 단계 수가 증가하는 알고리즘이다.</strong></span></p>
<blockquote>
<p>선형검색 알고리즘을 빅 오로 표현해보자.</p>
</blockquote>
<p>&lt; 빅 오 표기법으로 시간 복잡도를 표현하는 사고 과정 &gt;</p>
<ul>
<li><p>핵심 질문 : <span style="background-color:yellow; color:black;"><strong>배열에 원소가 N개일 때 선형 검색에 몇 단계가 필요할까?</strong></span></p>
</li>
<li><p>정답 : <span style="background-color:yellow; color:black;"><strong>배열에 N개의 원소가 있을 때 선형 검색에 N단계가 필요하다.</strong></span></p>
</li>
<li><p>표현 : <span style="color:red;"><strong>O(N)</strong></span> - &quot;빅 오 N&quot;, &quot;차수 N&quot;, &quot;오 N&quot;이라고 부른다.</p>
</li>
</ul>
<h1 id="🟪-o1--상수시간">🟪 <code>O(1)</code> : 상수시간</h1>
<p><span style="color:red;"><strong>데이터 원소가 N개와 상관없이 항상 일정한 상수 갯수의 단계 수만 걸리는 알고리즘이다.</strong></span>
<span style="color:red;"><strong>데이터 증가에 영향을 받지 않는 알고리즘이다.</strong></span></p>
<blockquote>
<p>배열에서 읽기의 효율성을 빅 오로  표현해보자. </p>
</blockquote>
<p>&lt; 빅 오 표기법으로 시간 복잡도를 표현하는 사고 과정 &gt;</p>
<ul>
<li><p>핵심 질문 : <span style="background-color:yellow; color:black;"><strong>데이터 원소가 N개일 때 배열에서 읽기에 몇 단계가 필요할까?</strong></span></p>
</li>
<li><p>정답 : <span style="background-color:yellow; color:black;"><strong>배열 읽기에 필요한 단계 수는 배열의 크기와 상관없이 딱 하나다.</strong></span></p>
</li>
<li><p>표현 : O(1) - &quot;오 1&quot;</p>
</li>
</ul>
<p>데이터 원소가 &quot;N&quot;개 일때 알고리즘에 필요한 단계 수를 질문했다. 
이 질문은 N에 대한 물음이었으나 답은 N과 무관하다.
배열에 원소가 몇 개든 배열에서 읽기는 항상 한 단계면 된다. </p>
<p><span style="color:red;"><strong>N에 구애받지 않고 항상 1단계만 걸리므로 O(1)을 가장 빠른 알고리즘 유형으로 분류한다. 
데이터가 늘어나도 알고리즘의 단계 수는 증가하지 않는다.</strong></span> </p>
<p><span style="color:red;"><strong>N이 얼마든 항상 상수 단계만 필요하다. 그래서 O(1) 알고리즘을 상수시간<code>constant time</code>을 갖는 알고리즘이라고도 표현한다.</strong></span></p>
<h1 id="🟪-로그-log-뜻">🟪 로그 <code>log</code> 뜻</h1>
<p>로그는 로가리즘<code>logarithm</code>의 줄임말이다.</p>
<p><span style="color:red;"><strong>❗로그<code>log</code></strong></span></p>
<ul>
<li><span style="color:red;"><strong>지수<code>exponent</code>와 역<code>inverse</code>의 관계다.</strong></span></li>
<li><span style="color:red;"><strong>2를 몇 번 곱해야 N이 나올까? = <code>log₂N</code></strong></span></li>
<li><span style="color:red;"><strong>1이 될 때까지 N을 2로 몇 번 곱해야 할까? = <code>log₂N</code></strong></span></li>
</ul>
<h3 id="🔵-지수exponent와-역inverse의-관계다">🔵 지수<code>exponent</code>와 역<code>inverse</code>의 관계다.</h3>
<p><code>log₂8</code>은 2³의 역<code>converse</code> 관계다.</p>
<p><code>log₂64</code>은 2⁶의 역이다.</p>
<h3 id="🔵-2를-몇-번-곱해야-n이-나올까">🔵 2를 몇 번 곱해야 N이 나올까?</h3>
<p>2를 세 번 곱해야 8이 나오므로 <code>log₂8</code> = 3이다.</p>
<p>2를 여섯 번 곱해야 8이 나오므로 <code>log₂64</code> = 6이다.</p>
<h3 id="🔵-1이-될-때까지-n을-2로-몇-번-곱해야-할까">🔵 1이 될 때까지 N을 2로 몇 번 곱해야 할까?</h3>
<p>8 / 2 / 2 / 2 = 1
8이 1이 될 때까지 2를 세 번 나눠야 하므로 <code>log₂8</code> = 3이다.</p>
<p>64 / 2 / 2 / 2 / 2 / 2 / 2 = 1
64가 1이 될 때까지 2를 여섯 번 나눠야 하므로 <code>log₂64</code> = 6이다.</p>
<h1 id="🟪-ologn----로그시간">🟪 <code>O(logN)</code>  :  로그시간</h1>
<h2 id="🔶-ologn--olog₂n">🔶 <code>O(logN) == O(log₂N)</code></h2>
<p>컴퓨터 과학에서 O(logN)은 O(log₂N)을 줄여 부르는 말이다.</p>
<ul>
<li><span style="color:red;"><strong>핵심 질문 : 데이터 원소가 N개 일 때 알고리즘에 몇 단계가 필요할까?</strong></span></li>
<li><span style="color:red;"><strong>정답 : O(logN)은 데이터 원소가 N개 있을 때 알고리즘에 log₂단계가 걸린다.</strong></span></li>
</ul>
<p>원소가 8개면 <code>log₂8</code> = 3이므로 이 알고리즘은 3단계가 걸린다. </p>
<p>이진 검색이 정확히 O(logN) 알고리즘 방식으로 동작한다. </p>
<blockquote>
<p><span style="background-color:yellow; color:black;"><strong>이진 검색</strong></span>을 빅 오 표기법의 관점에서 어떻게 설명할까?</p>
</blockquote>
<ul>
<li>배열의 크기가 3일 때 이진 검색은 2단계</li>
<li>배열의 크기가 7일 때 이진 검색은 3단계</li>
<li>배열의 크기가 15일 때 이진 검색은 4단계</li>
<li>배열의 크기가 100일때 이진 검색은 7단계</li>
<li>배열의 크기가 10,000일때 이진 검색은 13단계</li>
<li>배열의 크기가 1,000,000일때 이진 검색은 20단계</li>
</ul>
<p><span style="background-color:yellow; color:black;"><strong>데이터가 커질수록 단계 수가 늘어나므로 이진 검색은 O(1)이라 표현할 수 없다.
검색하고 있는 배열의 원소 수보다 단계 수가 훨씬 적으므로 O(N)이라 표현할 수도 없다.</strong></span></p>
<p><span style="background-color:yellow; color:black;"><strong>이진 검색은 O(1)과 O(N)사이 어디쯤엔가 있다. 
이것을 빅 오로 O(logN)으로 나타낸다.</strong></span>
그리고 오 로그 엔 이라고 부른다.</p>
<h2 id="🔶-데이터가-두-배로-증가할-때마다-한-단계씩-늘어나는-알고리즘">🔶 데이터가 두 배로 증가할 때마다 한 단계씩 늘어나는 알고리즘</h2>
<p><span style="color:red;"><strong>❗O(logN)</strong></span> : 오 로그 N</p>
<ul>
<li><span style="color:red;"><strong>로그시간<code>log time</code>의 시간 복잡도</strong></span></li>
<li><span style="color:red;"><strong>데이터 원소가 N개 있을 때 알고리즘에 log₂단계가 걸린다.</strong></span></li>
<li><span style="color:red;"><strong>데이터가 두 배로 증가할 때마다 한 단계씩 늘어나는 알고리즘</strong></span></li>
</ul>
<p>이러한 유형의 알고리즘을 로그시간<code>log time</code>의 시간 복잡도라고 말한다. 이 말의 뜻은 빅오의 방법으로 O(logN)을 데이터가 두 배로 증가할 때마다 한 단계씩 늘어나는 알고리즘이라고 설명하는 것이다. </p>
<h1 id="🟪-o1--on--ologn-그래프">🟪 <code>O(1) &amp; O(N) &amp; O(logN)</code> 그래프</h1>
<p><span style="background-color:yellow; color:black;"><strong>O(1) &gt; O(logN) &gt; O(N) 순으로 가장 효율적이다.</strong></span></p>
<p>O(logN)은 아주 조금씩 증가하는 곡선을 그리고 있는데 O(1)보다는 덜 효율적이지만 O(N)보다는 훨씬 효율적이다. </p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/6afb5d50-0162-44fd-ba97-df393b0ccc20/image.png" alt=""></p>
<h1 id="🟪-연습문제">🟪 연습문제</h1>
<blockquote>
<p>다음 알고리즘의 효율성을 빅 오 표기법으로 나타내라.</p>
</blockquote>
<h2 id="🔶-리스트-내-모든-항목을-출력함">🔶 리스트 내 모든 항목을 출력함</h2>
<pre><code class="language-java">public static void printThings() {
    String[] things = {&quot;apples&quot;, &quot;chairs&quot;, &quot;files&quot;, &quot;notes&quot;};

    for (String thing : things)
        System.out.printf(&quot;Here&#39;s a thing : %s \n&quot;, thing);
}</code></pre>
<p>이 알고리즘의 <code>for</code>루프에서 배열의 원소가 4개이기 때문에 4단계가 걸린다.
만약 배열의 원소가 10개이면 10단계가 걸릴 것이다.</p>
<p><span style="background-color:yellow; color:black;"><strong><code>for</code>루프에 대입되는 배열의 원소 갯수만큼 단계가 걸리므로 이 알고리즘의 효율성은 O(N)이다.</strong></span></p>
<h2 id="🔶-주어진-수가-소수인지-알아봄">🔶 주어진 수가 소수인지 알아봄</h2>
<blockquote>
<p>소수는 1보다 큰 자연수 중 1과 자기 자신만을 약수로 가지는 수다. </p>
</blockquote>
<pre><code class="language-java">public static boolean isPrime(int number) {
    if (number == 1) return false;
    for (int i = 2; i &lt; number; i++) {
        if (number % i == 0)
            return false;
    }
    return true;
}</code></pre>
<p>이 코드는 <code>number</code>를 인수로 받아 <code>2</code>부터 <code>number-1</code>까지의 모든 수로 <code>number</code>를 나눠서 나머지가 있는지 확인한다.</p>
<p>나머지가 없으면 이 수는 소수가 아니므로 바로 <code>false</code>를 반환한다.</p>
<p>모든 수로 나눴는데도 항상 나머지가 있으면 이 수는 소수이므로 <code>true</code>를 반환한다. </p>
<p><code>number</code>가 1이면 당연히 소수가 아니므로 <code>false</code>를 반환한다.</p>
<p> <span style="color:red;"><strong>핵심 질문 : <code>number</code>에 <code>N</code>을 전달할 때 알고리즘에 몇 단계가 필요한가?</strong></span>
 <span style="color:red;"><strong>↳ ( <code>number</code>가 함수 루프 실행 횟수를 좌우하기 때문에 <code>N</code>은 <code>number</code>이다. )</strong></span></p>
<p><code>7</code>을 <code>number</code>에 전달하면 <code>for</code>루프는 일곱단계를 실행한다.
(실제로는 2~6까지므로 다섯단계이다.)</p>
<p><code>101</code>이면 루프는 101단계를 실행한다. 
(실제로는 2~100까지므로 99단계이다.)</p>
<p><span style="background-color:yellow; color:black;"><strong>함수로 전달된 수에 비례해 단계 수가 증가하므로 O(N)알고리즘이다.</strong></span></p>
<h2 id="🔶-주어진-해가-윤년인지-알아봄">🔶 주어진 해가 윤년인지 알아봄</h2>
<pre><code class="language-java">public static boolean isLeapYear(int year) {
    return (year % 100 == 0) ? (year % 400 == 0) : (year % 4 == 0);
}</code></pre>
<p><span style="background-color:yellow; color:black;"><strong><code>N</code>은 <code>number</code>이다.</strong></span>
<span style="background-color:yellow; color:black;"><strong>함수로 전달된 수에 상관없이 단계 수가 일정하므로 O(1)알고리즘이다.</strong></span></p>
<h2 id="🔶-주어진-배열의-모든-수를-합함">🔶 주어진 배열의 모든 수를 합함</h2>
<pre><code class="language-java">public static int arraySum(int[] array) {
    int sum = 0;

    for (int num : array)
        sum += num;

    return sum;
}</code></pre>
<p><span style="background-color:yellow; color:black;"><strong><code>N</code>은 배열의 원소 갯수다.</strong></span>
<span style="background-color:yellow; color:black;"><strong>배열의 원소 갯수만큼 <code>for</code>루프가 실행되므로 O(N)알고리즘이다.</strong></span></p>
<h2 id="🔶-몇-번째-칸에-쌀을-놓아야-하는지-계산해줌">🔶 몇 번째 칸에 쌀을 놓아야 하는지 계산해줌</h2>
<p>체스판 한 칸에 쌀 한톨을 놓는다. 
두 번째 칸에는 이전 칸에 놓았던 쌀 양보다 두 배 더 많은 쌀 두 톨을 놓는다.
세 번째 칸에는 쌀 네 톨을 놓는다. (두 번째 칸 * 2)
네 번째 칸에 쌀 여덟 톨을 놓는다. (세 번째 칸 * 2)
다섯 번째 칸에 쌀 열여섯 톨을 놓는다. (네 번째 칸 * 2)</p>
<p>16을 함수에 전달하면 5를 반환한다. </p>
<pre><code class="language-java">public static int getChessboardSpace(int grains) {
    int chessboardSpace = 1;
    int placedGrains = 1;

    while (placedGrains &lt; grains) {
        chessboardSpace++;
        placedGrains *= 2;
    }

    return chessboardSpace;
}</code></pre>
<p><span style="background-color:yellow; color:black;"><strong><code>N</code>은 함수에 전달된 <code>grains</code>이다.</strong></span></p>
<p><code>grains = 256</code> 이면 <code>for</code>루프는 <code>9</code>번 실행된다.
<code>grains = 512</code> 이면 <code>for</code>루프는 <code>10</code>번 실행된다.
<code>grains = 1024</code> 이면 <code>for</code>루프는 <code>11</code>번 실행된다.</p>
<p><span style="background-color:yellow; color:black;"><strong><code>grains</code>가 두배로 늘어날 때 루프는 한 단계만 더 늘어나므로 O(logN)알고리즘이다.</strong></span></p>
<h2 id="🔶-문자열-배열을-받아-a로-시작하는-문자열만-포함시킨-새-배열을-반환함">🔶 문자열 배열을 받아 &quot;a&quot;로 시작하는 문자열만 포함시킨 새 배열을 반환함</h2>
<pre><code class="language-java">public static String[] getAStringsArr(String[] array) {
    ArrayList&lt;String&gt; aStringsArr = new ArrayList&lt;String&gt;();

    for (int i = 0; i &lt;array.length; i++) {
        String firstChar = array[i].split(&quot;&quot;)[0];
        if (&quot;a&quot;.equals(firstChar))
            aStringsArr.add(array[i]);
    }

    return aStringsArr.toArray(new String[aStringsArr.size()]);
}</code></pre>
<p><span style="background-color:yellow; color:black;"><strong><code>N</code>은 함수에 전달된 배열의 원소 갯수이다.</strong></span>
<span style="background-color:yellow; color:black;"><strong>전달된 배열의 원소 갯수만큼 <code>for</code>루프가 실행되므로 O(N)알고리즘이다.</strong></span></p>
<h2 id="🔶-정렬된-배열의-중앙값을-계산함">🔶 정렬된 배열의 중앙값을 계산함.</h2>
<pre><code class="language-java">public static int median(int[] array) {
    int middle = array.length / 2;

    if (array.length % 2 == 0)
        return (array[middle-1] + array[middle]) / 2;
    else
        return array[middle];
}</code></pre>
<p><span style="background-color:yellow; color:black;"><strong><code>N</code>은 함수에 전달된 배열의 길이이다.</strong></span>
<span style="background-color:yellow; color:black;"><strong>전달된 배열의 길이가 얼마든 상관없이 한 단계면 중앙값이 계산되어 반환된다.</strong></span>
<span style="background-color:yellow; color:black;"><strong><code>N</code>이 얼마든 상관없이 정해진 단계수만 걸리므로 O(1)알고리즘이다.</strong></span></p>
<br>
<br>
<br>


<hr>
<br>
<br>

<h1 id="🟦-출처">🟦 출처</h1>
<h2 id="🔷-그림-1">🔷 그림 1</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/5075f6e8-08cd-41bb-b134-6c7cd9f0e688/image.png" alt=""></p>
<p><a href="https://velog.io/@welloff_jj/Complexity-and-Big-O-notation">벨로그 사이트의 welloff_jj님의 hyeojung.log블로그의 &#39;복잡도(Complexity): 시간 복잡도와 공간 복잡도, 그리고 빅오(Big-O) 표기법&#39; 게시물 보러가기</a></p>
<h2 id="🔷-그림-2">🔷 그림 2</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/e7f9ee27-5ca5-44de-b549-e6921d087ea8/image.png" alt=""></p>
<p><a href="https://towardsdatascience.com/the-big-o-notation-d35d52f38134">Towards Data Science사이트의 Semi Koen의 The Big O Notation 게시물 보러가기</a></p>
<h2 id="🔷-글의-내용">🔷 글의 내용</h2>
<p>이 글 내용은 &#39;제인 웬그로우&#39;의 &#39;누구나 자료구조와 알고리즘 개정 2판&#39; 책을 100% 참고하여 작성하였습니다. 설명에 전문적인 용어보다는 일상적인 용어를 사용하고 그림으로 원리를 설명해주어 왕초보인 저가 이해하기에 아주 좋았습니다. 가격이 많이 나가는 편이지만 꼭 배워야 하는 내용이 모두 들어있고 그것을 제가 이해할 수 있는 수준으로 쓰여있어 전혀 아깝지 않은 소비였습니다. </p>
<p><img src="http://image.kyobobook.co.kr/images/book/xlarge/061/x9791160505061.jpg" alt="누구나 자료구조와 알고리즘 책 사진"></p>
<p><a href="http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&amp;ejkGb=KOR&amp;barcode=9791160505061">🖱 클릭! | &#39;제인 웬그로우&#39;의 &#39;누구나 자료구조와 알고리즘&#39; 책 구경하러 가보기</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[누구나 자료구조와 알고리즘] 이진검색,정렬된 배열, 알고리즘이란, 알고리즘이 중요한 이유]]></title>
            <link>https://velog.io/@on-n-on-turtle/%EB%88%84%EA%B5%AC%EB%82%98-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0%EC%99%80-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%A0%95%EB%A0%AC%EB%90%9C-%EB%B0%B0%EC%97%B4-%EC%9D%B4%EC%A7%84%EA%B2%80%EC%83%89-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%9D%B4%EB%9E%80-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%9D%B4-%EC%A4%91%EC%9A%94%ED%95%9C-%EC%9D%B4%EC%9C%A0</link>
            <guid>https://velog.io/@on-n-on-turtle/%EB%88%84%EA%B5%AC%EB%82%98-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0%EC%99%80-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%A0%95%EB%A0%AC%EB%90%9C-%EB%B0%B0%EC%97%B4-%EC%9D%B4%EC%A7%84%EA%B2%80%EC%83%89-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%9D%B4%EB%9E%80-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%9D%B4-%EC%A4%91%EC%9A%94%ED%95%9C-%EC%9D%B4%EC%9C%A0</guid>
            <pubDate>Sat, 30 Jul 2022 06:07:36 GMT</pubDate>
            <description><![CDATA[<h1 id="🟪-정렬된-배열">🟪 정렬된 배열</h1>
<p><span style="background-color:yellow; color:red;"><strong><code>ordered array</code></strong></span></p>
<p>정렬된 배열과 일반 배열의 차이점은 <span style="background-color:yellow; color:black;"><strong>&quot;값이 항상 순서대로 있어야 한다&quot;</strong></span> 는 점이다.
<span style="color:red;"><strong>❗값을 추가할 때마다 적절한 위치에 삽입하여 값을 정렬된 상태로 유지한다.</strong></span></p>
<h2 id="🔶-삽입----ⓝ②단계--">🔶 삽입 : <code>[</code>  ⓝ+②단계  <code>]</code></h2>
<blockquote>
<p>아래의 정렬된 배열에 <code>75</code>를 삽입해보자. </p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/cfa7cbce-1cd4-4776-bcfe-ec3523807d4f/image.png" alt=""></p>
<p>일반 배열이라면 배열의 맨 끝에 <code>75</code>를 삽입하여 한 단계만 삽입이 처리 된다.</p>
<p>하지만 정렬된 배열에서는 값을 오름차순으로 유지해야 하기 때문에 <span style="background-color:yellow; color:black;"><strong>적절한 위치를 찾고 다른 값들을 옮겨 그 위치를 빈 공간으로 만드는 과정이 추가로 필요하다.</strong></span> 그 다음에 삽입을 처리할 수 있는 것이다. </p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/25888e2c-82f0-4055-be46-a9d104dcba4b/image.png" alt=""></p>
<ul>
<li><p><span style="background-color:LightCyan; color:black;  ">1단계 :</span>  <span style="background-color:yellow; color:black;"><strong>[ 비교 ] <code>인덱스0</code>의 값을 확인하여 삽입값 <code>75</code>와 비교한다. <code>75</code>는 <code>3</code>보다 크므로 오른쪽에 들어가야 한다. 하지만 정확한 삽입 위치를 알 수 없으므로 다음 셀을 확인해야 한다.</strong></span></p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">2단계 :</span> <code>인덱스1</code>의 값을 확인한다. <code>75</code>가 더 크므로 다음 셀을 확인한다.</p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">3단계 :</span> <code>인덱스2</code>의 값을 확인한다. <strong><code>75</code>보다 더 큰 값이 나왔다! <span style="background-color:yellow; color:black;">앞 셀은 <code>75</code>보다 작고 지금 셀은 <code>75</code>보다 큰 첫 값이다.</span> 그러므로 여기 <span style="background-color:yellow; color:black;"><code>인덱스2</code>에 <code>75</code>를 삽입하면 정렬된 배열을 유지할 수 있다</span></strong> 는 것을 알 수 있다. </p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">4단계 :</span> <span style="background-color:yellow; color:black;"><strong>[ 옮기기 ] <code>인덱스2</code>를 빈 공간으로 만들기 위해</strong></span> 마지막 값인 <code>인덱스3</code>의 값을 <span style="background-color:yellow; color:black;">*<em>오른쪽으로 옮긴다. *</em></span></p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">5단계 :</span> <code>인덱스3</code>을 오른쪽으로 옮긴다.</p>
</li>
<li><p><span style="background-color:LightCyan; color:black;  ">6단계 :</span> <span style="background-color:yellow; color:black;"><strong>[ 삽입 ]</strong></span> <code>인덱스2</code>가 적절한 위치이고 빈공간이 되었다. 여기에 <code>75</code>를 삽입한다.</p>
</li>
</ul>
<p>여기서 원소가 4개 였고 비교에 3단계 옮기기에 2단계 삽입에 1단계, 총 6단계가 걸렸다. </p>
<p>그래서 <span style="color:red;"><strong>❗N개의 원소를 가진 정렬된 배열에서 삽입의 연산은 N+2단계</strong></span>가 걸린다고 볼 수 있다. </p>
<p><span style="background-color:yellow; color:black;"><strong>삽입의 위치가 어디든 단계 수는 비슷하다. 배열 앞 부분일수록 비교가 줄어들지만 이동이 늘어나고, 뒷 부분일수록 비교가 늘어나도 이동이 줄어들기 때문이다.</strong> </span></p>
<p><span style="background-color:yellow; color:black;"><strong>배열의 맨 끝에 놓이면 이동이 필요없으므로</strong></span> 제일 빠른 경우이다. 이 때는 <span style="background-color:yellow; color:black;"><strong>비교에 N단계와 삽입에 1단계, 총 N+1단계가 걸린다.</strong></span></p>
<p>가장 느릴 때 N+2단계, 가장 빠를 때 1단계가 걸리는 일반 배열의 삽입에 비해 정렬된 배열의 삽입이 느림을 알 수 있다. </p>
<h2 id="🔶-검색_선형검색----ⓝ단계--">🔶 검색_선형검색 : <code>[</code>  ⓝ단계  <code>]</code></h2>
<blockquote>
<p> &quot;선형검색&quot;으로 정렬된 배열을 검색연산 해보자. 
아래의 정렬된 배열에서 존재하지 않는 값 <code>22</code>를 검색해본다면?</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/c493f1ad-4942-480b-9d0b-6a9d5e17667a/image.png" alt=""></p>
<p>정렬된 배열에서는 <code>22</code><span style="background-color:yellow; color:black;">*<em>보다 큰 값이 나오면 바로 검색을 중단하고 해당 값이 없다고 판단할 수 있다. *</em></span></p>
<p>선형검색은 정렬된 배열에서 보통은 일반 배열보다 단계 수가 더 적게 걸린다.
하지만 <span style="background-color:yellow; color:black;"><strong>만약 찾으려는 값이 배열에서 제일 큰 값이라면 정렬된 배열과 일반 배열 모두 모든 셀을 검색해야 한다.</strong></span></p>
<p>그러므로 <span style="background-color:yellow; color:black;"><strong>선형검색으로 정렬된 배열을 검색 연산</strong></span> 한다면 일반배열과 똑같이 <span style="color:red;"><strong>❗N단계가 걸린다.</strong></span> </p>
<h3 id="span-stylebackground-colorblack-colororange❕코드-구현-❗span"><span style="background-color:black; color:orange;">❕코드 구현 ❗</span></h3>
<blockquote>
<ul>
<li><span style="color:blue;"><strong>메서드는 두 인수를 받는다.</strong></span></li>
</ul>
</blockquote>
<ul>
<li><span style="color:blue;"><strong>orderedArray : 검색할 정렬된 배열</strong></span></li>
<li><span style="color:blue;"><strong>searchValue :  찾으려는 값</strong></span><blockquote>
<ul>
<li><span style="color:blue;"><strong>배열의 모든 원소를 순회한다.</strong></span></li>
</ul>
</blockquote>
<ul>
<li><span style="color:blue;"><strong>원하는 값을 찾으면 그 인덱스를 반환한다.</strong></span><blockquote>
</blockquote>
</li>
<li><span style="color:blue;"><strong>찾고 있던 값보다 큰 원소에 도달하면 루프를 종료한다.</strong></span><blockquote>
</blockquote>
</li>
<li><span style="color:blue;"><strong>배열에서 값을 찾지 못하면 <code>null</code>을 반환한다.</strong></span></li>
</ul>
</li>
</ul>
<pre><code class="language-java">public static Integer linearSearch(int[] orderedArray, int searchValue) {
    for (int index = 0; index &lt; orderedArray.length; index++) {
        if (orderedArray[index] == searchValue)
            return index;

        else if (orderedArray[index] &gt; searchValue)
            break;
    }

    return null;
}</code></pre>
<ul>
<li><strong>JUNIT TEST</strong> 통과!</li>
</ul>
<pre><code class="language-java">import org.junit.Test;
import static org.junit.Assert.*;

@Test
public void linearSearchTest() {
    int[] array1 = {1, 3, 9, 10};

    Integer expectedNull = null;
    Integer expected0 = 0;
    Integer expected1 = 1;
    Integer expected2 = 2;
    Integer expected3 = 3;

    // 예상값 , 실제값
    assertEquals(expectedNull,linearSearch(array1,11));
    assertEquals(expectedNull,linearSearch(array1,2));
    assertEquals(expectedNull,linearSearch(array1,8));

    assertEquals(expected0,linearSearch(array1,1));
    assertEquals(expected1,linearSearch(array1,3));
    assertEquals(expected2,linearSearch(array1,9));
    assertEquals(expected3,linearSearch(array1,10));
}</code></pre>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/0b975a62-ce88-44c6-af26-e5113d74ec2f/image.png" alt=""></p>
<h2 id="🔶-검색_🌟이진검색🌟----ⓛⓞⓖⓝ단계--">🔶 검색_🌟이진검색🌟 : <code>[</code>  ⓛⓞⓖⓃ단계  <code>]</code></h2>
<blockquote>
<p>원소가 9개인 정렬된 배열이 있다. 이 배열에 어떤 값들이 있는지 전혀 모르는 상태에서 값 <code>7</code>을 찾아보자.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/f2854120-91ac-4b3d-9e14-85b81c15b606/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/31d90830-c9f5-4128-83b7-e0388073695b/image.png" alt=""></p>
<ul>
<li><span style="background-color:LightCyan; color:black;  ">1단계 :</span> <span style="background-color:yellow; color:black;"><strong>가운데 셀부터 검색을 시작한다</strong>.</span> 배열의 길이를 2로 나누어 가운데 셀의 인덱스를 계산한다. </li>
</ul>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/338a4e78-632f-41e4-a745-3f9241ab9bdc/image.png" alt=""></p>
<p><span style="background-color:yellow; color:black;"><strong>가운데 셀의 값은 <code>9</code>이므로 <code>7</code>은 왼쪽 어딘가에 있다.</strong></span> <code>9</code>와 <code>9</code>보다 오른쪽의 있는 셀 모두가 제거 되었으므로 이로써 <span style="background-color:yellow; color:black;"><strong>배열의 절반이 제거됐다.</strong></span></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/08efd5d6-dffe-4ad2-a882-dbc54ccc003b/image.png" alt=""></p>
<ul>
<li><span style="background-color:LightCyan; color:black;  ">2단계 :</span> <span style="background-color:yellow; color:black;"><strong><code>9</code>의 왼쪽 셀들 중 가운데 값을 확인한다. 가운데 값이 두 개이므로 임의로 왼쪽 값을 선택한다. 셀의 값이 <code>4</code>이므로 <code>7</code>은 오른쪽 어딘가에 있다. <code>4</code>와 <code>4</code>의 왼쪽 셀 모두가 제거 되었다.</strong></span> </li>
</ul>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/6b026b58-168b-46f5-8eed-986d9b03bdb9/image.png" alt=""></p>
<ul>
<li><span style="background-color:LightCyan; color:black;  ">3단계 :</span> <code>7</code>일 수 있는 두 개의 셀 중 임의로 왼쪽 셀을 선택한다. 값이 <code>6</code>이므로 <code>7</code>은 바로 오른쪽에 있다. 만약 거기도 없다면 이 배열에는 <code>7</code>은 없는 것이다. </li>
</ul>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/861be035-58aa-4927-a026-3e67512eb3fb/image.png" alt=""></p>
<ul>
<li><span style="background-color:LightCyan; color:black;  ">4단계 :</span> 4단계만에 검색이 완료됐다. </li>
</ul>
<p><span style="background-color:yellow; color:black;"><strong>이진 검색은 정렬된 배열에만 쓸 수 있다.</strong></span> 
이진 검색을 쓸 수 있다는 것이 정렬된 배열의 장점 중 하나이다. </p>
<p>검색 값이 배열의 원소 중 가장 큰 값이면 이진 검색에 최대 단계수가 걸린다.
배열의 크기가 3일 때 이진 검색에 필요한 최대 단계 수는 2다.
배열의 크기를 두 배로 늘리면 크기가 7이 되고, 이진 검색에 필요한 최대 단계 수는 3이 된다.
배열의 크기를 두 배로 늘리면 크기가 15가 되고 이진 검색에 필요한 최대 단계 수는 4가 된다.</p>
<p><span style="color:red;"><strong>❗이진 검색을 쓰면 추측할 때마다 검색해야 할 셀 중 절반을 제거할 수 있다. 그러므로 데이터를 두 배로 늘릴 때마다 이진 검색 알고리즘에서는 최대 한 단계만 더 추가된다. 이것을 logN단계가 걸린다고 한다.</strong></span> </p>
<h3 id="span-stylebackground-colorblack-colororange❕코드-구현-❗span-1"><span style="background-color:black; color:orange;">❕코드 구현 ❗</span></h3>
<blockquote>
<ul>
<li><span style="color:blue;"><strong>먼저 찾으려는 값이 있을 수 있는 상한선과 하한선을 정한다.</strong></span></li>
</ul>
</blockquote>
<ul>
<li><span style="color:blue;"><strong>최초의 상한선은 배열의 첫 번째 값, 하한선은 마지막 값이다.</strong></span><blockquote>
</blockquote>
</li>
<li><span style="color:blue;"><strong>상한선과 하한선 사이의 가운데 값을 계속해서 확인하는 루프를 시작한다.</strong></span><blockquote>
<ul>
<li><span style="color:blue;">*<em>루프를 상한선과 하한선이 같아질 때까지만 실행한다. *</em></span></li>
</ul>
</blockquote>
<ul>
<li>상한선과 하한선이 같아지면 검색값이 이 배열에 없다는 뜻이므로,<blockquote>
</blockquote>
⬇️ 루프안에서 <blockquote>
<ul>
<li><span style="color:blue;"><strong>상한선과 하한선 사이에 중간 지점을 찾는다.</strong></span></li>
</ul>
</blockquote>
</li>
<li><span style="color:blue;"><strong>결괏값이 정수가 아닐 때는 올림한다.</strong></span>
↳ <code>java의 ceil함수</code><blockquote>
</blockquote>
</li>
</ul>
</li>
<li><span style="color:blue;"><strong>중간 지점의 값을 확인한다.</strong></span><blockquote>
</blockquote>
</li>
<li><span style="color:blue;"><strong>중간 지점의 값이 찾고 있던 값이면 검색을 끝낸다.</strong></span><blockquote>
</blockquote>
</li>
<li><span style="color:blue;"><strong>아니라면 검색값이 중간지점값보다 작은지, 큰지 확인하여 상한선이나 하한선을 바꾼다.</strong></span><blockquote>
</blockquote>
</li>
<li><span style="color:blue;"><strong>루프를 빠져나오면 배열에 값이 없다는 뜻이므로 <code>null</code>을 반환한다.</strong></span></li>
</ul>
<pre><code class="language-java">public static Integer binarySearch(int[] orderedArray, int searchValue) {
    int lowerBound = 0;
    int upperBound = orderedArray.length - 1;

    while (lowerBound &lt;= upperBound) {
        int midpoint = (int) Math.ceil( ((double) upperBound + lowerBound) / 2 );

        if (searchValue == orderedArray[midpoint])
            return midpoint;
        else if (searchValue &lt; orderedArray[midpoint])
            upperBound = midpoint - 1;
        else if (searchValue &gt; orderedArray[midpoint])
            lowerBound = midpoint + 1;
    }

    return null;
}</code></pre>
<ul>
<li><strong>JUNIT TEST</strong> 통과!</li>
</ul>
<pre><code class="language-java">import org.junit.Test;
import static org.junit.Assert.*;

@Test
public void binarySearchTest() {
    int[] array = {3, 10, 37, 39, 44, 81, 659};

    Integer expectedNull = null;
    Integer expected0 = 0;
    Integer expected1 = 1;
    Integer expected2 = 2;
    Integer expected3 = 3;
    Integer expected4 = 4;
    Integer expected5 = 5;
    Integer expected6 = 6;

    //예상값, 실제값
    assertEquals(expectedNull, binarySearch(array, 788));
    assertEquals(expectedNull, binarySearch(array, 45));
    assertEquals(expectedNull, binarySearch(array, 2));
    assertEquals(expected0, binarySearch(array, 3));
    assertEquals(expected1, binarySearch(array, 10));
    assertEquals(expected2, binarySearch(array, 37));
    assertEquals(expected3, binarySearch(array, 39));
    assertEquals(expected4, binarySearch(array, 44));
    assertEquals(expected5, binarySearch(array, 81));
    assertEquals(expected6, binarySearch(array, 659));
}</code></pre>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/07a11bc6-a600-453b-8170-bc946c40acbd/image.png" alt=""></p>
<h1 id="🟪-선형검색-vs-이진검색">🟪 선형검색 <code>vs</code> 이진검색</h1>
<p>작은 크기의 배열이라면 이진 검색 알고리즘이 선형 검색 알고리즘보다 크게 나은 점은 없다. 하지만 배열이 더 커질 수록 이진 검색이 훨씬 선형 검색보다 빨라진다. </p>
<p>100개의 원소를 가진 배열에서 검색 연산에 필요한 최대 단계수 : </p>
<ul>
<li>선형 검색 : 100단계</li>
<li>이진 검색 : 7단계</li>
</ul>
<p>원소가 10,000개일 때 :</p>
<ul>
<li>선형 검색 : 10,000단계</li>
<li>이진 검색 : 13단계</li>
</ul>
<p>원소가 1,000,000개 일 때 :</p>
<ul>
<li>선형 검색 : 1,000,000단계</li>
<li>이진 검색 : 20단계</li>
</ul>
<p>선형 검색에서는 원소 수만큼의 단계가 필요하다. 배열의 원소 수를 두 배로 늘릴 때마다 단계 수도 두 배로 늘어난다. 반면 이진 검색에서는 한 단계만 늘어난다. </p>
<blockquote>
<p>⬇️ 선형 검색과 이진 검색의 이러한 성능 차이를 그래프로 표현하면 </p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/b1321bcb-ec5b-487a-9b24-19938ad115ce/image.jpg" alt=""></p>
<p>선형 검색에 해당하는 선을     보면 배열에 원소가 많아질수록 그에 비례해 검색에 걸리는 단계 수도 늘어난다. 기본적으로 배열에 원소 하나가 늘어날 때마다 선형 검색에는 4단계가 더 걸린다. 그래서 대각선 형태의 직선이 만들어진다.</p>
<p>이진 검색에 해당하는 선을 보면 데이터가 많아질수록 알고리즘의 단계 수는 아주 조금만 늘어난다. 이진 검색이 한 단계 늘어나려면 데이터 크기를 두 배로 늘려야 한다는 사실에 완벽히 부합한다. </p>
<h1 id="🟪-알고리즘이란">🟪 알고리즘이란</h1>
<p>알고리즘은 특정 과제를 달성하기 위해 컴퓨터에 제공되는 명령어 집합이다.
어떤 코드를 작성하든 컴퓨터가 따르고 실행할 알고리즘을 만드는 것이다.</p>
<ul>
<li>예시</li>
</ul>
<pre><code class="language-java">public static void printThings() {
    String[] things = {&quot;apples&quot;, &quot;chairs&quot;, &quot;files&quot;, &quot;notes&quot;};

    for (String thing : things)
        System.out.printf(&quot;Here&#39;s a thing : %s \n&quot;, thing);
}</code></pre>
<p><span style="background-color:yellow; color:black;"><strong>복잡하지 않을지라도 뭔가를 하는 코드는 모두 엄밀히 알고리즘, 즉 문제를 풀어나가는 절차다. 이 코드는 리스트의 모든 항목을 출력하고 싶다는 문제를 해결한다. 이 문제를 푸는 데 사용한 알고리즘은 print문이 포함된 for 루프다.</strong></span></p>
<h1 id="🟪-알고리즘이-중요한-이유">🟪 알고리즘이 중요한 이유</h1>
<p>선형 검색과 이진 검색의 성능 차이처럼, 같은 자료구조와 같은 연산을 하더라도 선택한 알고리즘에 의해서 속도 차이가 확연하게 날 수 있기 때문이다. </p>
<br>
<br>
<br>


<hr>
<br>
<br>

<h1 id="🟦-출처">🟦 출처</h1>
<h2 id="🔷-그림1">🔷 그림1</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/c38a1754-5997-4731-8383-fda18a2c3ad9/image.jpg" alt=""></p>
<p><a href="https://thebook.io/006950/ch15/01/04-01/">🖱 클릭! | &#39;더 북&#39;사이트의 &#39;컴퓨터 사이언스 부트캠프 with 파이썬&#39; 게시글의 &#39;그림 15-4 선형 탐색 알고리즘 vs. 이진 탐색 알고리즘&#39;표 보러가기</a></p>
<h2 id="🔷-글의-내용">🔷 글의 내용</h2>
<p>이 글 내용은 &#39;제인 웬그로우&#39;의 &#39;누구나 자료구조와 알고리즘 개정 2판&#39; 책을 100% 참고하여 작성하였습니다. 설명에 전문적인 용어보다는 일상적인 용어를 사용하고 그림으로 원리를 설명해주어 왕초보인 저가 이해하기에 아주 좋았습니다. 가격이 많이 나가는 편이지만 꼭 배워야 하는 내용이 모두 들어있고 그것을 제가 이해할 수 있는 수준으로 쓰여있어 전혀 아깝지 않은 소비였습니다. </p>
<p><img src="http://image.kyobobook.co.kr/images/book/xlarge/061/x9791160505061.jpg" alt="누구나 자료구조와 알고리즘 책 사진"></p>
<p><a href="http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&amp;ejkGb=KOR&amp;barcode=9791160505061">🖱 클릭! | &#39;제인 웬그로우&#39;의 &#39;누구나 자료구조와 알고리즘&#39; 책 구경하러 가보기</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[😶‍🌫️ [엉짧식] RUST를 알아보았다🦀 소유권!]]></title>
            <link>https://velog.io/@on-n-on-turtle/%EC%97%89%EC%A7%A7%EC%8B%9D-RUST%EB%A5%BC-%EC%95%8C%EC%95%84%EB%B3%B4%EC%95%98%EB%8B%A4</link>
            <guid>https://velog.io/@on-n-on-turtle/%EC%97%89%EC%A7%A7%EC%8B%9D-RUST%EB%A5%BC-%EC%95%8C%EC%95%84%EB%B3%B4%EC%95%98%EB%8B%A4</guid>
            <pubDate>Sun, 24 Jul 2022 13:57:21 GMT</pubDate>
            <description><![CDATA[<p>OKKY를 탐험하던 오늘, 구글이 c++을 대체할 언어인 <span style="color:blue;"><strong>CARBON</strong></span>을 발표했다는 소식을 보았어요.
댓글에 RUST보다 깔끔하게 보인다는 댓글에 CARBON보다 더 꽂혀버렸죠. 
그래서 시작된 <span style="color:blue;"><strong>RUST</strong></span> 폭풍 구글링 😊</p>
<p>rust document, rust의 간단한 예제와 토이프로젝트 예제와 심화 프로젝트 예제들, 그리고 니콜라스의 rust 설명 영상을 보게 되었어요. </p>
<p>이 글은 니콜라스의 rust언어 영상을 보고 간략하게 적어본 것입니다. </p>
<p>❗이 글은 엉성하고 짧은 지식 글입니다. 부디 <a href="https://youtu.be/w1dlmOjDLX8">출처를</a> 꼭 방문해주세요 😉</p>
<h1 id="🟪-c와-c의-대체-언어로-각광-받고-있다">🟪 C와 C++의 대체 언어로 각광 받고 있다.</h1>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/f0f76de3-307d-44af-b209-a6893782045e/image.png" alt=""></p>
<h6 id="span-stylecolorgrey-⬆️출처--영상의-028-스크린샷-span"><span style="color:grey;"><code>( ⬆️출처 : 영상의 0:28 스크린샷 )</code></span></h6>
<p>다른 언어와 비교하여 최고 수준으로 편리한 컴파일러와 소유권 개념 도입으로 보장되는 강력한 안전성과 빠른 속도 덕분에 C와 C++을 대체하는 언어로 각광 받고 있다.</p>
<p>예시로 아마존, 클라우드플레어, 마이크로소프트 같은 회사들이 C와 C++로 된 코드들을 Rust로 대체하고 있다.</p>
<h1 id="🟪-low-level-language--system-programming">🟪 low level language , System programming</h1>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/7030a57d-d1d6-485b-824c-79003b7cd455/image.png" alt=""></p>
<h6 id="span-stylecolorgrey-⬆️출처--영상의-243-스크린샷-span"><span style="color:grey;"><code>( ⬆️출처 : 영상의 2:43 스크린샷 )</code></span></h6>
<p><span style="color:blue;"><strong>RUST는 low level language로서 system programming에 가깝다.</strong></span> 
assembly language 바로 그 다음의 단계에 있는 저수준 언어이다. 
java 그리고 특히 js와 python와 비교하면 아주 저수준 언어인 것이다. </p>
<p>rust의 강점은 fast와 safe이다.</p>
<h1 id="🟪-fast">🟪 fast</h1>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/9c48656b-bbdf-4072-b8d5-a89ee3c5a1ec/image.png" alt=""></p>
<h6 id="span-stylecolorgrey-⬆️출처--영상의-553-스크린샷-span"><span style="color:grey;"><code>( ⬆️출처 : 영상의 5:53 스크린샷 )</code></span></h6>
<p>한 사례로 DISCORD회사는 빠른 속도로 인한 서비스 질 향상을 꾀하며 GO에서 RUST로 바꾸었다.</p>
<h2 id="🔶-중간단계가-없다">🔶 중간단계가 없다</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/fcbe2673-5e20-4a1d-aa9f-b86f111bcea4/image.png" alt=""></p>
<h6 id="span-stylecolorgrey-⬆️출처--영상의-351-스크린샷-span"><span style="color:grey;"><code>( ⬆️출처 : 영상의 3:51 스크린샷 )</code></span></h6>
<p>java는 class파일로 변환 후 컴퓨터가 기계어로 읽을 수 있게 된다. 
(더 많은 단계가 있겠지만 아주 간단하게 설명하자면 말이다.)
python언어는 C언어로 이해된 후에 컴퓨터가 기계어로 읽을 수 있게 되는 것이다. </p>
<p><span style="color:blue;"><strong>Rust는 java, python, js와 같이 컴퓨터가 기계어로 읽기 전에 거치게 되는 중간 단계가 없기 때문에 속도가 빠른 것이다.</strong></span></p>
<h2 id="🔶-garbage-collector가-없다">🔶 garbage collector가 없다</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/90e00e7a-bda6-4436-93a7-5a1f2534bb0b/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/226b886c-1b7c-458c-8a96-f8d7799d5b0f/image.png" alt=""></p>
<h6 id="span-stylecolorgrey-⬆️출처--영상의-513-스크린샷-span--span-stylecolorgrey-⬆️출처--영상의-518-스크린샷-span"><span style="color:grey;"><code>( ⬆️출처 : 영상의 5:13 스크린샷 )</code></span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color:grey;"><code>( ⬆️출처 : 영상의 5:18 스크린샷 )</code></span></h6>
<p>그리고 또한 garbage collector가 없기 때문에 빠르다. </p>
<p>c언어와 같은 저수준 언어는 변수를 만들 때 메모리 할당을 요청하고 더이상 쓰이지 않을 때는 메모리 공간 해제를 해야한다. </p>
<p>그러나 java, js, python같은 고수준 언어에서는 이렇게 할 필요가 없는 데 이는 garbage collector가 있기 때문이다. <span style="color:blue;"><strong>garbage collector는 쓰이지 않는 데이터가 메모리 공간에 있는지 늘 탐색하고 있다. 그리고 해당 공간을 발견하면 삭제한다.</strong></span> garbage collector가 이러한 일을 하기 때문에 개발자에게는 편리함을 주는 반면 프로그램의 성능은 느려지게 만드는 것이다. </p>
<p><span style="color:blue;"><strong>그래서 garbage collector가 없는 언어들이 있는 언어들보다 빠른 것이다.</strong></span></p>
<h1 id="🟪-safe">🟪 safe</h1>
<h2 id="❗span-stylebackground-coloryellowownershipspan-개념-덕분에-span-stylebackground-coloryellowmemory-access-bugspan로부터-안전하다">❗<span style="background-color:yellow"><code>Ownership</code></span> 개념 덕분에 <span style="background-color:yellow"><code>Memory Access Bug</code></span>로부터 안전하다!</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/5980eb6f-190f-42c8-a441-7d2206cac2cf/image.png" alt=""></p>
<h6 id="span-stylecolorgrey-⬆️출처--영상의-622-스크린샷-span"><span style="color:grey;"><code>( ⬆️출처 : 영상의 6:22 스크린샷 )</code></span></h6>
<p><span style="color:blue;"><strong>보안 문제의 70%가 메모리 엑세스와 관련이 있다</strong></span>. ➡️ 그렇게 때문에 Rust가 안전하다는 것이다. </p>
<p><span style="color:blue;"><strong>Memory Access Bug는 할당되지 않은 메모리 장소에 접근하거나, 이미 해제된 메모리 부분에 접근하려고 하거나, 또는 할당된 변수를 두 번 해제할려고 할 때 발생한다. 이는 곧 Runtime Error로 이어질 수 있다.</strong></span></p>
<p>이 문제 때문에 Rust가 인기가 많은 것이다. 
Rust는 C와 C++보다 느리더라도 거의 비슷한 퍼포먼스를 제공할 뿐만 아니라 더욱 안전하다.</p>
<p>그 이유는 Rust는 프로그램의 데이타에 대한 관념이 다르기 때문이다.
그것이 바로 소유권 <code>Ownership</code>이라는 개념이다.</p>
<p><span style="color:blue;">**
소유권 [ Ownership ]  이라는 개념에서는 프로그램의 데이터는 변수에 의해 소유된다. 그리고 데이터는 한번에 한 owner에게만 소유된다. Owner가 더이상 사용되지 않는다면, 데이터는 메모리에서 제거된다. 
**</span></p>
<blockquote>
<h2 id="span-stylebackground-coloryellowownershipspan"><span style="background-color:yellow"><code>Ownership</code></span></h2>
</blockquote>
<p><span style="background-color:yellow;">** <code>Owner  = 변수</code>
하나의 Owner( 변수 )에게 한번만 사용된다.
그리고 바로 메모리에서 제거된다. **</span></p>
<blockquote>
</blockquote>
<p>with the concept of ownership , the data of your program is owned by variables.
the data can only be owned by one owner at a time.
if the owner is not is scope or used anymore the data in dropped from memory.</p>
<h3 id="🌟-예시-코드-🌟">🌟 예시 코드 🌟</h3>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/63e2abaf-a73c-4765-b090-c9bdcda20a49/image.png" alt=""></p>
<h6 id="span-stylecolorgrey-⬆️출처--영상의-806-스크린샷-span"><span style="color:grey;"><code>( ⬆️출처 : 영상의 8:06 스크린샷 )</code></span></h6>
<p>main함수는 my_name 이라는 변수를 갖고 있다. 
그리고 main함수는 say_hi라는 함수를 부르는데 my_name 변수를 인수로 보낸다.</p>
<p>그리고 say_hi함수에서 인수로 받은 my_name 변수를 프린트한다.</p>
<p>모든 걸 완료한 후 main함수로 돌아와서 my_name변수를 한번더 프린트 한다.</p>
<p>❓❔ 결과는 어떻게 될까</p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/b6755308-1643-43bc-9836-a1888e7e00a4/image.png" alt=""></p>
<h6 id="span-stylecolorgrey-⬆️출처--영상의-837-스크린샷-span"><span style="color:grey;"><code>( ⬆️출처 : 영상의 8:37 스크린샷 )</code></span></h6>
<p>java, python 같은 언어를 하는 사람들은 
🧔🏻‍♀️ : &quot;만약 my_name변수에 <code>니꼬</code>라는 문자열 값이 할당되어 있다면
『hi 니꼬!
a is equals to 니꼬』 이렇게 출력이 되는 결과가 나타나겠지!!&quot;</p>
<p>Rust에선 어림도 없다구❗❕ </p>
<p>➡️ 실제 결과로는 이렇게 나온다 ❗</p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/50ba1d08-a9ff-4147-ac20-a2e68fb0b339/image.png" alt=""></p>
<p>🙀 : 앵?? 왜 두번째 print함수는 출력되지 않은거야??!!! </p>
<blockquote>
<p><span style="color:blue"><strong>my_name에 <code>니꼬</code>가 할당되었고, <code>data 니꼬</code>가 my_name 변수에서 say_hi함수로 이동함으로서 say_hi함수는 <code>data 니꼬</code>의 <code>owner</code>가 된다. 이 순간 부터 <code>main</code>함수의 <code>my_name</code>변수는 사용할 수 없게 된다.</strong> </span></p>
</blockquote>
<h1 id="🟪-어디에-쓰일-수-있을까">🟪 어디에 쓰일 수 있을까?</h1>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/de503496-79ab-4651-874f-09272e1c43d0/image.png" alt=""></p>
<h6 id="span-stylecolorgrey-⬆️출처--영상의-1028-스크린샷-span"><span style="color:grey;"><code>( ⬆️출처 : 영상의 10:28 스크린샷 )</code></span></h6>
<ul>
<li>블록체인 프로젝트의 스마트 컨트랙 구축</li>
<li>커맨드라인 인터페이스</li>
<li>백엔드</li>
<li>임베디드 소프트웨어</li>
<li>비디오 게임 엔진</li>
<li>웹 애플리케이션 
등등등</li>
</ul>
<h1 id="✍🏻-이-글의-모든-내용과-사진들의-출처">✍🏻 이 글의 모든 내용과 사진들의 출처</h1>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/2452a7bc-52e7-4441-8467-d2bfecbb2670/image.png" alt=""></p>
<h3 id="📻-노마드코더의-c가-주옥같은-개발자들-보세요-rust-10분-정리-영상-보러가기">📻 <a href="https://youtu.be/w1dlmOjDLX8"><code>노마드코더의 &lt;C가 주옥같은 개발자들 보세요. Rust 10분 정리!&gt; 영상 보러가기</code></a></h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 레벨1 콜라츠 추측 ]]></title>
            <link>https://velog.io/@on-n-on-turtle/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%97%B0%EC%8A%B5-%EF%BD%9C-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%A0%88%EB%B2%A81-%EC%BD%9C%EB%9D%BC%EC%B8%A0-%EC%B6%94%EC%B8%A1-1.-%EB%AC%B8%EC%A0%9C%EC%84%A4%EB%AA%85</link>
            <guid>https://velog.io/@on-n-on-turtle/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%97%B0%EC%8A%B5-%EF%BD%9C-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%A0%88%EB%B2%A81-%EC%BD%9C%EB%9D%BC%EC%B8%A0-%EC%B6%94%EC%B8%A1-1.-%EB%AC%B8%EC%A0%9C%EC%84%A4%EB%AA%85</guid>
            <pubDate>Thu, 02 Jun 2022 19:37:22 GMT</pubDate>
            <description><![CDATA[<h2 id="🔷-🖱️여기-클릭하면-문제로-이동해요">🔷 <a href="https://programmers.co.kr/learn/courses/30/lessons/12943">🖱️여기 클릭하면 문제로 이동해요!</a></h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/c3c95244-ee3a-4013-a48f-57637bb9715f/image.png" alt=""></p>
<p>이 글은 문제를 정리하고 저의 풀이를 보여드리는 거예요. 실제로 문제를 보고 풀어보세요. 클릭! 클릭! 해보세요! 🖱️</p>
<h2 id="🔷-문제">🔷 문제</h2>
<blockquote>
<p>1937년 Collatz란 사람에 의해 제기된 이 추측은, 주어진 수가 1이 될때까지 다음 작업을 반복하면, 모든 수를 1로 만들 수 있다는 추측입니다. 작업은 다음과 같습니다.</p>
<blockquote>
<p><span style="background-color:yellow; color:black;"><strong>1-1. 입력된 수가 짝수라면 2로 나눕니다. 
1-2. 입력된 수가 홀수라면 3을 곱하고 1을 더합니다.
2. 결과로 나온 수에 같은 작업을 1이 될 때까지 반복합니다.</strong></span></p>
</blockquote>
</blockquote>
<p>  <span style="background-color:yellow; color:black;"><strong>위 작업을 몇 번이나 반복해야하는지 반환하는 함수, solution을 완성해 주세요. 
  ❗단, 주어진 수가 1인 경우에는 0을, 작업을 500번 반복할 때까지 1이 되지 않는다면 –1을 반환해 주세요.
  ❗입력된 수, num은 1 이상 8,000,000 미만인 정수입니다.</strong></span></p>
<h3 id="✅-입출력-예시">✅ 입출력 예시</h3>
<p>  <img src="https://velog.velcdn.com/images/on-n-on-turtle/post/5c1e6ac4-815f-48aa-b598-d379af30fc7f/image.png" alt=""></p>
<ul>
<li>입력된 수가 <code>6</code>이라면 6 ➡️ 3 ➡️ 10 ➡️ 5 ➡️ 16 ➡️ 8 ➡️ 4 ➡️ 2 ➡️ 1 이 되어 총 8번 만에 1이 됩니다.</li>
<li><code>16</code> ➡️ 8 ➡️ 4 ➡️ 2 ➡️ 1 이되어 총 4번만에 1이 됩니다.</li>
<li><code>626331</code>은 500번을 시도해도 1이 되지 못하므로 -1을 리턴해야합니다.</li>
</ul>
<p>  <br><br><br></p>
<h2 id="🔷-내가-만든-로직">🔷 내가 만든 로직</h2>
<h3 id="✅-실패한-로직">✅ 실패한 로직</h3>
<ul>
<li><code>while</code>문으로 구현할 때<ul>
<li>1이 될 때 까지</li>
<li>짝수일 때는 <code>num /= 2</code> 한 후, <code>answer++</code></li>
<li>홀수일 때는 <code>num *= 3 + 1</code> 한 후, <code>answer++</code></li>
<li>위의 연산을 끝낸 후, <code>if num == 1</code>이면 <code>return answer</code> <br></li>
</ul>
</li>
<li><code>for</code>문으로 구현할 때<ul>
<li>500번 반복</li>
<li>짝수일 때는 <code>num /= 2</code> 한 후, <code>answer++</code></li>
<li>홀수일 때는 <code>num *= 3 + 1</code> 한 후, <code>answer++</code></li>
<li>위의 연산을 끝낸 후, <code>if num == 1</code>이면 <code>return answer</code></li>
</ul>
</li>
</ul>
<h3 id="✅-성공한-로직">✅ 성공한 로직</h3>
<ul>
<li><span style="background-color:yellow; color:black;"><strong>❗<code>num</code>의 자료형은 <code>long</code>으로! <code>int</code>는 ❌</strong></span><ul>
<li><span style="color:red;"><strong>모든 코드가 똑같은데도 불구하고 <code>num</code>의 자료형이 <code>int</code>이냐, <code>long</code>이냐에 따라 결과가 달라진다.</strong></span></li>
<li><span style="color:red;"><strong>그리고 <code>num</code>의 자료형이 <code>long</code>일 때의 결과만 통과한다.</strong></span>
➡️ <span style="color:red;"><strong>이유가 뭘까... 더 알아봐야겠다.</strong></span><br></li>
</ul>
</li>
<li><code>while</code>문으로 구현<ul>
<li>조건 : <code>num</code>이 1이 아닐 때</li>
<li><code>while(num != 1)</code></li>
</ul>
</li>
<li><code>while</code>문 시작하자 마자 바로 루프 카운팅 시작<ul>
<li><code>collatzCount++</code></li>
</ul>
</li>
<li><code>while</code>루프가 500번 반복되면 바로 -1 반환 <ul>
<li><code>if</code>문으로 구현</li>
<li>-1은 <code>itsNotCollazNum</code>변수명으로 의미부여</li>
<li><code>if(collazCount == 500) return itsNotCollazNum</code></li>
</ul>
</li>
<li>짝수일 때는 <code>num /= 2</code>  , 홀수일 때는 <code>num *= 3 + 1</code> 한 후, <code>num</code>에 대입<ul>
<li>삼항연산자 이용</li>
<li><code>num = (num%2==0) ? (num/2) : (num*3+1)</code></li>
</ul>
</li>
</ul>
<p><br><br><br></p>
<h2 id="🔷-실패한-나의-코드-1">🔷 실패한 나의 코드 1</h2>
<pre><code class="language-java">public class CollatzConjecture {
    public static int solution(int num) {
        int answer = 0;

        while (num &lt;= 1000) {
            if(num % 2 == 0) {
                num /= 2;
                answer++;
            }

            if (num == 1)
                return answer;

            if(num % 2 == 1) {
                num = (num * 3) + 1;
                answer++;
            }
        }

        answer = -1;
        return answer;
    }
}</code></pre>
<h3 id="⬇️-결과는🥲">⬇️ 결과는..🥲</h3>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/b4520a79-663c-457a-8110-2cc91c3f9dad/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/50312db2-242b-4ff2-80fc-9605a0600f54/image.png" alt=""></p>
<h2 id="🔷-실패한-이유">🔷 실패한 이유</h2>
<h3 id="✅-이상한-while문-조건">✅ 이상한 while문 조건</h3>
<h3 id="✅-ifnum--1문-위치">✅ <code>if(num == 1)</code>문 위치</h3>
<p>🥲 바꿔서 다시 해봤지만 다시 실패함. 결국 예상한 실패 이유가 틀렸다는 뜻!</p>
<h2 id="🔷-실패한-나의-코드-2">🔷 실패한 나의 코드 2</h2>
<pre><code class="language-java">public class CollatzConjecture {
    public static int solution(int num) {
        int collatzCount = 0;
        int itsNotCollatzNum = -1;

        while (collatzCount &lt;= 500) {
            if (num % 2 == 0) {
                num /= 2;
            } else  {
                num = (num * 3) + 1;
            }
            collatzCount++;

             if (num == 1) return collatzCount;
        }

        return itsNotCollatzNum;
    }
}</code></pre>
<h3 id="⬇️-바꾼-점">⬇️ 바꾼 점</h3>
<h3 id="✅-while문-조건">✅ <code>while()</code>문 조건</h3>
<p><code>while(num &lt;= 1000)</code> ➡️ <code>while(collatzCount &lt;= 500)</code></p>
<h3 id="✅-if문--3">✅ <code>if()</code>문 * 3</h3>
<p><code>if() if() if()</code> ➡️ <code>if() else if()</code></p>
<h3 id="✅-ifnum1문-위치">✅ <code>if(num==1)</code>문 위치</h3>
<p>짝수연산과 홀수 연산 사이 ➡️ 짝수 연산과 홀수 연산 뒤에 </p>
<h3 id="✅-answer문-위치">✅ <code>answer++</code>문 위치</h3>
<p>짝수 연산과 홀수 연산 각각에 ➡️ 짝수 연산과 홀수 연산에 모두 지우고, 짝수 연산과 홀수 연산이 끝나고 한번만 <code>answer++</code>할 수 있도록 했다.</p>
<h3 id="⬇️-결과는🥲-1">⬇️ 결과는..🥲</h3>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/e872c975-8817-4e93-adec-0022fc5fac1b/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/7c5fa31f-11b3-4f23-9e8b-c749e3118179/image.png" alt=""></p>
<p>아까보다 틀린 횟수는 확연하게 줄긴 했다..🥲</p>
<h2 id="🔷-엄청나게-어이없는-실패한-이유2">🔷 엄청나게 어이없는 실패한 이유2</h2>
<h3 id="✅-새로-추가된-규칙">✅ 새로 추가된 규칙</h3>
<p>  내가 처음 문제를 풀었을 때는 6월 3일!
  그러나 6월 10일에 
  <code>주어진 수가 1인 경우에는 0을 반환해 주세요.</code>라는 제한 규칙이 추가되었다.
  최근에 추가된 이 제한 규칙을 충족시키지 못했기 때문에 아무리 코드를 고쳐도 계속 똑같이 테스트5랑 테스트13번만 계속 틀리는 것이었다! </p>
<h3 id="✅-num의-자료형">✅ <code>num</code>의 자료형</h3>
<p>  <code>num</code>의 자료형이 <code>int</code>일 때와 <code>long</code>일 때 <code>return</code>값이 달라진다.</p>
<p>   <code>num</code>의 자료형이 <code>int</code>면 불합격, <code>long</code>면 통과된다.</p>
<h2 id="🔷-드디어-성공한-나의-코드">🔷 드디어 성공한 나의 코드</h2>
<pre><code class="language-java">class Solution {
    public int solution(long num) {
        int collatzCount = 0;
        int itsNotCollatzNum = -1;

        while (num != 1) {
            collatzCount++;

            if (collatzCount == 500)
                return itsNotCollatzNum;

            num = (num % 2 == 0) ? num / 2 : (num * 3) + 1;
        }

        return collatzCount;
    }
}</code></pre>
<h3 id="⬇️-바뀐점">⬇️ 바뀐점</h3>
<h3 id="✅-결국은-다른-사람의-풀이를-참고하여-통과했다">✅ 결국은 다른 사람의 풀이를 참고하여 통과했다..</h3>
<pre><code class="language-java">public static int sol(long num) {
    int answer = 0;

    while(num != 1){
        answer++;
        if(answer==500)
            return -1;
        if(num%2==0){
            num/=2;
        }else{
            num=num*3+1;
        }
    }
    return answer;
}</code></pre>
<h3 id="✅❗-span-stylecolorredint-num-➡️-long-numspan">✅❗ <span style="color:red;"><strong>int num ➡️ long num</strong></span></h3>
<h3 id="↳-이유--int-오버플로우"><a href="https://velog.io/@on-n-on-turtle/%EC%97%89%EC%A7%A7%EC%8B%9D-int-%EC%98%A4%EB%B2%84%ED%94%8C%EB%A1%9C%EC%9A%B0%EB%A5%BC-%EC%95%8C%EC%95%84%EB%B3%B4%EC%95%98%EB%8B%A4">↳ 이유 : INT 오버플로우</a></h3>
<p><code>num</code>의 자료형이 <code>int</code>일 때와 <code>long</code>일 때 <code>return</code>값이 달라진다.</p>
<ul>
<li><p><code>public int solution(long num)</code> 
➡️ <code>num=626331</code> 일때 <code>return -1</code>
➡️ 통과
<img src="https://velog.velcdn.com/images/on-n-on-turtle/post/7816e61e-b5f3-491a-91cd-b3593504e78f/image.png" alt="">
<img src="https://velog.velcdn.com/images/on-n-on-turtle/post/c1b5cd51-7bf9-4b6c-b711-b35cf1622110/image.png" alt=""></p>
</li>
<li><p><code>public int solution(int num)</code> 
➡️ <code>num=626331</code> 일때 <code>return 488</code>
➡️ 불합격
<img src="https://velog.velcdn.com/images/on-n-on-turtle/post/8cae1077-1d52-4816-8a36-5c59c1562394/image.png" alt="">
<img src="https://velog.velcdn.com/images/on-n-on-turtle/post/e532d9e7-e428-4b9d-967e-625e2922187e/image.png" alt=""></p>
</li>
</ul>
<h3 id="✅-while문-조건-1">✅ while문 조건</h3>
<h3 id="↳--whilecollazcount--500-➡️-whilenum--1">↳  while(collazCount &lt;= 500) ➡️ while(num != 1)</h3>
<p>문제의 조건은 <code>num</code>이 1일 떄는 0을 반환하고, <code>num</code>이 1이 될 때까지 콜라츠연산을 반복하는 것이므로 <code>num</code>이 1일 때는 루프를 타지 않아야 한다. 그러므로 <code>while</code>문의 조건이 <code>collazCount &lt;= 500</code>이어야 하는 것이 아니라 <code>num != 1</code>인 것이 맞다.</p>
<h3 id="✅-while문-안의-collatzcount-맨-위로-위치-변경">✅ while문 안의 collatzCount++ 맨 위로 위치 변경</h3>
<p><code>while</code>문이 시작하자마자 카운팅을 시작해야지 <code>collazCount</code>가 500일 때 바로 <code>-1</code>을 반환시킬 수 있기 때문이다.</p>
<h3 id="✅-while문-안의-if문-조건">✅ while문 안의 if문 조건</h3>
<h3 id="↳--ifnum-1-return-collazcount-➡️-if-collazcount--500-return-itsnotcollaznum">↳  if(num ==1) return collazCount ➡️ if (collazCount == 500) return itsNotCollazNum</h3>
<p><code>while</code>문의 조건과 <code>if</code>문의 조건을 반대로 해놔서 이때까지 틀린 것이었다.
<code>num</code>이 1이면 <code>while</code>문이 돌아가면 안되고
<code>collazCount</code>가 500이 되면 <code>while</code>문이 멈춰야 되는 것이었는데
이것을 정반대로 해서
<code>collazCount</code>가 500이 될 때까지 <code>num</code>이 1이어도 <code>while</code>문이 돌아가게 했고 그래서 <code>num</code>이 1일 때 0을 반환해야 하는데, 콜라츠 연산 횟수인 <code>collazCount</code>를 반환되어 버렸다.</p>
<h3 id="✅-return-값">✅ return 값</h3>
<h3 id="↳--return-itsnotcollaznum-➡️-return-collazcount">↳  return itsNotCollazNum ➡️ return collazCount</h3>
<p>이 문제는 콜라츠 연산의 횟수를 요구한 것이었는데
나는 <code>-1</code>을 반환했으니 당연히 틀리는 것이었다.</p>
<h3 id="⬇️-결과는😄">⬇️ 결과는..😄</h3>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/2bf09353-73a0-4c4e-8b17-94d3263fc452/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/fee779df-52ae-4877-b744-6cd3f8b2f39e/image.png" alt=""></p>
<h2 id="🔷-span-stylecolorredsolution함수의-매개변수num의-타입이-int면-불합격-long이면-합격인-이유span">🔷 <a href="https://velog.io/@on-n-on-turtle/%EC%97%89%EC%A7%A7%EC%8B%9D-int-%EC%98%A4%EB%B2%84%ED%94%8C%EB%A1%9C%EC%9A%B0%EB%A5%BC-%EC%95%8C%EC%95%84%EB%B3%B4%EC%95%98%EB%8B%A4"><span style="color:red;"><strong><code>solution</code>함수의 매개변수<code>num</code>의 타입이 <code>int</code>면 불합격, <code>long</code>이면 합격인 이유</strong></span></a></h2>
<p>⬆️ 클릭하면 그 이유에  대한 설명으로 이동됨</p>
<h2 id="🔷-그림출처">🔷 그림출처</h2>
<p>  <img src="https://velog.velcdn.com/images/on-n-on-turtle/post/ac3d53e7-bf17-4119-bb44-217d5bb2b73b/image.png" alt=""></p>
<p>  <a href="https://play.google.com/store/apps/details?id=appinventor.ai_garkhe.Collatz&amp;hl=sk&amp;gl=US"><code>구글플레이</code>사이트의 <code>김시현</code>님의 <code>콜라츠 추측 계산기</code>어플 보러가기 클릭! 🖱️</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 레벨1 평균 구하기 ]]></title>
            <link>https://velog.io/@on-n-on-turtle/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%97%B0%EC%8A%B5-%EF%BD%9C-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%A0%88%EB%B2%A81-%ED%8F%89%EA%B7%A0-%EA%B5%AC%ED%95%98%EA%B8%B0-1.-%EB%AC%B8%EC%A0%9C%EC%84%A4%EB%AA%85</link>
            <guid>https://velog.io/@on-n-on-turtle/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%97%B0%EC%8A%B5-%EF%BD%9C-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%A0%88%EB%B2%A81-%ED%8F%89%EA%B7%A0-%EA%B5%AC%ED%95%98%EA%B8%B0-1.-%EB%AC%B8%EC%A0%9C%EC%84%A4%EB%AA%85</guid>
            <pubDate>Wed, 01 Jun 2022 09:57:31 GMT</pubDate>
            <description><![CDATA[<h2 id="🔷-🖱️여기-클릭하면-문제로-이동해요">🔷 <a href="https://programmers.co.kr/learn/courses/30/lessons/12944">🖱️여기 클릭하면 문제로 이동해요!</a></h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/88bc00a5-e6a4-436f-80eb-3bf2835e723a/image.png" alt=""></p>
<p>이 글은 문제를 정리하고 저의 풀이를 보여드리는 거예요. 실제로 문제를 보고 풀어보세요. 클릭! 클릭! 해보세요! 🖱️</p>
<h2 id="🔷-문제">🔷 문제</h2>
<blockquote>
<p><span style="background-color:yellow"><strong>정수를 담고 있는 배열 arr의 평균값을 return하는 함수, solution을 완성해보세요.
  arr은 길이 1 이상, 100 이하인 배열입니다.
  arr의 원소는 -10,000 이상 10,000 이하인 정수입니다.</strong></span></p>
</blockquote>
<h3 id="✅-입출력-예시">✅ 입출력 예시</h3>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/32fbe901-7377-4744-a027-16067bb0a020/image.png" alt=""></p>
<h2 id="🔷-내가-만든-로직">🔷 내가 만든 로직</h2>
<h3 id="✅-solution">✅ solution()</h3>
<ul>
<li>❗<span style="background-color:yellow"><strong>결과는 <code>double</code>형이므로 합계 또한 자료형을 <code>double</code>로 해야 합계/갯수 했을 때 결과가 <code>double</code>로 나온다.</strong></span></li>
<li><code>for</code>문을 이용하여 <code>double</code>형 변수 <code>sum</code>에 인수 <code>int[]</code> 배열의 각각의 값들을 더한다.</li>
<li><code>sum</code>에 배열의 길이가 곧 갯수이므로 나눈다. </li>
</ul>
<h2 id="🔷-내가-만든-코드">🔷 내가 만든 코드</h2>
<pre><code class="language-java">class Solution {
    public double solution(int[] arr) {
        double sum = 0;
        for (int value : arr)
            sum += value;

        double answer = sum/arr.length;
        return answer;
    }
}</code></pre>
<h2 id="🔷-나의-코드-결과">🔷 나의 코드 결과</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/5b13e459-7c25-467d-b75b-fe7b6e077266/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/1b013721-9abc-446b-a590-fee88537f18f/image.png" alt=""></p>
<h2 id="🔷-그림출처">🔷 그림출처</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/99697e09-a1c2-441c-93cb-b8104515a510/image.png" alt=""></p>
<p><a href="https://kr.123rf.com/photo_76165125_%EC%8B%A0%EC%9A%A9-%EC%A0%90%EC%88%98-%EC%B8%A1%EC%A0%95%EA%B8%B0.html?vti=o6c0fltdm6xbq9qneb-1-86"><code>123RF</code>사이트의 <code>jameschipper</code>작가님의 <code>신용 점수 측정기</code>일러스트(<code>콘텐츠 ID: 76165125</code>) 보러가기 클릭! 🖱️</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 레벨1 하샤드 수 ]]></title>
            <link>https://velog.io/@on-n-on-turtle/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%97%B0%EC%8A%B5-%EF%BD%9C-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%A0%88%EB%B2%A81-%ED%95%98%EC%83%A4%EB%93%9C-%EC%88%98-1.-%EB%AC%B8%EC%A0%9C%EC%84%A4%EB%AA%85</link>
            <guid>https://velog.io/@on-n-on-turtle/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%97%B0%EC%8A%B5-%EF%BD%9C-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%A0%88%EB%B2%A81-%ED%95%98%EC%83%A4%EB%93%9C-%EC%88%98-1.-%EB%AC%B8%EC%A0%9C%EC%84%A4%EB%AA%85</guid>
            <pubDate>Tue, 31 May 2022 14:50:09 GMT</pubDate>
            <description><![CDATA[<h2 id="🔷-🖱️여기-클릭하면-문제로-이동해요">🔷 <a href="https://programmers.co.kr/learn/courses/30/lessons/12947">🖱️여기 클릭하면 문제로 이동해요!</a></h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/57c679b7-8da6-4fe3-914e-4dd662404695/image.png" alt=""></p>
<p>이 글은 문제를 정리하고 저의 풀이를 보여드리는 거예요. 실제로 문제를 보고 풀어보세요. 클릭! 클릭! 해보세요! 🖱️</p>
<h2 id="🔷-문제">🔷 문제</h2>
<blockquote>
<p><span style="background-color:yellow"><strong>양의 정수 x가 하샤드 수이려면 x의 자릿수의 합으로 x가 나누어져야 합니다. 
  예를 들어 18의 자릿수 합은 1+8=9이고, 18은 9로 나누어 떨어지므로 18은 하샤드 수입니다. 
  자연수 x를 입력받아 x가 하샤드 수인지 아닌지 검사하는 함수, solution을 완성해주세요.
  x는 1 이상, 10000 이하인 정수입니다.</strong></span></p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/a20587b9-c271-405a-a810-61f476c6312b/image.png" alt=""></p>
<h3 id="✅-입출력-예시">✅ 입출력 예시</h3>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/4cf485cc-1c03-456a-9cb6-9d8b6df6624a/image.png" alt=""></p>
<h2 id="🔷-내가-만든-로직">🔷 내가 만든 로직</h2>
<h3 id="✅-solution">✅ solution()</h3>
<ul>
<li>숫자를 자릿수별로 분리한다.<ul>
<li>숫자를 <code>String</code>으로 바꾼 다음 <code>.split(&quot;&quot;)</code>을 이용하여 각각 자릿수 별로 분리하여 &lt;문자열 배열&gt;에 넣는다.</li>
</ul>
</li>
<li><code>for문</code>을 이용하여 각 자릿수를 더한다. </li>
<li>숫자 / 더한 각 자릿수 의 결과가 나누어 떨어지면 <code>true</code>를 반환, 아니면 <code>false</code> 를 반환한다.<ul>
<li><code>if</code>문과 <code>% == 0</code>을 이용하여 나누어 떨어지는 지 판단한다.</li>
</ul>
</li>
</ul>
<h2 id="🔷-내가-만든-코드">🔷 내가 만든 코드</h2>
<pre><code class="language-java">class Solution {
    public boolean solution(int x) {
        boolean answer = false;

        String[] splittedNumbersArr = Integer.toString(x).split(&quot;&quot;);
        int sumSplittedNumbers = 0;
        for (String number : splittedNumbersArr)
            sumSplittedNumbers += Integer.parseInt(number);

        if (x%sumSplittedNumbers == 0)
            answer = true;

        return answer;
    }
}
</code></pre>
<h2 id="🔷-나의-코드-결과">🔷 나의 코드 결과</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/5cb59d69-abf9-4a0c-a228-fce46f7ad5e1/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/01b5a96f-4e61-4235-9d42-ca9c738f3e4c/image.png" alt=""></p>
<h2 id="🔷-그림출처">🔷 그림출처</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/3400c50b-96eb-4004-b05a-fa9cc2c9f774/image.png" alt=""></p>
<p><a href="https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&amp;blogId=comwel2009&amp;logNo=120143791233"><code>희망누리</code>님의 <code>근로복지공단 대표 공식블로그 희망누리</code>블로그의 <code>[신기한 인도 수학] 인도수학, 인도 수학공식, 수학의 나라 인도</code>게시글 보러가기 클릭! 🖱️ </a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 레벨1 핸드폰 번호 가리기 ]]></title>
            <link>https://velog.io/@on-n-on-turtle/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%97%B0%EC%8A%B5-%EF%BD%9C-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%A0%88%EB%B2%A81-%ED%95%B8%EB%93%9C%ED%8F%B0-%EB%B2%88%ED%98%B8-%EA%B0%80%EB%A6%AC%EA%B8%B0-1.-%EB%AC%B8%EC%A0%9C%EC%84%A4%EB%AA%85</link>
            <guid>https://velog.io/@on-n-on-turtle/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%97%B0%EC%8A%B5-%EF%BD%9C-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%A0%88%EB%B2%A81-%ED%95%B8%EB%93%9C%ED%8F%B0-%EB%B2%88%ED%98%B8-%EA%B0%80%EB%A6%AC%EA%B8%B0-1.-%EB%AC%B8%EC%A0%9C%EC%84%A4%EB%AA%85</guid>
            <pubDate>Tue, 31 May 2022 04:49:09 GMT</pubDate>
            <description><![CDATA[<h2 id="🔷-🖱️여기-클릭하면-문제로-이동해요">🔷 <a href="https://programmers.co.kr/learn/courses/30/lessons/12948">🖱️여기 클릭하면 문제로 이동해요!</a></h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/4a5feb87-22bf-4ca1-8748-f4c484725cde/image.png" alt=""></p>
<p>이 글은 문제를 정리하고 저의 풀이를 보여드리는 거예요. 실제로 문제를 보고 풀어보세요. 클릭! 클릭! 해보세요! 🖱️</p>
<h2 id="🔷-문제">🔷 문제</h2>
<blockquote>
<p><span style="background-color:yellow"><strong>프로그래머스 모바일은 개인정보 보호를 위해 고지서를 보낼 때 고객들의 전화번호의 일부를 가립니다.
전화번호가 문자열 phone_number로 주어졌을 때, 전화번호의 뒷 4자리를 제외한 나머지 숫자를 전부 *으로 가린 문자열을 리턴하는 함수, solution을 완성해주세요.
  phone_number는 길이 4 이상, 20이하인 문자열입니다.</strong></span></p>
</blockquote>
<h3 id="✅-입출력-예시">✅ 입출력 예시</h3>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/b024a04f-87c5-4512-af9a-9b6e81e0714b/image.png" alt=""></p>
<h2 id="🔷-내가-만든-로직">🔷 내가 만든 로직</h2>
<h3 id="✅-solution">✅ solution()</h3>
<ul>
<li>보여지는 마지막 4자리를 새로운 String 변수에 담는다.<ul>
<li><code>substring()</code> 메소드의 <code>index</code> : <code>phone_number_length</code> - 4</li>
</ul>
</li>
<li>가려지는 번호들의 숫자들을 <code>*</code>로 바꾼다<ul>
<li><code>StringBuilder</code>의 <code>append()</code>메소드를 이용하여 가려지는 번호의 갯수만큼 <code>*</code>을 <code>for</code>문으로 반복한다.</li>
</ul>
</li>
<li>가려진 번호와 보여지는 번호 두 개를 합친다.</li>
</ul>
<h2 id="🔷-내가-만든-코드">🔷 내가 만든 코드</h2>
<pre><code class="language-java">public static String solution(String phone_number) {
        int phone_number_length = phone_number.length();
        int numbers_shown_length = 4;
        int numbers_hidden_length = phone_number_length - numbers_shown_length;
        String numbers_shown = phone_number.substring(numbers_hidden_length);

        StringBuilder numbers_hidden = new StringBuilder();
        for (int i =0; i &lt; numbers_hidden_length; i++)
            numbers_hidden.append(&quot;*&quot;);

        String answer = numbers_hidden + numbers_shown;
        return answer;
    }</code></pre>
<h2 id="🔷-나의-코드-결과">🔷 나의 코드 결과</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/be54bc44-c378-4e9d-a2cd-2af466ccedbf/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/88a96a1e-acbb-43c1-93ec-8fff548ca502/image.png" alt=""></p>
<h2 id="🔷-그림출처">🔷 그림출처</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/6b29e51c-bc95-45e8-98a4-0e88b23fada3/image.png" alt=""></p>
<p><a href="http://www.10x10.co.kr/shopping/category_prd.asp?itemid=4210027"><code>텐바이텐</code>사이트의 <code>라이언과 춘식이는 통화중 주차번호판</code>상품 사진 보러 가기 클릭! 🖱️</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 레벨1 행렬의 덧셈 , 2차원 배열 복습]]></title>
            <link>https://velog.io/@on-n-on-turtle/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%97%B0%EC%8A%B5-%EF%BD%9C-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%A0%88%EB%B2%A81-%ED%96%89%EB%A0%AC%EC%9D%98-%EB%8D%A7%EC%85%88-1.-%EB%AC%B8%EC%A0%9C%EC%84%A4%EB%AA%85</link>
            <guid>https://velog.io/@on-n-on-turtle/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%97%B0%EC%8A%B5-%EF%BD%9C-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%A0%88%EB%B2%A81-%ED%96%89%EB%A0%AC%EC%9D%98-%EB%8D%A7%EC%85%88-1.-%EB%AC%B8%EC%A0%9C%EC%84%A4%EB%AA%85</guid>
            <pubDate>Sun, 29 May 2022 15:07:34 GMT</pubDate>
            <description><![CDATA[<h2 id="🔷-🖱️여기-클릭하면-문제로-이동해요">🔷 <a href="https://programmers.co.kr/learn/courses/30/lessons/12950">🖱️여기 클릭하면 문제로 이동해요!</a></h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/c26b18d1-51f7-4346-88da-2b0e6e21772f/image.png" alt=""></p>
<p>이 글은 문제를 정리하고 저의 풀이를 보여드리는 거예요. 실제로 문제를 보고 풀어보세요. 클릭! 클릭! 해보세요! 🖱️</p>
<h2 id="🔷-문제">🔷 문제</h2>
<blockquote>
<p><span style="background-color:yellow">** 행렬의 덧셈은 행과 열의 크기가 같은 두 행렬의 같은 행, 같은 열의 값을 서로 더한 결과가 됩니다. 
  2개의 행렬 arr1과 arr2를 입력받아, 행렬 덧셈의 결과를 반환하는 함수, solution을 완성해주세요.
  행렬 arr1, arr2의 행과 열의 길이는 500을 넘지 않습니다.**</span></p>
</blockquote>
<h3 id="✅-입출력-예시">✅ 입출력 예시</h3>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/9ef6bbba-1871-4676-a046-f7c68abcba00/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/75dcff66-7a9c-4c7d-b58e-d1ad7941c30d/image.png" alt=""></p>
<h2 id="🔷-2차원배열">🔷 2차원배열</h2>
<h3 id="✅-span-stylebackground-coloryellow2차원-배열은-2중-for문과-구조가-같다-span">✅ <span style="background-color:yellow">*<em>2차원 배열은 2중 for문과 구조가 같다. *</em></span></h3>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/23ad4c61-ebb4-43e7-89b4-3f9d57e47ea4/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/97614426-1210-4c30-9d8f-b82e60ea4626/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/c249b5ae-03f5-4d46-983e-089c5955f0a3/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/e21e9bfb-24bb-486d-a720-128f5da46c11/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/3a7e3260-fb41-4b7b-99de-0cf3089df80c/image.png" alt=""></p>
<h3 id="✅-2차원-배열-생성-방법">✅ 2차원 배열 생성 방법</h3>
<p><span style="background-color:yellow">** int[][] array4 = new int[5][7];**</span></p>
<h3 id="✅-2차원-배열에-값을-저장하는-방법">✅ 2차원 배열에 값을 저장하는 방법</h3>
<p><span style="background-color:yellow"><strong>array4[3][6] = 10;</strong></span></p>
<p>❗ <code>array4[1] = 10 ;</code>  ➡️ 🚫이렇게 사용하면 오류!!🚫
❗<span style="background-color:yellow"><strong>array4[1] 은 <span style="color:red">또 다른 1차원 배열을 가리킬 수 있는 참조형 변수</span>이기 때문에 값을 담을수는 없다.</strong></span></p>
<h3 id="✅-선언과-동시에-초기화하는-방법">✅ 선언과 동시에 초기화하는 방법</h3>
<p><span style="background-color:yellow"><strong>int[][] array6 = {{1}, {2,3}, {4,5,6}};</strong></span></p>
<h3 id="✅-❗🌟span-stylecolorblue가변크기의-2차원-배열을-생성하는-방법span">✅ ❗🌟<span style="color:blue">가변크기의 2차원 배열을 생성하는 방법</span></h3>
<p><span style="background-color:yellow"><strong>int[][] array5 = new int[3][];</strong></span>
<span style="color:blue">➡️ array5는 3개짜리 배열을 참조한다.</span>
<span style="color:blue">➡️ 3개짜리 배열은 아직 참조하는 배열이 없다</span>
<span style="background-color:yellow">** array5[0] = new int[1];<strong></span>
<span style="color:blue">➡️ 정수를 하나 담을 수 있는 배열을 생성</span>
<span style="color:blue">➡️ array5 의 0 번째 인덱스가 참조</span>
<span style="background-color:yellow"></strong>array5[1] = new int[2];<strong></span>
<span style="color:blue">➡️ 정수를 두 개 담을 수 있는 배열을 생성</span>
<span style="color:blue">➡️ array5 의 1 번째 인덱스가 참조</span>
<span style="background-color:yellow"></strong>array5[2] = new int[3];**</span>
<span style="color:blue">➡️ 정수를 세 개 담을 수 있는 배열을 생성</span>
<span style="color:blue">➡️ array5 의 2 번째 인덱스가 참조</span></p>
<h2 id="🔷-내가-만든-로직">🔷 내가 만든 로직</h2>
<h3 id="✅-solution">✅ solution()</h3>
<ul>
<li><span style="background-color:yellow"><strong>가변크기의 2차원 배열</strong></span>을 생성한다.</li>
<li>arr1과 arr2는 solution 메소드의 인자이고, answer은 solution 메소드의 return값이다.</li>
<li>arr1과 arr2와 answer, 이 세개의 이차원 배열은 같은 행열의 크기를 가졌으므로</li>
<li>answer의 행의 크기와 열의 크기를 정할 때 arr1을 이용한다.</li>
<li>answer의 행의 크기는 arr1의 열의 크기와 같고, answer의 각각의 행의 크기는 arr1의 각각의 행의 크기와 같은 점을 이용하여 </li>
<li>처음에는 answer을 가변크기의 2차원 배열로 선언하고 
( <code>new int[arr1.length][]</code> ) </li>
<li>for문을 이용하여 각 행의 크기를 정한다. 
( <code>new int[arr1.length][arr1[0~n].length]</code> ) </li>
</ul>
<h2 id="🔷-내가-만든-코드">🔷 내가 만든 코드</h2>
<pre><code class="language-java">public class Solution {
    public static int[][] solution(int[][] arr1, int[][] arr2) {
        int columnLength = arr1.length;
        int[][] answer = new int[columnLength][];

        for (int column = 0; column &lt; columnLength; column++) {
            int rowLength = arr1[column].length;
            answer[column] = new int[rowLength];

            for(int row = 0; row &lt; rowLength; row++) {
                answer[column][row] = arr1[column][row] + arr2[column][row];
            }
        }

        return answer;
    }
}</code></pre>
<h3 id="✅-🚫주의">✅ 🚫주의</h3>
<ul>
<li><span style="background-color:yellow"><strong>두번째 for문 안에 <code>answer[column] = new int[rowLength];</code>을 선언하면 row가 바뀔 때 마다 행이 초기화 되기 때문에 꼭! 첫번째 for문 안에서 미리 선언하고 난  후에 두번째 for문에서 각 row에 값을 넣어줘야 한다.</strong></span></li>
</ul>
<h2 id="🔷-나의-코드-결과">🔷 나의 코드 결과</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/c4972350-da71-4597-81a9-157696723f9d/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/95ff9ec1-ed0c-416b-b68f-1630cf7b065a/image.png" alt=""></p>
<h2 id="🔷-2차원-배열-내용-출처">🔷 2차원 배열 내용 출처</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/b2c20980-2e06-4eeb-b179-f1aa2a4710c3/image.png" alt=""></p>
<p><a href="https://programmers.co.kr/learn/courses/5/lessons/135"><code>프로그래머스</code>사이트의 <code>자바입문-2차원배열</code>글 보러가기 클릭! 🖱️</a></p>
<h2 id="🔷-그림출처">🔷 그림출처</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/04a2f9cc-8275-43e2-8261-c49899a2e00c/image.png" alt=""></p>
<p><a href="https://www.insight.co.kr/newsRead.php?ArtNo=49522"><code>인사이트</code>사이트의 <code>애니팡</code>사진 보러가기 클릭! 🖱️</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 레벨1 x만큼 간격이 있는 n개의 숫자 ]]></title>
            <link>https://velog.io/@on-n-on-turtle/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%97%B0%EC%8A%B5-%EF%BD%9C-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%A0%88%EB%B2%A81-x%EB%A7%8C%ED%81%BC-%EA%B0%84%EA%B2%A9%EC%9D%B4-%EC%9E%88%EB%8A%94-n%EA%B0%9C%EC%9D%98-%EC%88%AB%EC%9E%90-1.-%EB%AC%B8%EC%A0%9C%EC%84%A4%EB%AA%85</link>
            <guid>https://velog.io/@on-n-on-turtle/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%97%B0%EC%8A%B5-%EF%BD%9C-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%A0%88%EB%B2%A81-x%EB%A7%8C%ED%81%BC-%EA%B0%84%EA%B2%A9%EC%9D%B4-%EC%9E%88%EB%8A%94-n%EA%B0%9C%EC%9D%98-%EC%88%AB%EC%9E%90-1.-%EB%AC%B8%EC%A0%9C%EC%84%A4%EB%AA%85</guid>
            <pubDate>Sun, 29 May 2022 08:04:30 GMT</pubDate>
            <description><![CDATA[<h2 id="🔷-🖱️여기-클릭하면-문제로-이동해요">🔷 <a href="https://programmers.co.kr/learn/courses/30/lessons/12954">🖱️여기 클릭하면 문제로 이동해요!</a></h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/f1475ef9-f87c-431f-b42b-0be630e60c36/image.png" alt=""></p>
<p>이 글은 문제를 정리하고 저의 풀이를 보여드리는 거예요. 실제로 문제를 보고 풀어보세요. 클릭! 클릭! 해보세요! 🖱️</p>
<h2 id="🔷-문제">🔷 문제</h2>
<blockquote>
<p><span style="background-color:yellow">** 함수 solution은 정수 x와 자연수 n을 입력 받아, x부터 시작해 x씩 증가하는 숫자를 n개 지니는 리스트를 리턴해야 합니다. 
  x는 -10000000 이상, 10000000 이하인 정수입니다.
  n은 1000 이하인 자연수입니다.**</span></p>
</blockquote>
<h3 id="✅-입출력-예시">✅ 입출력 예시</h3>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/ab445f9c-ad21-4a4d-a1b1-4ce1ffb2441e/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/660e437a-7a3a-462d-b2cc-04420029824f/image.png" alt=""></p>
<h2 id="🔷-내가-만든-로직">🔷 내가 만든 로직</h2>
<h3 id="✅-solution">✅ solution()</h3>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/db94b00c-6a87-40db-8041-a470c7e8ae23/image.png" alt=""></p>
<h2 id="🔷-내가-만든-코드">🔷 내가 만든 코드</h2>
<pre><code class="language-java">class Solution {
    public long[] solution(int x, int n) {
        long[] answer = new long[n];

        for(int answerIndex = 0; answerIndex &lt; n; answerIndex++) {
            int multiplyNumber = answerIndex + 1;
            answer[answerIndex] = x * multiplyNumber;
        }

        return answer;
    }
}</code></pre>
<h2 id="🔷-나의-코드-결과">🔷 나의 코드 결과</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/7b0c935c-bf7f-47d6-a018-7054a386ebd7/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/191638d6-a9a6-46cb-bece-9a02034cb646/image.png" alt=""></p>
<h2 id="🔷-틀린이유">🔷 틀린이유</h2>
<p><span style="background-color:yellow">** 
❗자료형 때문!!
**</span></p>
<p>return될 <code>answer[]</code>은 <code>long</code>자료형만 들어갈 수 있다.
인수 <code>x</code>를 <code>int</code>로 한다면 제한되는 범위 끝에 다다를 때 <code>answer[]</code>에 들어가야 하는 수를 <code>int</code>자료형은 담을 수 없게 될 것이다. 그래서 <code>long</code>자료형으로 처음부터 x를 받아야한다.</p>
<span style="color:grey;">
(이유를 도저히 모르겠어서 해매다가 `다른사람의 풀이`를 보고서야 알게되었다...🐶)
</span>



<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/1dc15039-0f4c-4eef-9250-f2c0d2d92be5/image.png" alt=""></p>
<h2 id="🔷-다시-도전하는-코드">🔷 다시 도전하는 코드</h2>
<pre><code class="language-java">class Solution {
    public long[] solution(long x, int n) {  ⬅️⬅️❗❗❗
        long[] answer = new long[n];

        for(int answerIndex = 0; answerIndex &lt; n; answerIndex++) {
            int multiplyNumber = answerIndex + 1;
            answer[answerIndex] = x * multiplyNumber;
        }

        return answer;
    }
}</code></pre>
<h2 id="🔷-다시-도전한-결과">🔷 다시 도전한 결과</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/853c3e90-b76e-4f83-b0b3-ab8d2cd8fc7c/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/1baeeb55-9186-4aa5-86c1-0c976fe90ace/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준]레벨1 직사각형 별찍기]]></title>
            <link>https://velog.io/@on-n-on-turtle/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%97%B0%EC%8A%B5-%EF%BD%9C-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%A0%88%EB%B2%A81-%EC%A7%81%EC%82%AC%EA%B0%81%ED%98%95-%EB%B3%84%EC%B0%8D%EA%B8%B0-1.-%EB%AC%B8%EC%A0%9C%EC%84%A4%EB%AA%85</link>
            <guid>https://velog.io/@on-n-on-turtle/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%97%B0%EC%8A%B5-%EF%BD%9C-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%A0%88%EB%B2%A81-%EC%A7%81%EC%82%AC%EA%B0%81%ED%98%95-%EB%B3%84%EC%B0%8D%EA%B8%B0-1.-%EB%AC%B8%EC%A0%9C%EC%84%A4%EB%AA%85</guid>
            <pubDate>Sat, 28 May 2022 10:25:42 GMT</pubDate>
            <description><![CDATA[<h2 id="🔷-🖱️여기-클릭하면-문제로-이동해요">🔷 <a href="https://programmers.co.kr/learn/courses/30/lessons/12969">🖱️여기 클릭하면 문제로 이동해요!</a></h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/84c2c8ba-76c1-4553-904a-7ef1fa8a6522/image.png" alt=""></p>
<p>이 글은 문제를 정리하고 저의 풀이를 보여드리는 거예요. 실제로 문제를 보고 풀어보세요. 클릭! 클릭! 해보세요! 🖱️</p>
<h2 id="🔷-문제">🔷 문제</h2>
<blockquote>
<p><span style="background-color:yellow">** 이 문제에는 표준 입력으로 두 개의 정수 n과 m이 주어집니다.
별( * ) 문자를 이용해 가로의 길이가 n, 세로의 길이가 m인 직사각형 형태를 출력해보세요.
  n과 m은 각각 1000 이하인 자연수입니다.**</span></p>
</blockquote>
<p>숫자 두 개가 입력되면, 첫 번째 숫자는 가로의 길이이고, 두 번재 숫자는 세로의 길이가 됩니다. 여기에 맞게 별<code>*</code>을 출력하면 됩니다.</p>
<h3 id="✅-입력되는-데이터의-제한-조건">✅ 입력되는 데이터의 제한 조건</h3>
<p>각각 1000 이하인 자연수 2개만 입력됩니다.</p>
<h3 id="✅-입출력예시">✅ 입출력예시</h3>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/48d66cc0-f8ef-4254-b2fd-d306aa511668/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/d64d22a1-746d-473c-9e63-774109b608ac/image.png" alt=""></p>
<h2 id="🔷-내가-만든-로직">🔷 내가 만든 로직</h2>
<h3 id="✅-printresult">✅ printResult()</h3>
<ul>
<li>인수로 정수 2개를 받는다.</li>
<li>for문을 2번 돌린다.</li>
<li>첫번째 for문은 열<code>column,세로</code>을 표현하므로 두번째 인수만큼 반복하여 &lt; <code>*</code> &gt;을 출력한다.</li>
<li>두번째 for문은 행<code>row,가로</code>을 표현하므로 첫번째 인수만큼 반복하여 <code>System.out.println()</code>을 출력하여 다음 행으로 넘긴다. 이때 <code>System.print.out(&quot;\n&quot;
)</code>을 출력하면 다음 행으로 넘어간다음 또 다음 행으로 넘어가므로 이건 안된다. </li>
</ul>
<h2 id="🔷-내가-만든-코드">🔷 내가 만든 코드</h2>
<pre><code class="language-java">import java.util.Scanner;

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

        int first_number = scanner.nextInt();
        int second_number = scanner.nextInt();

        printResult(first_number, second_number);
    }

    public static void printResult(int first_number, int second_number) {
        for (int column = 0; column &lt; second_number; column++) {
            for (int row = 0; row &lt; first_number; row++) {
                System.out.print(&#39;*&#39;);
            }
            System.out.println();
        }
    }    

}</code></pre>
<h2 id="🔷-나의-코드-결과">🔷 나의 코드 결과</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/54b277ae-e2db-4f20-bbf4-11c51687cab1/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/9e0cd1dc-1d57-4b20-a60d-969508cd236c/image.png" alt=""></p>
<h2 id="🔷-그림-출처">🔷 그림 출처</h2>
<p><img src="https://velog.velcdn.com/images/on-n-on-turtle/post/5063d59e-2a69-4621-a462-b5a4446a8490/image.png" alt=""></p>
<p><a href="https://icons8.kr/illustrations/illustration/bonbon-star">🖱️ &#39;icons.kr&#39;사이트의 무료일러스트, &lt; &#39;Bonbon&#39;작가의 별 일러스트 &gt; 다운 받기 클릭 </a></p>
]]></description>
        </item>
    </channel>
</rss>