<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title>zlfn.space</title>
      <link>https://zlfn.space</link>
      <description>zlfn&#x27;s digital space</description>
      <generator>Zola</generator>
      <language>ko</language>
      <atom:link href="https://zlfn.space/rss.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Fri, 10 Apr 2026 00:00:00 +0000</lastBuildDate>
      <item>
          <title>컴퓨터 아키텍처와 RISC-V</title>
          <pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://zlfn.space/blog/computer-architecture-riscv/</link>
          <guid>https://zlfn.space/blog/computer-architecture-riscv/</guid>
          <description xml:base="https://zlfn.space/blog/computer-architecture-riscv/">&lt;p&gt;컴퓨터 아키텍처와 RISC-V CPU의 구조에 대해 알아보겠습니다.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;본 글의 내용은 포항공과대학교의 CSED311의 내용을 기반으로&lt;br &#x2F;&gt;
수업에서 다루지 않은 몇몇 내용을 추가하여 구성하였습니다.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h1 id=&quot;akitegceoran&quot;&gt;아키텍처란?&lt;&#x2F;h1&gt;
&lt;p&gt;컴퓨터 아키텍처는 하드웨어와 소프트웨어 사이의 인터페이스 규약입니다.
구체적으로는 CPU가 이해하는 명령어 집합(ISA, Instruction Set Architecture)을
중심으로, 아래 내용들을 정의합니다.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;명령어(인스트럭션): 어떤 연산(덧셈,분기,메모리 접근 등)을 지원하고 어떤 형식으로
표현하는가&lt;&#x2F;li&gt;
&lt;li&gt;레지스터: 레지스터가 몇 개이고, 각각 몇 비트인가, 각각의 용도는 무엇인가&lt;&#x2F;li&gt;
&lt;li&gt;메모리 모델: 주소 공간 크기, 바이트 순서(엔디언)&lt;&#x2F;li&gt;
&lt;li&gt;예외&#x2F;인터럽트 처리: 오류나 외부 이벤트를 어떻게 다루는가&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;아키텍처&lt;&#x2F;strong&gt;는 실제 하드웨어적 구현과 무관하게 동일하게 유지되는 &lt;strong&gt;추상 계층&lt;&#x2F;strong&gt;
입니다. 컴파일러가 이 규약만 보고 해당 아키텍처에 맞는 코드를 생성하면, 해당
아키텍처를 구현한 어떤 칩에서든 동작합니다. 따라서 제조사가 다르더라도
아키텍처가 같으면 유저는 동일한 OS와 응용 프로그램을 실행할 수 있습니다. (AMD와
Intel의 x86-64 CPU를 생각할 수 있습니다)&lt;&#x2F;p&gt;
&lt;p&gt;반면 &lt;strong&gt;마이크로 아키텍처&lt;&#x2F;strong&gt;는 아키텍처라는 &quot;약속&quot;을 실제 하드웨어로 구현하는 내부
설계입니다. 파이프라인, 비순차 실행, 분기 예측 등 최적화나 세부적인 구현이
마이크로 아키텍처에 해당합니다.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;akitegceoyi-yuhyeong&quot;&gt;아키텍처의 유형&lt;&#x2F;h2&gt;
&lt;p&gt;컴퓨터 아키텍처의 주요 유형에는 폰 노이만 아키텍처, 하버드 아키텍처,
데이터플로우 아키텍처 등이 있습니다.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pon-noiman-akitegceo&quot;&gt;폰 노이만 아키텍처&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;폰 노이만 아키텍처&lt;&#x2F;strong&gt;는 존 폰 노이만이 제안한 컴퓨터의 기본 구조로, 오늘날 거의
모든 범용 컴퓨터의 토대가 됩니다. 폰 노이만 아키텍처 이전의 컴퓨터(ENIAC 등)는
프로그램을 바꾸려면 물리적으로 배선을 변경해야 했습니다.&lt;&#x2F;p&gt;
&lt;p&gt;당시 ENIAC을 개발한 모클리와 에커트는 후속 컴퓨터 EDVAC을 설계하면서 프로그램과
데이터를 같은 메모리에 저장하는 방법을 구상합니다. 이렇게 하면 프로그램을 메모리에
올리기만 하면 하나의 배선으로 서로 다른 작업을 수행할 수 있다는 장점이 있습니다.
(이후 폰 노이만이 이 아이디어를 정리한 보고서를 단독 저자로 배포하게 되면서,
이러한 구조의 이름이 폰 노이만 아키텍처가 되었습니다.)&lt;&#x2F;p&gt;
&lt;p&gt;폰 노이만 아키텍처는 CPU가 메모리에서 명령어를 가져오고, 해석하고, 실행하는
과정을 반복하여 프로그램을 실행합니다. 이때 명령어와 데이터가 같은 메모리, 같은
데이터 버스를 공유하기 때문에, CPU가 아무리 빠르더라도 메모리 대역폭에 의해
성능이 제한되는 폰 노이만 병목(Von Neumann Bottleneck)이 일어납니다. 이러한
이유로, 현대 CPU는 폰 노이만 아키텍처를 기반으로 하지만, 전통적인 폰 노이만
아키텍처의 구조를 그대로 사용하지 않고, 아래 하버드 아키텍처의 구조와 적절히
결합하여 사용합니다.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;habeodeu-akitegceo&quot;&gt;하버드 아키텍처&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;하버드 아키텍처&lt;&#x2F;strong&gt;는 폰 노이만 아키텍처와 비슷한 시기 하버드 대학의 Mark I 컴퓨터에서 유래한
아키텍처입니다. Mark I은 명령어를 펀치 테이프에서, 데이터를 기계식 카운터에서
따로 읽었기 때문에, 폰 노이만 아키텍처와 달리 명령어 메모리와 데이터 메모리를
물리적으로 완전히 분리한 구조를 가집니다.&lt;&#x2F;p&gt;
&lt;p&gt;하버드 아키텍처는 명령어와 데이터의 버스를 구분하여 명령어와
데이터를 동시에 읽을 수 있기 때문에, 처리량이 높다는 장점이 있습니다.
하지만 두 메모리간의 용량을 유연하게 나눌 수 없고, 프로그램을 명령어 메모리로 옮기는
별도 메커니즘이 필요합니다. 현대에는 마이크로컨트롤러(아두이노에 들어가는 AVR 등)나
DSP(디지털 신호 처리기) 같은 일부 분야에서 하버드 아키텍처가 이용됩니다.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sujeongdoen-habeodeu-akitegceo&quot;&gt;수정된 하버드 아키텍처&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;수정된 하버드 아키텍처&lt;&#x2F;strong&gt;는 현대 CPU 대부분이 채택한 폰 노이만 아키텍처와
하버드 아키텍처 사이의 절충안입니다. L1 캐시 레벨에서 I-cache와 D-cache를 분리해
하버드 아키텍처의 높은 대역폭이라는 이점을 취하고, 그 이하의 메모리는 통합하여
폰 노이만 아키텍처의 유연성을 유지합니다. CPU 입장에서는 L1 캐시의 메모리가
명령어와 데이터로 분리되어 있으므로 하버드 아키텍처처럼 동작하지만, 캐시를 직접
다루지 않는 컴파일러와 프로그래머의 입장에서는 하나의 주소공간으로 컴퓨터를 다룰 수
있습니다.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;deiteopeulrou-akitegceo&quot;&gt;데이터플로우 아키텍처&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;데이터플로우 아키텍처&lt;&#x2F;strong&gt;는 위 하버드 아키텍처나 폰 노이만 아키텍처와 근본적으로
다른 아키텍처 패러다임입니다. 폰 노이만 방식은 프로그램 카운터가 &quot;다음에 실행할
명령어&quot;를 순차적으로 지정합니다. 데이터플로우 아키텍처는 이러한
폰 노이만 방식의 순차적인 연산 시행이라는 한계를 탈피하기 위해 설계된
아키텍처로, 프로그램 카운터가 없습니다.
데이터플로우 아키텍처에서는 프로그램 카운터가 순차적으로 어떤 명령어를 수행할지
지정하지 않아도 필요한 데이터가 전부 준비되면 명령어가 즉시 실행됩니다. 프로그램의 실행
순서를 프로그래머나 하드웨어가 정하는 것이 아니라, 데이터 자체가 실행
흐름을 결정하는 것입니다.&lt;&#x2F;p&gt;
&lt;p&gt;데이터플로우 아키텍처에서 프로그램은 순차적인 명령어 목록이 아니라, 방향
그래프로 표현됩니다. &lt;code&gt;(a + b) * (c - d)&lt;&#x2F;code&gt;와 같은 연산을 시행할 때, 덧셈 노드와
뺄셈 노드는 서로 의존성이 없으므로 동시에 실행됩니다. 두 연산의 결과가 모두 곱셈
노드에 도착하면 곱셈 연산이 발화(fire)합니다. 명시적으로 프로그래머가 병렬
연산을 지정하지 않아도, 자동으로 모든 연산이 병렬적으로 시행되는 것입니다.&lt;&#x2F;p&gt;
&lt;p&gt;1970년대 처음 등장한 데이터플로우 아키텍처는 1980-1990년대 차세대 컴퓨터로
활발하게 연구되었으나, 다양한 한계로 인해 상용화에는 실패합니다. 데이터플로우
아키텍처에 필요한 연산들이 하드웨어적으로 매우 비싸기도 했고, 대규모 데이터
구조를 다룸에 있어서의 어려움, 기존의 모든 소프트웨어 인프라가 순차 실행 모델을
전제로 작성되어 있다는 복합적인 문제 때문이었습니다.&lt;&#x2F;p&gt;
&lt;p&gt;순수한 데이터플로우 컴퓨터는 현재 사라졌지만, 아이디어는 현대까지 남아
이어지고 있습니다. 폰 노이만 모델 안에서의 비순차 실행(OoO) 구조, FPGA에서의
회로 설계 등에서 데이터플로우 아키텍처의 설계 사상이 이어지고 있고, 최근에는 AI
가속 프로세서 들이 데이터플로우 원리를 하드웨어에 다시 적용하고 있어, 비록 범용
컴퓨팅 머신으로 상용화되지는 않았지만, 다양한 특수 목적 하드웨어에서
데이터플로우 아키텍처를 이용하려는 연구가 지속되고 있습니다.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;isa&quot;&gt;ISA&lt;&#x2F;h2&gt;
&lt;p&gt;ISA는 &lt;strong&gt;Instruction Set Architecture&lt;&#x2F;strong&gt;의 약자로, 소프트웨어와 하드웨어 사이의
인터페이스라고 할 수 있습니다. ISA는 아래와 같은 사항들을 결정합니다.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;명령어 세트에 어떤 연산이 존재하는지, 각 명령어의 인코딩 형식은 어떤지&lt;&#x2F;li&gt;
&lt;li&gt;하드웨어가 직접적으로 지원하는 데이터 타입에는 어떤 것들이 있는지, 바이트
순서는 어떤지 (리틀 엔디언, 빅 엔디언)&lt;&#x2F;li&gt;
&lt;li&gt;레지스터 구성과 레지스터의 개수, 비트폭과 용도&lt;&#x2F;li&gt;
&lt;li&gt;주소 지정 방식 (Addressing Mode)와 명령어가 피연산자의 위치를 어떻게
지정하는지&lt;&#x2F;li&gt;
&lt;li&gt;메모리 모델의 주소 공간 크기&lt;&#x2F;li&gt;
&lt;li&gt;어떤 상황(0으로 나누기, 페이지 폴트, 잘못된 명령어)에서 예외가 발생하는지,
인터럽트는 어떻게 처리되는지&lt;&#x2F;li&gt;
&lt;li&gt;권한 수준과 보호 모드&#x2F;커널 모드의 구분, 각 모드에서 접근 가능한 레지스터와
명령어의 범위, 가상 메모리 관련 부분&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;반면, ISA 아래에 위치하는 마이크로아키텍처와 관련된 부분(클럭 속도, 파이프라인
단계, 캐시 구조 등)과 소프트웨어 계층의 규약들(ABI, 메모리 맵, 펌웨어
인터페이스)은 ISA가 지정하지 않습니다.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Programmer Visible State&lt;&#x2F;strong&gt;는 ISA에서 프로그래머(컴파일러)가 명령어를 통해 직접
읽거나 쓸 수 있는 모든 하드웨어 상태입니다. 프로그램의 의미(sementics)는 이
상태들의 변화로 정의됩니다. 구체적으로는 범용 레지스터, 프로그램 카운터, 스택
포인터, 플래그 레지스터, 메모리 주소 공간 전체 등이 해당합니다.&lt;&#x2F;p&gt;
&lt;p&gt;이와 반대로 보이지 않는 상태(microarchitectural state)는 캐시 내용, 분기
예측기의 히스토리, 리오더 버퍼, 예약 스테이션, 물리 레지스터 파일, TLB 엔트리
등이 있습니다. 이들은 성능에만 영향을 주고, 프로그램의 논리적인 결과를 바꾸지
않습니다.&lt;&#x2F;p&gt;
&lt;p&gt;같은 ISA를 구현한 어떤 칩에서든 &lt;strong&gt;Programmer Visible State&lt;&#x2F;strong&gt;의 변화가 동일하면
정확한 구현이고, 그 외의 내부 상태는 자유롭게 다를 수 있습니다.&lt;&#x2F;p&gt;
&lt;p&gt;ISA가 제공하는 명령어들을 기능별로 분류하면 아래와 같이 나눌 수 있습니다.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;산술&#x2F;논리 연산(Arithmetic&#x2F;Logical)&lt;&#x2F;strong&gt;: 레지스터나 즉시값에 대해 연산을
수행합니다. 결과는 보통 레지스터에 저장되고, 부수적으로 플래그가 갱신됩니다.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;데이터 이동(Data Transfer&#x2F;Memory)&lt;&#x2F;strong&gt;: 레지스터와 메모리, 또는 레지스터 간에
데이터를 옮깁니다.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;제어 흐름(Control Flow)&lt;&#x2F;strong&gt;: 프로그램 카운터를 변경해 실행 흐름을 바꿉니다.
무조건 분기(Jump), 조건 분기(Branch), 함수 호출&#x2F;복귀 등이 있습니다.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;시스템 명령어(System&#x2F;Privileged)&lt;&#x2F;strong&gt;: OS나 하드웨어의 제어를 위한
명령어입니다. 사용자 모드에서 커널로 진입, 인터럽트 제어 등이 있습니다. 현대
마이크로프로세서에서는 이런 명령어는 대부분 커널 모드에서만 실행 가능하고,
유저 모드에서 실행하면 예외가 발생합니다.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;이러한 명령어는 반드시 &lt;strong&gt;원자적으로(Atomicity)&lt;&#x2F;strong&gt; 실행되어야 합니다. 하나의
명령어는 Programmer Visible State를 여러 개 변경할 수 있지만, 이러한 중간 변경
과정은 프로그래머에게 노출되어서는 안됩니다. 실제 하드웨어에서는 파이프라인에서
레지스터를 먼저 쓰고, PC를 나중에 갱신하는 식으로 명령어를 단계적으로 처리할 수
있지만, 이는 Microarchitectural State이지, Programmer Visible State가 아닙니다.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;isayi-yeogsa&quot;&gt;ISA의 역사&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;edsac&quot;&gt;EDSAC&lt;&#x2F;h3&gt;
&lt;p&gt;EDSAC은 최초의 저장 프로그램 컴퓨터 중 하나로, 아주 단순한 ISA를 가지고
있습니다.&lt;&#x2F;p&gt;
&lt;p&gt;명령어는 5비트 opcode + 예약 비트 + 10비트 메모리 주소(n)로 구성되며, 단일 누산기
(Accumulator) 구조입니다. 레지스터는 Acc 하나뿐이고, 모든 연산은 이 Acc
레지스터를 중심으로 돌아갑니다. 명령어의 예시는 아래와 같습니다.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A n: &lt;code&gt;M[n]&lt;&#x2F;code&gt;을 &lt;code&gt;ACC&lt;&#x2F;code&gt;에 더합니다&lt;&#x2F;li&gt;
&lt;li&gt;T n: &lt;code&gt;ACC&lt;&#x2F;code&gt;의 내용을 &lt;code&gt;M[n]&lt;&#x2F;code&gt;으로 옮기고 ACC를 비웁니다&lt;&#x2F;li&gt;
&lt;li&gt;E n: &lt;code&gt;ACC&amp;gt;=0&lt;&#x2F;code&gt;이라면, &lt;code&gt;M[n]&lt;&#x2F;code&gt;으로 점프합니다&lt;&#x2F;li&gt;
&lt;li&gt;I n: 테이프로부터 다음 글자를 읽고, &lt;code&gt;M[n]&lt;&#x2F;code&gt;이 가르키는 주소에 저장합니다.&lt;&#x2F;li&gt;
&lt;li&gt;Z  : 프로그램을 멈추고 벨을 울립니다.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;모든 메모리 주소가 명령어에 하드코딩 되어 있다는 점이 특징입니다. 하지만 이러면
아래와 같은 문제가 발생합니다.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;코드에서 함수를 실행할 경우, 함수는 호출 위치로 복귀해야합니다.
하지만EDSAC은 복귀 주소가 명령어에 하드 코딩 되어있으므로,
같은 함수를 여러 곳에서 호출할 경우 복귀 주소를 지정하기 어려웠습니다.&lt;&#x2F;li&gt;
&lt;li&gt;배열 원소를 접근할 때, 배열의 주소가 명령어에 하드코딩되어 있으므로 루프를
돌면서 배열에 접근하려면 매번 명령어 자체를 수정해서 주소를 바꿔야했습니다.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;isayi-baljeon&quot;&gt;ISA의 발전&lt;&#x2F;h3&gt;
&lt;p&gt;이러한 문제를 해결하고자, 후대 CPU는 다양한 방식으로 진화해왔습니다.&lt;&#x2F;p&gt;
&lt;p&gt;첫 번째로 레지스터는 누산기 레지스터 하나만을 이용하는 구조에서, 프로그램의 주소
지정을 위한 레지스터가 추가되었고, 현대는 범용 레지스터(GPR, General Purpose
Register)가 다수 추가되어 모든 레지스터를 어떤 용도로든 사용할 수 있게
되었습니다.&lt;&#x2F;p&gt;
&lt;p&gt;두 번째로 명령어에 다양한 피연산자를 지정할 수 있게 되었습니다. EDSAC 처럼
명령어가 암묵적인 피연산자(ACC)를 가지고 명시적 피연산자는 하나 뿐인 구조를
&lt;strong&gt;Monadic&lt;&#x2F;strong&gt;, &lt;code&gt;OP inout, in2&lt;&#x2F;code&gt; 처럼 피연산자가 2개이고 입력 중 하나가 결과로
덮어쓰이는 구조를 &lt;strong&gt;Dyadic&lt;&#x2F;strong&gt;, &lt;code&gt;OP out, in1, in2&lt;&#x2F;code&gt;와 같이 출력과 입력 2개를 모두
명시하는 구조를 &lt;strong&gt;Triadic&lt;&#x2F;strong&gt;이라고 합니다.&lt;&#x2F;p&gt;
&lt;p&gt;후술할 CISC 아키텍처에서는 &lt;code&gt;ADD [mem], reg&lt;&#x2F;code&gt;와 같이 명령어 하나로 메모리 접근과 연산을
동시에 수행할 수 있는 반면, RISC 아키텍처에서는 메모리 접근은 load&#x2F;store 만으로
합니다. (load-store architecture)&lt;&#x2F;p&gt;
&lt;p&gt;세 번째로 명령어에 다양한 메모리 주소를 지정할 수 있게 되었습니다.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Absoulte&lt;&#x2F;strong&gt; - &lt;code&gt;LD rt, 100&lt;&#x2F;code&gt;: EDSAC과 같이 주소가 명령어에 상수로 지정된 방식입니다.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Register Indirect&lt;&#x2F;strong&gt; - &lt;code&gt;LD rt, (r_base)&lt;&#x2F;code&gt;: 레지스터에 들어가 있는 값을 주소로
사용합니다. 포인터 역참조가 이런 방식입니다.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Displaced&lt;&#x2F;strong&gt; - &lt;code&gt;LD rt, offset(r_base)&lt;&#x2F;code&gt;: 레지스터 값에 상수 오프셋을 더해
주소를 만듭니다. 구조체 접근에 유용합니다.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Indexed&lt;&#x2F;strong&gt; - &lt;code&gt;LD rt, (r_base, r_index)&lt;&#x2F;code&gt;: 두 레지스터 값을 더해 주소를
만듭니다.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Memory Indirect&lt;&#x2F;strong&gt; - &lt;code&gt;LD rt, ((r_base))&lt;&#x2F;code&gt;: 메모리 주소에서 값을 읽고, 그 값을
다시 주소로 사용합니다. 이중 포인터 역참조에 해당합니다.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Auto increment&#x2F;decrement&lt;&#x2F;strong&gt; - &lt;code&gt;LDR rt, (r_base)&lt;&#x2F;code&gt;: 레지스터 값을 주소로
사용하되, 접근 전이나 후에 레지스터 값을 자동으로 증가&#x2F;감소 시킵니다. 배열을
순차적으로 순회할 때 유용합니다.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;riscyi-deungjang&quot;&gt;RISC의 등장&lt;&#x2F;h3&gt;
&lt;p&gt;초기의 CPU 발전은, 단순했던 ISA를 점점 복잡하게 하고, 명령어 세트에 다양한
기능들을 넣으며 진행되었습니다. 당시에는 어셈블리로 직접 프로그래밍하는 것이
보편적이었으며, 다양한 명령어를 넣음으로서 프로그래머의 코딩을 간편하게 만들 수
있었습니다. 또한, 메모리 크기나 성능이 제한적이었기 때문에, 자주 사용되는 복잡한
연산들을 한번에 처리하는 것이 유용했습니다.&lt;&#x2F;p&gt;
&lt;p&gt;하지만, 이후 컴파일러 기술이 발전하며 프로그래머가 직접 복잡한 어셈블리 명령어를
이용해 프로그래밍하는 경우는 거의 없어졌습니다. 사람이 직접 사용하는 것을
상정하고 만들어진 복잡한 명령어들은 컴파일러가 최적하기 어려웠으며, 명령어마다
실행 시간이나 메모리 접근 횟수가 천차만별이라 파이프라인을 효율적으로 설계하기도
어려웠습니다.&lt;&#x2F;p&gt;
&lt;p&gt;이러한 배경에서 RISC (Reduced Instruction Set Computer)가 등장합니다. 모든
명령어의 크기는 같은 크기로, 메모리 접근은 반드시 지정된 명령어로, 각 명령어는
단순하게 하되 레지스터를 넉넉하게 제공하는 등의 명령어 세트를 단순하게 만들자는
철학으로 만든 RISC CPU는 복잡성을 하드웨어에서 컴파일러로 이동하고, 하드웨어를
단순하게 만드는 대신, 최적화 부담은 발전한 컴파일러에 넘깁니다.&lt;&#x2F;p&gt;
&lt;p&gt;RISC는 파이프라인을 쉽게 만들 수 있고, 클럭을 높이기에도 유리했습니다.
하드웨어가 단순하므로 트랜지스터를 캐시, 분기 예측기등 성능에 도움이 되는 곳에
투자할 수 있고, 검증과 디버깅이 쉬웠으며 설계 사이클도 짧았습니다.&lt;&#x2F;p&gt;
&lt;p&gt;RISC와 대비하여 RISC 이전의 아키텍처들(x86, M68K, Z80 등)을
CISC (Complex Instruction Set Computer)라고 부르는데,
M68K, Z80등 많은 CISC 아키텍처들은 사라졌지만, x86은 거대한 소프트웨어 생태계 때문에
사라지지는 않고, 대신 외부 ISA는 CISC, 내부적으로는 RISC라는 절충안을 채택하여
복잡한 명령어를 CPU 내부적으로 RISC로 분해하여 처리하는 설계를 도입했습니다.&lt;&#x2F;p&gt;
&lt;p&gt;현대 RISC 아키텍처의 대표 주자로는 ARM이 있는데, ARM은 초기에 간단한
설계를 통한 높은 전성비(전력 당 성능비)를 무기로 새로운 분야인 모바일 시장에
빠르게 진출했고, 2020년대 이전까지는 RISC 아키텍처는 모바일, 임베디드 등 저전력
설계에서, CISC 아키텍처는 고전력을 소모하는 대신 높은 성능을 필요로 하는
워크스테이션이나 데스크탑, 서버 환경에서 이용되어 왔습니다.&lt;&#x2F;p&gt;
&lt;p&gt;하지만 2020년대 이후 Apple Silicon에서 M1 칩을 출시하면서 이러한 상황이 크게
역전되었습니다. 애플의 M1 등 ARM CPU는 RISC 아키텍처 기반의 CPU가 높은 성능과 CISC
CPU보다 개선된 전성비로 빠르게 시장 점유율을 늘려나가고 있으며, 애플 이외에도 ARM
Windows&#x2F;Linux 노트북이 판매되는 등 모바일 시장 이외에도 RISC 아키텍처가
점유율을 조금씩 늘려가고 있습니다.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;risc-v&quot;&gt;RISC-V&lt;&#x2F;h1&gt;
&lt;p&gt;RISC-V는 2010년에 UC Berkeley에서 시작된 오픈소스 ISA입니다. 1981년에 설계된
최초의 RISC 프로세서인 RISC-I, RISC-II에 지난 30년간의 교훈을 반영해 레거시 없이
깨끗한 RISC ISA를 처음부터 설계했습니다. (V는 Berkeley에서 개발한 다섯 번째 RISC
설계라는 뜻입니다. RISC-I, RISC-II, SOAR, SPUR, RISC-V)&lt;&#x2F;p&gt;
&lt;p&gt;RISC-V는 특정 회사에 종속된 ARM이나 x86과 달리, 누구나 무료로 RISC-V ISA를
구현한 프로세서를 만들 수 있고, 스타트업, 학교, 대기업 모두 자유롭게 칩을 설계할
수 있습니다. 또한, 모듈식 설계를 이용해 하나의 거대한 ISA가 아니라, 최소한의
명령어를 가진 작은 ISA에 필요한 확장을 붙히는 구조로 개발되었습니다.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;risc-vyi-programmer-visible-state&quot;&gt;RISC-V의 Programmer Visible State&lt;&#x2F;h2&gt;
&lt;p&gt;RISC-V에는 기본적으로 x0부터 x31까지 32개의 정수 범용 레지스터가 있습니다.
x0은 항상 0으로 고정된 상태인데, 이는 x0을 0으로 고정함으로서 다양한
동작을 기존 명령어로 표현함으로서 명령어 가짓 수를 줄일 수 있기 때문입니다.
(예를 들어, NOP를 &lt;code&gt;ADDI x0, x0, 0&lt;&#x2F;code&gt;으로, 즉시값 로드를 &lt;code&gt;ADDI x1, x0, 42&lt;&#x2F;code&gt;로 표현할
수 있습니다.)&lt;&#x2F;p&gt;
&lt;p&gt;또한, 범용 레지스터에 포함되지 않는 PC 레지스터와 부동소수점 연산을 제공하는 F&#x2F;D
확장에 포함되는 부동소수점 레지스터 등이 존재합니다.&lt;&#x2F;p&gt;
&lt;p&gt;메모리는 바이트 주소 지정 방식이며, 기본적으로 리틀 엔디언 방식입니다. 메모리의
모든 바이트는 Programmer Visible State이며, 기본적으로 리틀 엔디언 정렬을
이용합니다.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;risc-vyi-hwagjang-cegye&quot;&gt;RISC-V의 확장 체계&lt;&#x2F;h2&gt;
&lt;p&gt;RISC-V는 작은 기본 ISA에 필요한 확장을 조합하여 사용하는 구조입니다.&lt;&#x2F;p&gt;
&lt;p&gt;기본이 되는 ISA는 아래와 같습니다.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;RV32I&lt;&#x2F;strong&gt; : 32비트 정수 기본. 정수 산술&#x2F;논리, load&#x2F;store 등 최소한의
명령어만을 가집니다.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;RV64I&lt;&#x2F;strong&gt; : 64비트 정수 기본. RV32I에 64비트 연산과 더블워드 명령어가
추가됩니다.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;RV128I&lt;&#x2F;strong&gt; : 128비트 정수 기본. 다만 64비트보다 큰 주소 공간이 언제 필요할지는
아직 불분명하기 때문에, 사양이 완전히 확정(frozen)되지는 않은 상태입니다.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;RV32E&lt;&#x2F;strong&gt;, &lt;strong&gt;RV64E&lt;&#x2F;strong&gt; : 임베디드용 축소 ISA, 레지스터를 32개에서 16개로 줄여 극소형
마이크로컨트롤러의 비용을 낮춥니다.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;여기에 아래와 같은 표준 Extension 들이 존재합니다.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;M&lt;&#x2F;strong&gt; : 정수 곱셈, 나눗셈 : &lt;code&gt;MUL&lt;&#x2F;code&gt;, &lt;code&gt;MULH&lt;&#x2F;code&gt; 등 하드웨어 곱셈기의 네이티브 정수
곱셈 연산 명령어를 추가합니다. 극소형 임베디드 기기에서는 하드웨어 곱셈 없이
곱셈과 나눗셈을 비트연산 등 다른 연산으로 대체할 수 있기 때문에, 곱셈과
나눗셈이 별도의 확장으로 분리되어 있습니다.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;A&lt;&#x2F;strong&gt; : 원자적 연산 : 멀티 코어 환경에서 코어 간 메모리 공유를 위한
명령어입니다. 메모리에 대한 쓰기나 읽기를 원자적으로 수행하거나, 메모리를
예약하는 기능 등이 정의되어 있습니다.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;F&lt;&#x2F;strong&gt; : 32비트 부동소수점 연산 : FPU를 통한 하드웨어 부동 소수점 연산을
추가합니다. 32개의 부동소수점 레지스터 f0-f31과 부동 소수점 연산의 결과를
기록하는 플래그인 fcsr이 추가됩니다.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;D&lt;&#x2F;strong&gt;, &lt;strong&gt;Q&lt;&#x2F;strong&gt; : 각각 64비트 배정밀도 부동소수점 연산과 128비트 4배정밀도
부동소수점 연산 명령어를 추가합니다.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;C&lt;&#x2F;strong&gt; : 자주 쓰는 명령어를 16비트로 인코딩할 수 있게 합니다. 코드의 크기를
줄일 수 있어 플래시 메모리 크기가 크게 제한되는 임베디드 환경에서 사용할 수
있습니다.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;V&lt;&#x2F;strong&gt; : 벡터 확장. SIMD와 유사한 다양한 벡터 연산을 지원합니다.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;H&lt;&#x2F;strong&gt; : 하이퍼바이저 확장. 하이퍼바이저가 지원하는 가상화 계층을 지원합니다.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;이외에 단일 알파벳 대신, 확장 이름 앞에 Z를 붙힌 세분화된 확장들도 있습니다.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Zicsr&lt;&#x2F;strong&gt; : CSR 접근 명령어&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Zifencei&lt;&#x2F;strong&gt; : 명령어 캐시 동기화, 자기 수정코드, JIT 컴파일시 I-Cache와
D-Cache 일관성 보장&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Zba&lt;&#x2F;strong&gt;, &lt;strong&gt;Zbb&lt;&#x2F;strong&gt;, &lt;strong&gt;Zbc&lt;&#x2F;strong&gt;, &lt;strong&gt;Zbs&lt;&#x2F;strong&gt; : 주소 계산 가속, 기본 비트 연산, 캐리리스
곱셈 등 세부 비트 조작 명령어&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Zfinx&lt;&#x2F;strong&gt; : 부동소수점 연산을 정수 레지스터에서 수행&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Ztso&lt;&#x2F;strong&gt; : Total Store Ordering 메모리 모델 보장. x86 바이너리 변환시 유용&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Zicond&lt;&#x2F;strong&gt; : 조건부 연산. 분기 없이 조건부로 값을 선택&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;정말 다양한 확장이 존재하기 때문에 소프트웨어 호환성을 위해 자주 사용하는
확장들을 묶어 정의하는 &lt;strong&gt;RISC-V 프로파일&lt;&#x2F;strong&gt;이 존재합니다.
예를 들어 &lt;strong&gt;RVA20U64&lt;&#x2F;strong&gt;는 I, M, A, F, D, C, Zicsr, Zifencei 확장을
필수로 가지도록 정의되어 있습니다.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;risc-v-myeongryeongeo-pomes&quot;&gt;RISC-V 명령어 포멧&lt;&#x2F;h2&gt;
&lt;p&gt;RISC-V는 6가지의 기본 명령어 포멧을 정의합니다. RV32I에서 모두 32비트 고정
길이이며, opcode, rd, rs1, rs2의 위치가 포맷 간 최대한 일관되게 배치되어
디코딩을 단순하게 만듭니다.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;r-type&quot;&gt;R-Type&lt;&#x2F;h3&gt;
&lt;p&gt;레지스터 간 연산에 사용됩니다.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[31:25]  [24:20]  [19:15]  [14:12]  [11:7]  [6:0]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;funct7   rs2      rs1      funct3   rd      opcode&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7비트    5비트    5비트    3비트    5비트   7비트&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;rs1, rs2 두 소스 레지스터로 연산하고 결과를 rd에 저장합니다. &lt;code&gt;funct7&lt;&#x2F;code&gt;와
&lt;code&gt;funct3&lt;&#x2F;code&gt;가 구체적인 연산 종류를 구분합니다.&lt;&#x2F;p&gt;
&lt;p&gt;예: &lt;code&gt;ADD x1, x2, x3&lt;&#x2F;code&gt;: x1 &amp;lt;- x2 + x3&lt;&#x2F;p&gt;
&lt;h3 id=&quot;i-type&quot;&gt;I-Type&lt;&#x2F;h3&gt;
&lt;p&gt;즉시값 연산, load, JALR 등에 사용됩니다.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[31:20]     [19:15]  [14:12]  [11:7]  [6:0]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;imm[11:0]   rs1      funct3   rd      opcode&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;12비트      5비트    3비트    5비트   7비트&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;12비트 즉시값이 부호 확장(sign-extend)되어 사용됩니다. R-type에서 &lt;code&gt;funct7&lt;&#x2F;code&gt;과
&lt;code&gt;rs2&lt;&#x2F;code&gt; 자리가 즉시값으로 대체된 형태입니다.&lt;&#x2F;p&gt;
&lt;p&gt;예: &lt;code&gt;ADDI x1, x2, 10&lt;&#x2F;code&gt;: x1 &amp;lt;- x2 + 10&lt;&#x2F;p&gt;
&lt;p&gt;R-type에서 &lt;code&gt;funct7&lt;&#x2F;code&gt;이 빠졌기 때문에, 약간의 명령어 차이가 존재합니다. 예를
들어 R-type에서 &lt;code&gt;funct7&lt;&#x2F;code&gt;으로 구분되는 ADD&#x2F;SUB의 경우, I-type에서는 음수 즉시값을
쓰면 되므로 명령어 자체가 필요 없어 빠졌고, Immeidate field 를 나눠 세부
명령어를 구분하는 경우도 있습니다.
(RV32I 기준 즉시값이 최대 5비트까지만 필요한 SLLI, SRLI, SRAI 등 시프트
명령어는, 앞 7비트를 명령어 지정자로, 나머지 5비트를 시프트 즉시값으로
사용합니다.)&lt;&#x2F;p&gt;
&lt;p&gt;메모리에서 값을 가져오는 Load 명령어 또한 I-Type 인데, &lt;code&gt;opcode&lt;&#x2F;code&gt; 자리에 Load를
의미하는 &lt;code&gt;0000011&lt;&#x2F;code&gt;을 넣고, &lt;code&gt;rs1&lt;&#x2F;code&gt;을 베이스로, 12비트 &lt;code&gt;imm&lt;&#x2F;code&gt;은 오프셋으로
이용합니다. &lt;code&gt;funct3&lt;&#x2F;code&gt;에 따라 32비트를 읽는 &lt;code&gt;LW&lt;&#x2F;code&gt;, 16비트를 읽고 부호 확장하는 &lt;code&gt;LH&lt;&#x2F;code&gt;,
16비트를 읽고 제로 확장하는 &lt;code&gt;LHU&lt;&#x2F;code&gt;, 8비트를 읽는 &lt;code&gt;LB&lt;&#x2F;code&gt;, &lt;code&gt;LBU&lt;&#x2F;code&gt; 등이 구분됩니다.&lt;&#x2F;p&gt;
&lt;p&gt;또한, 즉시값은 항상 12비트로 제한됩니다. 프로그램에서 사용하는 즉시값은
통상적으로 작은 값이고, 큰 상수가 필요한 경우는 통상적으로 드물기 때문에,
최적화를 위한 의도한 설계입니다. 꼭 큰 상수가
필요한 경우에는 후술할 U-type 명령어나 AUIPC 등을 이용해 값을 만들어 쓰게 됩니다.
이는 하나의 명령어로 모든 것을 하려 하지 말고, 간단한 여러 명령어의 조합으로
해결하자는 RISC의 철학을 따른 것입니다.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;s-type&quot;&gt;S-Type&lt;&#x2F;h3&gt;
&lt;p&gt;메모리에 값을 저장하는데 사용됩니다.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[31:25]   [24:20]  [19:15]  [14:12]  [11:7]   [6:0]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;imm[11:5] rs2      rs1      funct3   imm[4:0] opcode&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7비트     5비트    5비트    3비트    5비트    7비트&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;결과를 레지스터에 쓰지 않으므로 &lt;code&gt;rd&lt;&#x2F;code&gt;가 없고, 대신 &lt;code&gt;rd&lt;&#x2F;code&gt; 자리에 즉시값 하위
비트를, &lt;code&gt;funct7&lt;&#x2F;code&gt; 자리에 즉시값의 상위비트를 넣습니다.&lt;&#x2F;p&gt;
&lt;p&gt;예: &lt;code&gt;SW x3, 12(x2)&lt;&#x2F;code&gt;: &lt;code&gt;MEM[x2 + 12]&lt;&#x2F;code&gt; &amp;lt;- x3&lt;&#x2F;p&gt;
&lt;h3 id=&quot;b-type-sb-type&quot;&gt;B-Type (SB-Type)&lt;&#x2F;h3&gt;
&lt;p&gt;조건 분기에 사용됩니다.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[31]     [30:25]    [24:20]  [19:15]  [14:12]  [11:8]   [7]     [6:0]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;imm[12]  imm[10:5]  rs2      rs1      funct3   imm[4:1] imm[11] opcode&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1비트    6비트      5비트    5비트    3비트    4비트    1비트   7비트&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;S-Type과 유사하지만, 즉시값의 비트 배치가 다릅니다. 즉시값이 분기 오프셋으로
사용되며, RISC-V 명령어는 최소 16비트 단위로 정렬되어 분기 오프셋의 최하위
비트는 항상 0이므로 인코딩하지 않습니다. 따라서 13비트 범위의 분기가 가능합니다.&lt;&#x2F;p&gt;
&lt;p&gt;예 : &lt;code&gt;BEQ x1, x2, offset&lt;&#x2F;code&gt;: &lt;code&gt;x1 == x2&lt;&#x2F;code&gt;면 PC &amp;lt;- PC + offset&lt;&#x2F;p&gt;
&lt;p&gt;비트 배치가 특이하게 꼬여있는 이유는 S-type과 최대한 많은 비트 위치를 공유해서
하드웨어를 단순화하기 위함입니다. 이러한 S-Type과의 유사성 때문에 B-Type을
SB-Type이라고 부르기도 합니다.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;u-type&quot;&gt;U-Type&lt;&#x2F;h3&gt;
&lt;p&gt;상위 20비트 즉시값을 사용하는 명령어입니다.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[31:12]     [11:7]  [6:0]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;imm[31:12]  rd      opcode&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;20비트      5비트   7비트&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;20비트 즉시값이 상위 20비트에 배치되고, 하위 12비트는 0으로 채워집니다. I-Type
명령어에서 최대 12비트까지의 즉시값을 사용할 수 있기 때문에, 이를 보완하기 위해
만들어진 명령어입니다.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;LUI&lt;&#x2F;strong&gt; (Load Upper Immedate): rd &amp;lt;- imm &amp;lt;&amp;lt; 12, 큰 상수를 만들 때 ADDI와
조합하여 사용합니다. &lt;code&gt;0x12345678&lt;&#x2F;code&gt;을 만들 때, &lt;code&gt;LUI x1, 0x12345&lt;&#x2F;code&gt;로 상위 20비트를
채우고, &lt;code&gt;ADDI x1, x1, 0x678&lt;&#x2F;code&gt;로 하위 12비트를 채웁니다.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;AUIPC&lt;&#x2F;strong&gt; (Add Upper Immediate to PC): rd &amp;lt;- PC + (imm &amp;lt;&amp;lt; 12), PC 상대 주소
계산에 사용되며, JAL과 load와 조합하여 현재 위치에서 ±2GB 범위의 주소를 만들
수 있습니다.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;j-type-uj-type&quot;&gt;J-Type (UJ-Type)&lt;&#x2F;h3&gt;
&lt;p&gt;무조건 점프에 사용됩니다.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[31]     [30:21]    [20]     [19:12]    [11:7]  [6:0]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;imm[20]  imm[10:1]  imm[11]  imm[19:12] rd      opcode&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1비트    10비트     1비트    8비트      5비트   7비트&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;20비트 즉시값을 점프 오프셋으로 사용하며, B-Type과 동일하게 bit0은 항상 0이므로
인코딩하지 않습니다. 따라서 21비트 범위(±1MB)의 점프가 가능합니다.&lt;&#x2F;p&gt;
&lt;p&gt;B-Type과 유사하게, U-Type과 비트 위치를 최대한 공유하도록 설계되어 있습니다.
따라서 UJ-Type이라고 불리기도 합니다.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rv32i-myeongryeongeo-seteu&quot;&gt;RV32I 명령어 세트&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;jeongsu-sansul-nonri-r-type&quot;&gt;정수 산술&#x2F;논리 (R-type)&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;명령어&lt;&#x2F;th&gt;&lt;th&gt;동작&lt;&#x2F;th&gt;&lt;th&gt;설명&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;ADD rd, rs1, rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← rs1 + rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;덧셈&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SUB rd, rs1, rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← rs1 - rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;뺄셈&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;AND rd, rs1, rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← rs1 &amp;amp; rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;비트 AND&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;OR rd, rs1, rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← rs1 | rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;비트 OR&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;XOR rd, rs1, rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← rs1 ^ rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;비트 XOR&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SLL rd, rs1, rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← rs1 &amp;lt;&amp;lt; rs2[4:0]&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;논리 좌시프트&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SRL rd, rs1, rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← rs1 &amp;gt;&amp;gt; rs2[4:0]&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;논리 우시프트 (0 채움)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SRA rd, rs1, rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← rs1 &amp;gt;&amp;gt;&amp;gt; rs2[4:0]&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;산술 우시프트 (부호 유지)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SLT rd, rs1, rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← (rs1 &amp;lt; rs2) ? 1 : 0&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;부호 있는 비교&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SLTU rd, rs1, rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← (rs1 &amp;lt; rs2) ? 1 : 0&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;부호 없는 비교&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;jeugsigabs-sansul-nonri-i-type&quot;&gt;즉시값 산술&#x2F;논리 (I-type)&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;명령어&lt;&#x2F;th&gt;&lt;th&gt;동작&lt;&#x2F;th&gt;&lt;th&gt;설명&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;ADDI rd, rs1, imm&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← rs1 + sext(imm)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;즉시값 덧셈&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;ANDI rd, rs1, imm&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← rs1 &amp;amp; sext(imm)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;즉시값 AND&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;ORI rd, rs1, imm&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← rs1 | sext(imm)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;즉시값 OR&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;XORI rd, rs1, imm&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← rs1 ^ sext(imm)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;즉시값 XOR&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SLLI rd, rs1, shamt&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← rs1 &amp;lt;&amp;lt; shamt&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;즉시값 논리 좌시프트&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SRLI rd, rs1, shamt&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← rs1 &amp;gt;&amp;gt; shamt&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;즉시값 논리 우시프트&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SRAI rd, rs1, shamt&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← rs1 &amp;gt;&amp;gt;&amp;gt; shamt&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;즉시값 산술 우시프트&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SLTI rd, rs1, imm&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← (rs1 &amp;lt; sext(imm)) ? 1 : 0&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;즉시값 부호 있는 비교&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SLTIU rd, rs1, imm&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← (rs1 &amp;lt; sext(imm)) ? 1 : 0&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;즉시값 부호 없는 비교&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;sangwi-jeugsigabs-u-type&quot;&gt;상위 즉시값 (U-type)&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;명령어&lt;&#x2F;th&gt;&lt;th&gt;동작&lt;&#x2F;th&gt;&lt;th&gt;설명&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;LUI rd, imm&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← imm &amp;lt;&amp;lt; 12&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;상위 20비트 로드&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;AUIPC rd, imm&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← PC + (imm &amp;lt;&amp;lt; 12)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;PC 기준 상위 20비트 덧셈&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;load-i-type&quot;&gt;Load (I-type)&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;명령어&lt;&#x2F;th&gt;&lt;th&gt;funct3&lt;&#x2F;th&gt;&lt;th&gt;동작&lt;&#x2F;th&gt;&lt;th&gt;설명&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;LB rd, imm(rs1)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← sext(MEM8[rs1 + sext(imm)])&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;바이트 로드 (부호 확장)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;LH rd, imm(rs1)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;001&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← sext(MEM16[rs1 + sext(imm)])&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;하프워드 로드 (부호 확장)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;LW rd, imm(rs1)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;010&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← MEM32[rs1 + sext(imm)]&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;워드 로드&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;LBU rd, imm(rs1)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;100&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← zext(MEM8[rs1 + sext(imm)])&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;바이트 로드 (제로 확장)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;LHU rd, imm(rs1)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;101&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← zext(MEM16[rs1 + sext(imm)])&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;하프워드 로드 (제로 확장)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;store-s-type&quot;&gt;Store (S-type)&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;명령어&lt;&#x2F;th&gt;&lt;th&gt;funct3&lt;&#x2F;th&gt;&lt;th&gt;동작&lt;&#x2F;th&gt;&lt;th&gt;설명&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SB rs2, imm(rs1)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;MEM8[rs1 + sext(imm)] ← rs2[7:0]&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;바이트 저장&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SH rs2, imm(rs1)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;001&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;MEM16[rs1 + sext(imm)] ← rs2[15:0]&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;하프워드 저장&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SW rs2, imm(rs1)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;010&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;MEM32[rs1 + sext(imm)] ← rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;워드 저장&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;jogeon-bungi-b-type&quot;&gt;조건 분기 (B-type)&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;명령어&lt;&#x2F;th&gt;&lt;th&gt;funct3&lt;&#x2F;th&gt;&lt;th&gt;동작&lt;&#x2F;th&gt;&lt;th&gt;설명&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;BEQ rs1, rs2, offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;if (rs1 == rs2) PC ← PC + offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;같으면 분기&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;BNE rs1, rs2, offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;001&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;if (rs1 != rs2) PC ← PC + offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;다르면 분기&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;BLT rs1, rs2, offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;100&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;if (rs1 &amp;lt; rs2) PC ← PC + offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;부호 있는 미만&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;BGE rs1, rs2, offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;101&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;if (rs1 &amp;gt;= rs2) PC ← PC + offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;부호 있는 이상&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;BLTU rs1, rs2, offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;110&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;if (rs1 &amp;lt; rs2) PC ← PC + offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;부호 없는 미만&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;BGEU rs1, rs2, offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;111&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;if (rs1 &amp;gt;= rs2) PC ← PC + offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;부호 없는 이상&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;jeompeu&quot;&gt;점프&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;명령어&lt;&#x2F;th&gt;&lt;th&gt;타입&lt;&#x2F;th&gt;&lt;th&gt;동작&lt;&#x2F;th&gt;&lt;th&gt;설명&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;JAL rd, offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;J-type&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← PC+4, PC ← PC + offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;직접 점프 (함수 호출)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;JALR rd, rs1, imm&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;I-type&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd ← PC+4, PC ← (rs1 + sext(imm)) &amp;amp; ~1&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;간접 점프 (함수 복귀 등)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;memori-sunseo&quot;&gt;메모리 순서&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;명령어&lt;&#x2F;th&gt;&lt;th&gt;설명&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;FENCE pred, succ&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;메모리 접근 순서 보장 (pred&#x2F;succ: I, O, R, W의 조합)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;siseutem-myeongryeongeo&quot;&gt;시스템 명령어&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;명령어&lt;&#x2F;th&gt;&lt;th&gt;동작&lt;&#x2F;th&gt;&lt;th&gt;설명&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;ECALL&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;환경 호출 트랩 발생&lt;&#x2F;td&gt;&lt;td&gt;시스템 콜 (OS 진입)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;EBREAK&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;디버그 트랩 발생&lt;&#x2F;td&gt;&lt;td&gt;브레이크포인트&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;과거에는 &lt;code&gt;Zicsr&lt;&#x2F;code&gt;, &lt;code&gt;Zifencei&lt;&#x2F;code&gt; 확장이 RV32I에 포함되어 있었으나, 2.1에서 별도
확장으로 분리되어서 현재는 총 40개의 명령어가 RV32I를 구성하고 있습니다.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;risc-v-abi-keonbensyeon&quot;&gt;RISC-V ABI 컨벤션&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;rejiseuteo-keonbensyeon&quot;&gt;레지스터 컨벤션&lt;&#x2F;h3&gt;
&lt;p&gt;ISA 수준에서는 강제되지 않지만, 모든 시스템에서 권장되는 레지스터의 사용
컨벤션입니다. &lt;code&gt;x0 = 0&lt;&#x2F;code&gt; 만이 유일하게 ISA에서 강제되는 것이고, 나머지는 하드웨어
관점에서 동등합니다. 실제로 이러한 컨벤션을 준수하는 것은 ABI, Calling
Convention의 역할입니다.&lt;&#x2F;p&gt;
&lt;p&gt;하지만, 대부분의 컴파일러, OS, 디버거가 이러한 컨벤션을 준수하고 있기 때문에,
특수한 베어메탈 임베디드에서 외부 라이브러리조차 사용하지 않는 매우 특수한
경우를 제외하고는 이러한 컨벤션을 준수해야합니다.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;레지스터&lt;&#x2F;th&gt;&lt;th&gt;ABI 이름&lt;&#x2F;th&gt;&lt;th&gt;용도&lt;&#x2F;th&gt;&lt;th&gt;Caller&#x2F;Callee saved&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x0&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;zero&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;항상 0 (ISA 수준에서 고정)&lt;&#x2F;td&gt;&lt;td&gt;—&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x1&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;ra&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;복귀 주소 (Return Address)&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;sp&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;스택 포인터 (Stack Pointer)&lt;&#x2F;td&gt;&lt;td&gt;Callee&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x3&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;gp&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;전역 포인터 (Global Pointer)&lt;&#x2F;td&gt;&lt;td&gt;—&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x4&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;tp&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;스레드 포인터 (Thread Pointer)&lt;&#x2F;td&gt;&lt;td&gt;—&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x5&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;t0&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;임시 레지스터&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x6&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;t1&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;임시 레지스터&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x7&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;t2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;임시 레지스터&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x8&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;s0&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;fp&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;저장 레지스터 &#x2F; 프레임 포인터&lt;&#x2F;td&gt;&lt;td&gt;Callee&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x9&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;s1&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;저장 레지스터&lt;&#x2F;td&gt;&lt;td&gt;Callee&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x10&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;a0&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;함수 인자 1 &#x2F; 반환값 1&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x11&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;a1&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;함수 인자 2 &#x2F; 반환값 2&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x12&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;a2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;함수 인자 3&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x13&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;a3&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;함수 인자 4&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x14&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;a4&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;함수 인자 5&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x15&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;a5&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;함수 인자 6&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x16&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;a6&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;함수 인자 7&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x17&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;a7&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;함수 인자 8&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x18&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;s2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;저장 레지스터&lt;&#x2F;td&gt;&lt;td&gt;Callee&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x19&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;s3&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;저장 레지스터&lt;&#x2F;td&gt;&lt;td&gt;Callee&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x20&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;s4&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;저장 레지스터&lt;&#x2F;td&gt;&lt;td&gt;Callee&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x21&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;s5&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;저장 레지스터&lt;&#x2F;td&gt;&lt;td&gt;Callee&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x22&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;s6&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;저장 레지스터&lt;&#x2F;td&gt;&lt;td&gt;Callee&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x23&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;s7&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;저장 레지스터&lt;&#x2F;td&gt;&lt;td&gt;Callee&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x24&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;s8&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;저장 레지스터&lt;&#x2F;td&gt;&lt;td&gt;Callee&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x25&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;s9&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;저장 레지스터&lt;&#x2F;td&gt;&lt;td&gt;Callee&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x26&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;s10&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;저장 레지스터&lt;&#x2F;td&gt;&lt;td&gt;Callee&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x27&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;s11&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;저장 레지스터&lt;&#x2F;td&gt;&lt;td&gt;Callee&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x28&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;t3&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;임시 레지스터&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x29&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;t4&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;임시 레지스터&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x30&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;t5&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;임시 레지스터&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x31&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;t6&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;임시 레지스터&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
</description>
      </item>
      <item>
          <title>CSED311: Computer Architecture</title>
          <pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://zlfn.space/blog/series-csed311/</link>
          <guid>https://zlfn.space/blog/series-csed311/</guid>
          <description xml:base="https://zlfn.space/blog/series-csed311/">&lt;p&gt;포항공과대학교 CSED 311 컴퓨터 구조 수업의 내용을 기반으로 정리한 시리즈입니다.&lt;&#x2F;p&gt;
&lt;p&gt;수업에서 다루지 않은 몇몇 내용을 추가하여 구성하였습니다.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>B-Tree, B+Tree</title>
          <pubDate>Sun, 26 May 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://zlfn.space/blog/b-tree/</link>
          <guid>https://zlfn.space/blog/b-tree/</guid>
          <description xml:base="https://zlfn.space/blog/b-tree/">&lt;p&gt;B-Tree, B+Tree와 자기 균형 이진 트리&lt;sub&gt;Self-Balanced Binary Tree&lt;&#x2F;sub&gt;와의 차이점을 알아본 다음, B-Tree에서 탐색, 삽입, 삭제 과정을 알아보겠습니다.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;이 내용은 포항공과대학교의 CSED 233의 내용을 기반으로 하며, 수업과 차이가 있는 부분은 &lt;em&gt;기울임체&lt;&#x2F;em&gt;로 별도 명시하였습니다.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;b-tree&quot;&gt;B-Tree&lt;&#x2F;h2&gt;
&lt;p&gt;B-Tree는 디스크 상에서 활용될 목적으로 개발된 탐색 트리의 일종입니다. 기본적인 아이디어는 이진 탐색 트리 하나의 노드에 여러 개의 데이터를 저장하는 것인데, 이러면 기본적인 속도는 Red-Black Tree 등 기존 이진 탐색 트리에 비해 느려지지만, 자료의 임의 접근&lt;sub&gt;Random Access&lt;&#x2F;sub&gt; (자료의 주소로 자료를 탐색) 과정과 자기 균형 횟수를 크게 줄일 수 있습니다.
HDD나 SSD 등의 디스크 드라이브는 자료의 임의 접근과 쓰기 속도가 굉장히 느린 대신, 순차 접근&lt;sub&gt;Sequential Access&lt;&#x2F;sub&gt; 속도는 비교적 빠르기 때문에 디스크에 저장되는 데이터들을 다루는 DBMS나 File System에서 주로 활용하는 자료구조입니다.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;디스크 드라이브 이외에도 &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dl.acm.org&#x2F;doi&#x2F;10.1145&#x2F;342009.335449&quot;&gt;메인 메모리&lt;&#x2F;a&gt;나 &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;link.springer.com&#x2F;chapter&#x2F;10.1007&#x2F;978-3-642-33615-7_27&quot;&gt;GPGPU&lt;&#x2F;a&gt; 등 cache-conscious indexing이 필요한 다양한 상황에서 B-Tree를 이용할 수 있는 듯 합니다.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;probs&quot;&gt;Probs&lt;&#x2F;h3&gt;
&lt;p&gt;자기 균형 이진 트리와 비교해서는 선술하였듯, 자료의 임의 접근과 자기 균형 횟수를 줄여서 디스크에서 더 효율적이라는 장점이 있습니다.&lt;&#x2F;p&gt;
&lt;p&gt;정렬된 배열&lt;sub&gt;Sorted Array&lt;&#x2F;sub&gt;도 디스크에서 순차 접근이 용이하므로 사용할 수 있지만, B-Tree는 차지하는 디스크 공간이 약간 더 큰 대신 배열보다 업데이트가 빠르고 (전체 배열에서 정렬하는 것보다 트리 노드 내에서 정렬하는 것이 빠르므로) 데이터 탐색이 빠르다는 장점이 있습니다.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;b-tree-of-order-m&quot;&gt;B-Tree of order m&lt;&#x2F;h2&gt;
&lt;p&gt;m진 탐색 트리는 아래와 같은 조건을 만족해야 합니다.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;루트 노드는 최소 2개의 자식 노드를 가집니다.&lt;&#x2F;li&gt;
&lt;li&gt;루트 노드와 리프 노드를 제외한 중간 노드&lt;sub&gt;internal nodes&lt;&#x2F;sub&gt;는 최소 $\lceil x&#x2F;2 \rceil$ 개의 자식 노드를 가집니다.&lt;&#x2F;li&gt;
&lt;li&gt;모든 리프 노드는 같은 레벨에 있습니다.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;아래는 4진 B-Tree의 예시입니다.
&lt;img src=&quot;https:&#x2F;&#x2F;zlfn.space&#x2F;blog&#x2F;b-tree&#x2F;IMG_0344.png&quot; alt=&quot;IMG_0344&quot; title=&quot;IMG_0344&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;탐색 트리이므로 아래와 같은 조건도 만족합니다.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;첫 번째 서브 트리의 키는 첫 번째 키보다 작아야 합니다.&lt;&#x2F;li&gt;
&lt;li&gt;N+1 번째 서브 트리의 키는 N 번째 키 이상이고, N+1 번째 키보다 작아야 합니다.&lt;&#x2F;li&gt;
&lt;li&gt;마지막 서브 트리의 키는 마지막 키 이상이어야 합니다.
&lt;img src=&quot;https:&#x2F;&#x2F;zlfn.space&#x2F;blog&#x2F;b-tree&#x2F;IMG_0343.png&quot; alt=&quot;IMG_0343&quot; title=&quot;IMG_0343&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;analysis&quot;&gt;Analysis&lt;&#x2F;h3&gt;
&lt;p&gt;B-Tree의 삽입, 삭제, 검색 연산은 $O(log_m,n)$에 수행할 수 있습니다. 이때 $m$은 트리의 평균 가지 수&lt;sub&gt;branching factor&lt;&#x2F;sub&gt;가 됩니다.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h3&gt;
&lt;p&gt;B-Tree는 주로 디스크에서 구현한다고 했는데, 보통 한 노드가 하나의 디스크 블록을 차지하게 구현합니다. 여기서 블록은 메인 메모리와 디스크가 주고 받는 데이터의 단위입니다. &lt;em&gt;수업에서는 파일에 최대로 할당할 수 있는 연속적인 디스크 공간 이라고 설명했습니다.&lt;&#x2F;em&gt;&lt;br &#x2F;&gt;
디스크의 데이터는 블록 단위로 한 번에 메모리로 불러 들여올 수 있기 때문에, 블록 단위로 노드를 구성하는 것이 가장 적합합니다.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;b-tree-1&quot;&gt;B+Tree&lt;&#x2F;h2&gt;
&lt;p&gt;B+Tree는 B-Tree와 비슷하되, 실제 데이터는 리프노드에만 저장하고, 루트노드와 중간노드에는 키만 저장하는 방식입니다. 데이터가 리프노드에만 저장되기 때문에 중복된 키도 허용됩니다. &lt;em&gt;추가로, 각 리프노드에 형제노드&lt;sub&gt;Sibling&lt;&#x2F;sub&gt;으로 가는 포인터를 주어 모든 데이터를 순회하는 것을 효율적으로 만듭니다.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;B-Tree와 비교해서 메모리 사용량과 요구 디스크 공간이 약간 커지는 단점이 있으나, 데이터의 순차 검색 성능이 매우 좋아집니다.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;NTFS, XFS, JFS2 FileSystem과 MySQL 등 관계형 데이터베이스 테이블의 인덱싱에 B+Tree를 이용합니다&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;b-tree-2&quot;&gt;B*Tree&lt;&#x2F;h3&gt;
&lt;p&gt;B*Tree는 노드의 생성 최소화를 위하여 B+Tree에서 몇 가지의 제약 조건을 추가한 자료구조입니다. 자식 노드 수의 최소 개수는 $\lceil 2M&#x2F;3 \rceil$개로 늘어나고, 노드가 가득 차면 노드 분할을 진행하는 B+Tree와 달리 형제 노드로 재배치를 우선적으로 진행합니다.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;2-3-tree&quot;&gt;2-3 Tree&lt;&#x2F;h2&gt;
&lt;p&gt;2-3 Tree는 B-Tree의 특수한 경우입니다. 3진 트리로서 모든 중간노드가 2~3개의 자식노드를 가지며, 마찬가지로 모든 리프노드는 같은 레벨에 정렬됩니다.&lt;&#x2F;p&gt;
&lt;p&gt;실제로 자주 쓰이는 형태는 아니지만, 2-3 Tree의 경우 B-Tree의 기본 연산들을 설명하기 쉽기 때문에 이런 형태를 가정합니다.&lt;&#x2F;p&gt;
&lt;p&gt;B-Tree로도 2-3 Tree를 구현할 수 있지만, B+Tree의 형태로 2-3 Tree를 구현한다고 생각하고 아래 설명을 진행하겠습니다.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;search&quot;&gt;Search&lt;&#x2F;h3&gt;
&lt;p&gt;탐색은 이진 탐색 트리와 유사하게 하면 됩니다. 2개의 노드와 키 값을 비교하여 왼쪽 자식노드, 중간 자식노드, 오른쪽 자식노드 중 하나를 선택하면서 내려가는 과정을 반복하면 됩니다. 시간 복잡도는 $O(log_3,n)$ 입니다.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;insert&quot;&gt;Insert&lt;&#x2F;h3&gt;
&lt;p&gt;삽입은 우선 데이터가 들어갈 노드를 찾는 것으로 시작합니다. 이때 노드에 빈 공간이 있는 경우와 없는 경우로 구분할 수 있는데, 노드에 빈 공간이 있는 경우는 그냥 그 자리에 데이터를 넣으면 됩니다.&lt;&#x2F;p&gt;
&lt;p&gt;노드에 빈 공간이 없는 경우에는 새로운 노드를 만들어 데이터를 삽입한 다음 균형을 맞춥니다.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;delete&quot;&gt;Delete&lt;&#x2F;h3&gt;
&lt;p&gt;제거도 우선 데이터가 있는 노드를 찾는 것으로 시작합니다. 이때는 노드에 자식이 3개 있는 경우와 2개 밖에 없는 경우로 나누게 되는데, 3개 있는 경우는 그냥 없애면 되지만, 2개 있는 경우는 하나를 삭제해 버리면 B-Tree의 구조 조건 중 하나인 최소 $\lceil x&#x2F;2 \rceil$ 개의 자식 노드 (2-3 Tree에서는 2개)를 충족하지 못하게 됩니다.&lt;&#x2F;p&gt;
&lt;p&gt;따라서 이 경우 형제노드의 남는 데이터를 끌어오거나 (형제노드의 자식이 3개인 경우)  값을 형재노드로 재위치시킨 후, 노드를 삭제하는 방법으로 데이터를 삭제합니다. (형제노드의 자식이 2개인 경우)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference&quot;&gt;Reference&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;POSTECH CSED 233 : Data Structure&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.quora.com&#x2F;Why-is-BTree-used-in-DBMS-not-BST-or-AVL&quot;&gt;https:&#x2F;&#x2F;www.quora.com&#x2F;Why-is-BTree-used-in-DBMS-not-BST-or-AVL&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;yeongjaekong.tistory.com&#x2F;38&quot;&gt;https:&#x2F;&#x2F;yeongjaekong.tistory.com&#x2F;38&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ko.wikipedia.org&#x2F;wiki&#x2F;B%2B_%ED%8A%B8%EB%A6%AC&quot;&gt;https:&#x2F;&#x2F;ko.wikipedia.org&#x2F;wiki&#x2F;B%2B_%ED%8A%B8%EB%A6%AC&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.quora.com&#x2F;When-duplicate-keys-are-allowed-in-a-B-tree-what-are-the-changes-of-some-algorithms-when-compared-to-the-B-tree-with-no-duplicate-keys&quot;&gt;https:&#x2F;&#x2F;www.quora.com&#x2F;When-duplicate-keys-are-allowed-in-a-B-tree-what-are-the-changes-of-some-algorithms-when-compared-to-the-B-tree-with-no-duplicate-keys&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>CSED233: Data Structure</title>
          <pubDate>Sun, 26 May 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://zlfn.space/blog/series-csed233/</link>
          <guid>https://zlfn.space/blog/series-csed233/</guid>
          <description xml:base="https://zlfn.space/blog/series-csed233/">&lt;p&gt;포항공과대학교 CSED 233 자료구조 수업의 내용을 기반으로 정리한 시리즈입니다.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>딕셔너리와 맵, 해싱</title>
          <pubDate>Sat, 25 May 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://zlfn.space/blog/dictionary-and-hashing/</link>
          <guid>https://zlfn.space/blog/dictionary-and-hashing/</guid>
          <description xml:base="https://zlfn.space/blog/dictionary-and-hashing/">&lt;p&gt;본 글에서는 딕셔너리와 해싱을 알아보고, 각 언어의 구현을 알아보며 배운 내용을 체크해보려 합니다.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;이 내용은 포항공과대학교의 CSED 233의 내용을 기반으로 하며,&lt;br &#x2F;&gt;
수업에서 다루지 않은 내용은 인용문으로 표기하였거나 별도 명시하였으니 참고바랍니다.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;dictionary-adt&quot;&gt;Dictionary ADT&lt;&#x2F;h2&gt;
&lt;p&gt;딕셔너리는 추상 자료형&lt;sub&gt;Abstract Data Types&lt;&#x2F;sub&gt;의 일종으로, 특정 키에 대해 특정 원소가 매핑되는 짝의 집합으로 구성되어 있습니다.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;구현마다 다르긴 합니다만&lt;&#x2F;em&gt; 대체로 중복키는 허용되지 않습니다.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Map이라고도 불립니다. 다만 Map과 Dictionary를 다르게 정의하는 경우도 가끔 있습니다.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;fundamental-operations&quot;&gt;Fundamental Operations&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;x = (k : key, d : data)&lt;&#x2F;li&gt;
&lt;li&gt;Insert(x, &lt;em&gt;D&lt;&#x2F;em&gt;) : 삽입 연산&lt;&#x2F;li&gt;
&lt;li&gt;Delete(k, &lt;em&gt;D&lt;&#x2F;em&gt;) : 제거 연산&lt;&#x2F;li&gt;
&lt;li&gt;Search(k, &lt;em&gt;D&lt;&#x2F;em&gt;) : 조회&lt;sub&gt;Lookup&lt;&#x2F;sub&gt; 연산&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote&gt;
&lt;p&gt;딕셔너리는 무순사전&lt;sub&gt;Unordered Dictionary&lt;&#x2F;sub&gt;과 순서 사전&lt;sub&gt;Ordered Dictionary&lt;&#x2F;sub&gt;으로 구분됩니다.
무순사전은 요소를 임의의 순서로 집합에 추가하고, 순서사전은 요소를 key를 기준으로 하여 특정한 순서로 집합에 추가합니다. 많은 언어는 이 두 종류의 딕셔너리를 모두 구현체에 포함하고 있습니다.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;dictionary-implementations&quot;&gt;Dictionary Implementations&lt;&#x2F;h2&gt;
&lt;p&gt;딕셔너리를 구현하는 방법은 리스트, 해싱, 트리 세가지로 나눌 수 있습니다.&lt;br &#x2F;&gt;
각각의 구현이 key를 찾는 방법과 시간 복잡도는 아래와 같습니다.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Unsorted List&lt;&#x2F;strong&gt; : 리스트를 처음부터 끝까지 순회하며 key를 찾습니다 : $O(n)$&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Sorted List&lt;&#x2F;strong&gt; : 이진 탐색을 이용하여 key를 찾습니다 : $O(log,n)$&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Hash Table&lt;&#x2F;strong&gt; : key의 해시값을 이용하여 데이터에 직접 접근합니다 : 최악 $O(n)$, 평균 $O(1)$&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Binary Search Tree&lt;&#x2F;strong&gt; : 이진 탐색 트리를 이용하여 key를 정렬한 다음 찾습니다 : 최악 $O(n)$, 평균 $O(log,n)$&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Self-Balanced Binary Search Tree&lt;&#x2F;strong&gt; : AVL Tree나 Red-Black Tree 등으로 구현된 자기 균형 이진 탐색 트리에서는 : $O(log,n)$&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Unsorted List는 Python의 &lt;code&gt;OrderedDict&lt;&#x2F;code&gt; 구현에 사용되고, (Doubled Linked List를 이용해 들어간 순으로 정렬됩니다.)&lt;br &#x2F;&gt;
Binary Search Tree는 C++의 &lt;code&gt;map&lt;&#x2F;code&gt;, Rust의 &lt;code&gt;BTreeMap&lt;&#x2F;code&gt; 구현에 사용됩니다.&lt;br &#x2F;&gt;
이 글에서는 Hash Table 구현 위주로 설명하며, 다른 구현은 다루지 않습니다.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;hashing&quot;&gt;Hashing&lt;&#x2F;h2&gt;
&lt;p&gt;해싱을 이용해서 키를 해시 테이블의 특정 위치에 매핑합니다.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;생각해봐야 할 점&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;어떤 해시 함수를 사용할 것인가?&lt;&#x2F;li&gt;
&lt;li&gt;충돌을 어떻게 해결할 것인가?&lt;&#x2F;li&gt;
&lt;li&gt;해시 테이블의 크기는 어떻게 할 것인가?&lt;&#x2F;li&gt;
&lt;li&gt;해시 테이블이 꽉 차면 어떻게 할 것인가?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;hash-function&quot;&gt;Hash Function&lt;&#x2F;h2&gt;
&lt;p&gt;해시 함수는 충돌을 최소화하고, 계산이 빨리 끝나는 것이 좋은 해시함수가 됩니다. 해시 테이블의 사용에서 대부분의 경우 들어오는 키가 밀집되어&lt;sub&gt;highly clusted&lt;&#x2F;sub&gt; 있기 때문에, 이를 분산하는 것은 해시 함수의 중요한 역할입니다.&lt;&#x2F;p&gt;
&lt;p&gt;우선 해시 함수는 키가 정수가 아닌 경우 특정 정수로 변환하고, 정수를 해시 테이블의 범위의 맞는 수로 변환하여 분산시킵니다.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;division&quot;&gt;Division&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; hash&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;%&lt;&#x2F;span&gt;&lt;span&gt; M&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;정수를 해시 테이블의 크기 M으로 나누면 해시된 값이 항상 해시 테이블 내부에 있음을 보장할 수 있습니다.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;choice-of-m&quot;&gt;Choice of M&lt;&#x2F;h4&gt;
&lt;p&gt;만약 Divisor M이 짝수 값이라면, Hash Table 상의 가능한 모든 해시값을 만들 수 없습니다. 따라서 짝수 값 M을 사용해서는 안됩니다.&lt;br &#x2F;&gt;
만약 m=6이고 들어오는 값이 모두 짝수일 때 :&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0 =&amp;gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2 =&amp;gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4 =&amp;gt; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6 =&amp;gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8 =&amp;gt; 2...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;홀수 M에서는 그런 문제가 덜 발생하나, 여전히 같은 문제로 해시 테이블이 낭비될 가능성이 있습니다.&lt;br &#x2F;&gt;
만약 m=9=3*3이고 들어오는 값이 모두 3의 배수일 때 :&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3 =&amp;gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6 =&amp;gt; 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;9 =&amp;gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;12 =&amp;gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;15 =&amp;gt; 6...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;따라서, &lt;strong&gt;작은 소인수가 없는&lt;&#x2F;strong&gt; 임의의 수나 소수로 M을 선정하는 것이 가장 적합합니다.&lt;&#x2F;p&gt;
&lt;p&gt;예를 들면, 713=23 * 31은 들어오는 값이 23의 배수, 31의 배수가 아닌 경우 균일한 해시 값을 냅니다. 23의 배수, 31의 배수인 경우는 2의 배수, 3의 배수인 경우보다 훨씬 드문 경우이므로 나쁘지 않은 M 값이라고 할 수 있겠습니다.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;string-folding&quot;&gt;String Folding&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; hash&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; sum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;char&lt;&#x2F;span&gt;&lt;span&gt; c &lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        sum &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; sum &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;%&lt;&#x2F;span&gt;&lt;span&gt; M&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;만약 들어오는 값이 정수가 아닌 문자열인 경우 문자열을 접어서&lt;sub&gt;Folding&lt;&#x2F;sub&gt; 특정 정수로 만들 수 있습니다.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;mid-square&quot;&gt;Mid-Square&lt;&#x2F;h3&gt;
&lt;p&gt;키 값을 제곱하여 중간 자리 숫자만을 선택하여 해시 테이블의 인덱스로 사용하는 방식입니다. 제곱 결과는 키 값의 모든 자릿수의 영향을 받기 때문에, 키 값이 밀집되어 있더라도 분산된 해시 결과 값을 낼 확률이 높습니다.&lt;&#x2F;p&gt;
&lt;p&gt;십진수로 예를 들겠습니다. 4567을 제곱하면 20857489가 되는데, 이 중 중간 2자리인 &lt;code&gt;57&lt;&#x2F;code&gt;을 인덱스로 사용한다고 해봅시다. 이때 4568을 제곱하면 20866624가 되는데, 인덱스는 &lt;code&gt;66&lt;&#x2F;code&gt;이 됩니다. 키 값은 한 자리 차이이나 해시값은 전혀 다르게 나온 것을 알 수 있습니다.&lt;&#x2F;p&gt;
&lt;p&gt;보통은 2진수 값을 사용하기 때문에 중간 r비트를 추출하여 0~$2^r-1$ 사이의 값이 나오게 됩니다.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;types-of-hashing&quot;&gt;Types of Hashing&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;static-hashing&quot;&gt;Static Hashing&lt;&#x2F;h3&gt;
&lt;p&gt;정적 해싱&lt;sub&gt;Static Hashing&lt;&#x2F;sub&gt;은 해시 테이블의 크기를 고정하여 해싱하는 방법입니다. 충돌하는 키를 다루는 방법에 따라 다시 &lt;strong&gt;Open Hashing&lt;&#x2F;strong&gt;이나 &lt;strong&gt;Closed Hashing&lt;&#x2F;strong&gt;으로 나뉘게 됩니다.
데이터의 사이즈가 커질수록 성능이 크게 감소하는 단점이 있습니다.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;open-hashing&quot;&gt;Open Hashing&lt;&#x2F;h4&gt;
&lt;p&gt;오픈 해싱 (Seperate Chaning이라고도 불림)은 충돌이 발생할 경우 연결 리스트 등을 이용해 여러 개의 키-데이터를 해시 테이블 인덱스 하나에 보관하는 방법입니다.&lt;br &#x2F;&gt;
충돌이 다수 발생하여 하나의 인덱스에 너무 많은 데이터가 보관될 경우 조회가 느려지게 됩니다.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;closed-hashing&quot;&gt;Closed Hashing&lt;&#x2F;h4&gt;
&lt;p&gt;폐쇄 해싱은 오픈 해싱과 다르게 충돌을 피하고 하나의 해시 테이블 인덱스에는 하나의 값만 보관하는 방법입니다. &lt;strong&gt;Bucket Hashing&lt;&#x2F;strong&gt;과 &lt;strong&gt;Rehashing&lt;&#x2F;strong&gt; 두가지 방법이 있습니다.&lt;&#x2F;p&gt;
&lt;p&gt;폐쇄해싱의 경우 충돌이 발생하면 데이터를 원래 있어야 할 곳이 아닌 다른 곳에 보관하기 때문에, 데이터를 삭제할 경우 삭제되었다는 흔적을 남겨주어야 충돌해서 다른 곳에 가버린 데이터를 검색할 수 있습니다.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;bucket-hashing&quot;&gt;Bucket Hashing&lt;&#x2F;h5&gt;
&lt;p&gt;해시 테이블의 슬롯을 일정 크기의 버킷으로 나누어서 (즉, 하나의 해시 값에 여러 인덱스를 할당하여) 충돌이 발생하여도 다음 인덱스를 채우는 방법입니다. 이 방법을 사용하여도 버킷이 가득 차면 오버플로우가 발생하게 되는데, 슬롯이 가득 찬 인덱스를 검색하는 Overflow Bucket을 따로 만들어서 문제를 해결할 수 있습니다.&lt;&#x2F;p&gt;
&lt;p&gt;마찬가지로 충돌이 발생할 경우 점점 속도가 느려지며, 특히 Overflow Bucket은 $O(n)$으로 검색되기 때문에 오버플로우가 자주 발생할 경우 조회가 느려지게 됩니다.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;rehashing&quot;&gt;Rehashing&lt;&#x2F;h5&gt;
&lt;p&gt;충돌이 발생하면 다시 해싱하는 방법입니다. Open Addressing이라고도 불립니다. 원래 키 값에 Probe 함수의 값을 더해서 다른 인덱스를 만들어내게 됩니다.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Linear Probing&lt;&#x2F;strong&gt;: 충돌이 발생할 때마다 키 값을 1씩 증가시킵니다. 이 경우 들어오는 키 값이 밀집되어 있는 경우 1차 군집화&lt;sub&gt;Primary Clustering&lt;&#x2F;sub&gt; 문제가 발생하여 비어있는 공간의 탐색에 시간이 오래 걸리게 됩니다. (5, 6, 7, 8 키가 이미 들어간 상태에서 4가 들어간다고 생각해보면 4, 5, 6, 7, 8, 9을 모두 해싱해보아야 빈 공간을 찾을 수 있을 것입니다.)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Pseudo-Random Probing&lt;&#x2F;strong&gt; : 충돌이 발생할 때 마다 키 값을 임의의 순열 값으로 증가시킵니다. 보통 Shift-Register Sequence가 사용되는데, 충돌이 발생할 때 마다 키 값을 Shift하고 (2배 하고) 특정 값과 XOR하는 방법입니다.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Quadratic Probing&lt;&#x2F;strong&gt; : 임의의 다항식을 이용하여 키 값을 증가시킵니다. 보통 제곱 값을 이용해서 k+1, k+4, k+9... 순으로 찾게 됩니다.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Secondary Clustering&lt;&#x2F;strong&gt; : 2차 군집화는 &lt;strong&gt;Pseudo-Random&lt;&#x2F;strong&gt;이나 &lt;strong&gt;Quadratic&lt;&#x2F;strong&gt; 프로빙을 이용하더라도 초기 해시값이 같은 키의 경우 다음 해시값도 계속 일치하는 문제입니다. 이 경우 동일한 해시 값을 가진 키가 여러 번 들어오면 점점 조회가 느려지게 됩니다.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Double Hashing&lt;&#x2F;strong&gt; : 이 경우 이중 해싱을 이용해서 문제를 해결합니다. 탐색을 위해 서로 다른 두개의 해시 함수를 이용하는 방법입니다.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;dynamic-hashing&quot;&gt;Dynamic Hashing&lt;&#x2F;h3&gt;
&lt;p&gt;동적 해싱&lt;sub&gt;Dynamic Hashing&lt;&#x2F;sub&gt;은 데이터의 증가에 따라 해시 테이블의 크기를 늘려 해싱하는 방법입니다. &lt;em&gt;수업에서는 다루지 않았습니다.&lt;&#x2F;em&gt;
데이터 증감에 따라서 해시함수가 동적으로 변환되며, 해시테이블 버킷의 수가 고정되지 않고 필요할 때마다 늘거나 줄어듭니다.&lt;br &#x2F;&gt;
주로 다루는 데이터 크기가 매우 큰 DBMS에서 이런 방식을 사용합니다.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;extendible-hashing&quot;&gt;Extendible Hashing&lt;&#x2F;h4&gt;
&lt;p&gt;확장성 해싱은 동적 해싱에서 가장 많이 사용하는 방법으로, 이중구조로 딕셔너리를 만드는 방법입니다. 키를 비트 스트링으로 변환하고, 비트 스트링의 처음 몇 비트를 디렉토리라는 배열의 인덱스로 사용합니다.
디렉토리는 다시 버킷들의 포인터를 가지는데, 이 버킷에 데이터를 저장합니다. 만약 버킷에 오버플로우가 발생하면 버킷을 분할하여 공간을 늘립니다.&lt;&#x2F;p&gt;
&lt;p&gt;데이터의 크기가 커지더라도 디스크 접근 횟수가 늘어나지 않으나, 데이터의 숫자가 적을 경우 오히려 비효율적이라는 단점이 있습니다.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hashmap-implementation&quot;&gt;HashMap Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;각 언어의 해시맵 구현 방법을 알아보겠습니다. 마찬가지로 &lt;em&gt;수업에서는 다루지 않았습니다.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;c-unordered-map&quot;&gt;C++ : unordered_map&lt;&#x2F;h3&gt;
&lt;p&gt;C++의 해시맵인 unordered_map은 우선 기본적인 Division Hashing을 이용하여 Linked List 버킷에 데이터를 저장합니다. 이때 &lt;code&gt;load_factor&lt;&#x2F;code&gt;라는 값이 변경되는데, 이는 &lt;code&gt;입력된 데이터의 개수 &#x2F; 버킷의 총 개수&lt;&#x2F;code&gt;를 의미합니다.&lt;&#x2F;p&gt;
&lt;p&gt;만약 이 &lt;code&gt;load_factor&lt;&#x2F;code&gt;가 &lt;code&gt;max_load_factor&lt;&#x2F;code&gt; (기본적으로 1.0)를 넘어서면 전체 버킷의 개수를 증가시키고, 전체 데이터를 새로운 &lt;code&gt;bucket_count&lt;&#x2F;code&gt;로 재해싱합니다.&lt;&#x2F;p&gt;
&lt;p&gt;이때 어떤 값으로 &lt;code&gt;bucket_count&lt;&#x2F;code&gt;를 증가시킬지는 Undefined Behavior입니다. 각 컴파일러마다 다른 값을 사용하는데, GCC와 Clang은 소수를, MSVC는 2의 제곱에서 1을 뺀 값을 이용한다고 합니다.&lt;&#x2F;p&gt;
&lt;p&gt;아래 프로그램을 통해 대략적인 구조를 확인해볼 수 있습니다.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; main&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        unordered_map&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; map&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F9E2AF;&quot;&gt;        std&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;cout &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; map&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;bucket_count&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;&quot;&gt; std&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;endl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;--&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                map&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;insert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;make_pair&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F9E2AF;&quot;&gt;                std&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;cout &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; map&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;bucket_count&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;&quot;&gt; std&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;endl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;                for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;auto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; x &lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; map&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                        cout &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &amp;quot;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;first&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &amp;quot;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;second&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &amp;quot;)&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                        cout &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &amp;quot; is in bucket= &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; map&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;bucket&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;first&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; endl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;모듈로 연산만을 이용하기 때문에, C++의 unordered_map은 &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codingdog.tistory.com&#x2F;entry&#x2F;c-unorderedmap-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%B5%9C%EC%95%85%EC%9D%98-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%A5%BC-%EB%A7%8C%EB%93%A4%EA%B9%8C&quot;&gt;저격 데이터를 만들기가 쉽다는 문제가 있습니다.&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;python-dictionary&quot;&gt;Python : Dictionary&lt;&#x2F;h3&gt;
&lt;p&gt;파이썬은 딕셔너리가 표준 라이브러리가 아닌 언어의 기본 기능으로 내장되어 있는데, Rehashing, 그중에서도 Linear Probing을 기본적으로 사용하고, 그 외에는 C++의 구현과 비슷하게 load_factor를 이용하여 일정 수준 이상일 경우 해시테이블의 크기를 증가시킵니다.&lt;br &#x2F;&gt;
다만 Linear Probing은 Primary Clustrering에 매우 취약하기 때문에, 기본 load_factor가 1.0인 C++과 다르게 0.75를 기본 값으로 사용한다고 합니다.&lt;&#x2F;p&gt;
&lt;p&gt;앞서 C++은 저격 데이터를 만들기가 상당히 쉽다고 말했는데, 이렇게 저격 데이터를 만들어서 해시맵의 용량과 CPU 사용량을 늘리는 것을 HashDoS 공격이라고 합니다. HashDoS 공격을 당한 서버는 갑자기 프로세서 사용량이 폭증하여 요청을 정상적으로 처리할 수 없게 됩니다.&lt;&#x2F;p&gt;
&lt;p&gt;따라서 Python은 3.4 정도 버전부터 HashDoS 공격을 방어하기 위해 &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;SipHash&quot;&gt;SipHash&lt;&#x2F;a&gt; 알고리즘을 이용합니다. 자세한 내용은 여기서 설명하지 않겠지만, 임의의 난수를 통해 데이터를 해싱하여 임의로 해시값을 중복시키는 것을 어렵게 만드는 알고리즘입니다. Pseudo-Random Hashing의 일종으로 보면 될 것 같습니다.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rust-hashmap&quot;&gt;Rust : HashMap&lt;&#x2F;h3&gt;
&lt;p&gt;Rust도 기본적으로 &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;SipHash&quot;&gt;SipHash&lt;&#x2F;a&gt; 알고리즘을 이용합니다.&lt;&#x2F;p&gt;
&lt;p&gt;해시 테이블의 구현은 &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;abseil.io&#x2F;about&#x2F;design&#x2F;swisstables&quot;&gt;SwissTable&lt;&#x2F;a&gt;의 Rust 포팅 버전을 이용하는데, 마찬가지로 많이 복잡하여 자세한 내용은 설명하지 않지만, SIMD를 활용하여 최적화한 Open Addressing 해시 테이블이라고 생각하면 될 듯 합니다.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference&quot;&gt;Reference&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;POSTECH: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;plms.postech.ac.kr&#x2F;local&#x2F;ubion&#x2F;course&#x2F;syllabusV.php?id=9392&quot;&gt;CSED 233 Data Structure&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;skyil.tistory.com&#x2F;117&quot;&gt;https:&#x2F;&#x2F;skyil.tistory.com&#x2F;117&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;34496582&#x2F;is-ordereddict-a-tree&quot;&gt;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;34496582&#x2F;is-ordereddict-a-tree&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;9456790&#x2F;why-are-composite-numbers-bad-for-hashing-by-division&quot;&gt;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;9456790&#x2F;why-are-composite-numbers-bad-for-hashing-by-division&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;m.blog.naver.com&#x2F;beaqon&#x2F;221300416700&quot;&gt;https:&#x2F;&#x2F;m.blog.naver.com&#x2F;beaqon&#x2F;221300416700&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;growth-coder.tistory.com&#x2F;16&quot;&gt;https:&#x2F;&#x2F;growth-coder.tistory.com&#x2F;16&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;31112852&#x2F;how-stdunordered-map-is-implemented&quot;&gt;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;31112852&#x2F;how-stdunordered-map-is-implemented&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;charsyam.wordpress.com&#x2F;2018&#x2F;02&#x2F;04&#x2F;%EC%9E%85-%EA%B0%9C%EB%B0%9C-siphash%EC%9D%98-%EC%82%AC%EC%9A%A9-data-ddos%EB%A5%BC-%EB%B0%A9%EC%A7%80%ED%95%B4%EB%B3%BC%EA%B9%8C&#x2F;&quot;&gt;https:&#x2F;&#x2F;charsyam.wordpress.com&#x2F;2018&#x2F;02&#x2F;04&#x2F;%EC%9E%85-%EA%B0%9C%EB%B0%9C-siphash%EC%9D%98-%EC%82%AC%EC%9A%A9-data-ddos%EB%A5%BC-%EB%B0%A9%EC%A7%80%ED%95%B4%EB%B3%BC%EA%B9%8C&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;collections&#x2F;struct.HashMap.html&quot;&gt;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;collections&#x2F;struct.HashMap.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;faultlore.com&#x2F;blah&#x2F;hashbrown-tldr&#x2F;&quot;&gt;https:&#x2F;&#x2F;faultlore.com&#x2F;blah&#x2F;hashbrown-tldr&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>트리 리루팅 (전방향 트리 DP)</title>
          <pubDate>Fri, 12 Apr 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://zlfn.space/blog/rerooting/</link>
          <guid>https://zlfn.space/blog/rerooting/</guid>
          <description xml:base="https://zlfn.space/blog/rerooting/">&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;atcoder.jp&#x2F;contests&#x2F;abc348&quot;&gt;엣코더 ABC #348&lt;&#x2F;a&gt;의 &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;atcoder.jp&#x2F;contests&#x2F;abc348&#x2F;tasks&#x2F;abc348_e&quot;&gt;E - Minimize Sum of Distance&lt;&#x2F;a&gt; 에서 트리 DP, 그중에서도 전방향 트리(&lt;ruby&gt;全方位木&lt;rp&gt;（&lt;&#x2F;rp&gt;&lt;rt&gt;ぜん ほうい き&lt;&#x2F;rt&gt;&lt;rp&gt;）&lt;&#x2F;rp&gt;&lt;&#x2F;ruby&gt;) DP를 쓴다고 해서 찾아봤습니다.&lt;&#x2F;p&gt;
&lt;p&gt;이 알고리즘은 일본 외에서는 &lt;strong&gt;Rerooting&lt;&#x2F;strong&gt; 이라고 불리며, 루트가 정해지지 않은 트리에서 조건에 맞는 루트를 구할 때 유용하게 사용할 수 있는 테크닉입니다. 한국에서는 트리에서의 다이나믹 프로그래밍 분류의 일종으로 취급되지만, 외국에서는 이름을 따 붙힐 정도로 경쟁적 프로그래밍에서 은근 자주 출제되는 알고리즘인 듯 합니다.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gaenyeom&quot;&gt;개념&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;teuri-dfs&quot;&gt;트리 DFS&lt;&#x2F;h3&gt;
&lt;p&gt;우선 특정 노드에 대해서 &lt;strong&gt;다른 노드까지 가는 간선 비용의 총합&lt;&#x2F;strong&gt;을 구하는 방법을 생각해 봅시다. 이는 DFS+DP를 통해 $O(n)$으로 구현할 수 있습니다.
&lt;img src=&quot;https:&#x2F;&#x2F;zlfn.space&#x2F;blog&#x2F;rerooting&#x2F;IMG_0140.png&quot; alt=&quot;IMG_0140&quot; title=&quot;IMG_0140&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;riruting&quot;&gt;리루팅&lt;&#x2F;h3&gt;
&lt;p&gt;그렇다면 &lt;strong&gt;다른 노드까지 가는 간선 비용의 총합이 가장 작은&lt;&#x2F;strong&gt; 노드는 어떻게 구할 수 있을까요? 위에 설명한 트리 DFS를 노드의 개수만큼 사용하면 되겠지만, 그렇다면 $O(n^2)$이 소요되어 정점이 $10^5$개만 넘어가면 시간초과가 날 것입니다.&lt;br &#x2F;&gt;
바로 이때 &lt;strong&gt;리루팅 테크닉&lt;&#x2F;strong&gt;을 사용합니다. DFS+DP트리의 루트를 옮기는 것은 $O(1)$에 가능하다는 것을 이용하는 테크닉입니다.&lt;&#x2F;p&gt;
&lt;p&gt;위 그림에서, A노드의 총 거리합인 30을 이용해서 B노드의 총 거리합을 구해봅시다. A노드와 그 너머에 있는 A(0), C(3), F(7) 노드의 거리는 A-B 간선의 비용 5만큼 증가해서, A(5), C(8), F(12)가 될 것이고, B노드와 그 아래에 있는 B(5), D(8), E(7) 노드의 거리는 A-B 간선의 비용 5만큼 감소해서 B(0), D(3), E(2)가 될 것입니다. A노드의 증가분과 B노드의 감소분은 서로 상쇄되니까&lt;br &#x2F;&gt;
즉, &lt;code&gt;(A의 총 거리합) - {(A노드 너머 노드 수) - (B노드 아래 노드 수)} * (A-B 간선의 비용)}&lt;&#x2F;code&gt;이 B노드의 총 거리합이 되는 거죠.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;zlfn.space&#x2F;blog&#x2F;rerooting&#x2F;IMG_0141.png&quot; alt=&quot;IMG_0141&quot; title=&quot;IMG_0141&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;이 방법을 이용해서 A노드의 총 거리합을 알 때, B노드의 총 거리합을 $O(1)$에 구할 수 있습니다.&lt;br &#x2F;&gt;
이 테크닉을 루트를 옮기다고 생각하면 리루팅 테크닉이고, 양방향으로 검색하며 DFS를 돌린다고 생각하면 전방향트리 DP라는 이름이 됩니다. 알고리즘이 대부분 그렇듯 이름은 별로 중요하지 않습니다.&lt;&#x2F;p&gt;
&lt;p&gt;여기서 A노드 너머 노드 수와 B노드 아래 노드 수는 A의 총 거리합을 구하는 첫 DFS를 할 때, &lt;strong&gt;서브노드의 개수를 함께 저장&lt;&#x2F;strong&gt;해두면 구할 수 있습니다. 위의 예시로 들면, &lt;code&gt;A의 서브노드 개수&lt;&#x2F;code&gt; - &lt;code&gt;B의 서브노드 개수&lt;&#x2F;code&gt;가 A 너머의 노드 수가 되겠고, &lt;code&gt;B의 서브노드 개수&lt;&#x2F;code&gt;가 그대로 B노드 아래 노드 수가 되겠네요.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;yeje&quot;&gt;예제&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;boj-27730-gyeonuwa-jignyeo&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.acmicpc.net&#x2F;problem&#x2F;27730&quot;&gt;BOJ 27730 : 견우와 직녀&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;위 예제를 그대로 적용할 수 있는 문제입니다.  트리 두 개에 대해서 시행하고, 양 쪽에서 거리합이 가장 작은 노드를 출력하면 됩니다.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;boj-7812-jungang-teuri&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.acmicpc.net&#x2F;problem&#x2F;7812&quot;&gt;BOJ 7812 : 중앙 트리&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;중앙 노드를 리루팅을 이용해 구한 다음, 다시 DFS를 돌려서 모든 노드에서의 거리를 출력하면 됩니다.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;abc-348-e&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;atcoder.jp&#x2F;contests&#x2F;abc348&#x2F;tasks&#x2F;abc348_e&quot;&gt;ABC#348 E&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;제가 리루팅 테크닉이라는 이름을 처음 알게 된 문제인데, 간선의 비용이 아닌 &lt;strong&gt;정점의 비용&lt;&#x2F;strong&gt;이 주어집니다.
즉, &lt;code&gt;(해당 정점으로 가는데 필요한 간선 수) * (정점의 비용)&lt;&#x2F;code&gt;이 간선의 비용이 됩니다.&lt;br &#x2F;&gt;
이 문제는 정점의 비용 합 &lt;code&gt;c[x]&lt;&#x2F;code&gt;와 거리 합&lt;code&gt;c[x]*d&lt;&#x2F;code&gt;를 모두 기억하면서 해결하면 됩니다.
정리한 정해 코드는 아래와 같고, 해설은 &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;atcoder.jp&#x2F;contests&#x2F;abc348&#x2F;editorial&#x2F;9774&quot;&gt;에디토리얼&lt;&#x2F;a&gt;이 있으니 참조해 주세요.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F9E2AF;&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &amp;lt;bits&#x2F;stdc++.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;using namespace&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;&quot;&gt; std&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F9E2AF;&quot;&gt;#define&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; llint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; long long int&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; main&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cin &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    vector&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    vector&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;vector&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; tree&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cin &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tree&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]].&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tree&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]].&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    vector&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;llint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cin &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;    &#x2F;&#x2F;sum_c[i]는 루트를 i로 하는 트리에 대해 정점 c[x]의 합&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;    &#x2F;&#x2F;sum_d[i]는 루트를 i로 하는 트리에 대해 c[x] * d(i, x)의 합&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    vector&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;llint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; sub_sum_c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; sub_sum_d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    auto&lt;&#x2F;span&gt;&lt;span&gt; dfs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;](&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;auto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; par&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;) -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; pair&amp;lt;llint, llint&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;        &#x2F;&#x2F;v: 현재 노드, par: 부모 노드&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; tree&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]) {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F;모든 하위방향 노드들에 대해&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;t &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; par&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; continue&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F;부모 방향으로는 가지 않는다&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;            auto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; [&lt;&#x2F;span&gt;&lt;span&gt;child_sum_c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; child_sum_d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            sub_sum_c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; child_sum_c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F;하위방향 c를 누적&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            sub_sum_d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; child_sum_d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F;하위방향 d를 누적&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        sub_sum_d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; sub_sum_c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;];&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F;재귀적으로 c[x]가 d(i, x)번 합해진다&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        sub_sum_c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; {&lt;&#x2F;span&gt;&lt;span&gt;sub_sum_c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;],&lt;&#x2F;span&gt;&lt;span&gt; sub_sum_d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;    };&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; dfs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;dfs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F;루트에서부터 dfs, 0(1)번 노드를 루트로 취급&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;    &#x2F;&#x2F;dfs를 통해 모든 노드에 대해 f(n)을 구합니다.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    vector&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;llint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    auto&lt;&#x2F;span&gt;&lt;span&gt; reroot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;](&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;auto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; par&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; llint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; par_sum_c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; llint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; par_sum_d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;) -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;        &#x2F;&#x2F;v: 현재 노드, par: 부모 노드, par_sum_c: 상위방향으로의 c합, par_sum_d: 상위방향으로의 d합&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sub_sum_d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; par_sum_d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; t &lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; tree&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]) {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F;모든 하위방향 노드들에 대해&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;t &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; par&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; continue&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F;부모 방향으로는 가지 않는다&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            llint nc &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; par_sum_c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F;v의 상위방향으로의 c 합&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;                    +&lt;&#x2F;span&gt;&lt;span&gt; sub_sum_c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F;v의 하위방향으로의 c합&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;                    &#x2F;&#x2F;여기까지 모든 노드의 c합&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;                    -&lt;&#x2F;span&gt;&lt;span&gt; sub_sum_c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;];&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F;t의 하위방향으로의 c합 뺀다&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;                    &#x2F;&#x2F;nc : t의 상위방향으로의 c합&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            llint nd &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; par_sum_d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F;v의 상위 방향으로의 d합&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;                    +&lt;&#x2F;span&gt;&lt;span&gt; sub_sum_d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F;v의 하위방향으로의 d합&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;                    -&lt;&#x2F;span&gt;&lt;span&gt; sub_sum_d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; sub_sum_c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F;t의 양방향 d합을 뺸다&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;                    &#x2F;&#x2F;여기까지 t가 v위치에 있었을 때 sum_d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;                    +&lt;&#x2F;span&gt;&lt;span&gt; nc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F;t의 상위방향으로의 c합&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;                    &#x2F;&#x2F;nd : t의 상위방향으로의 d합&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; nc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; nd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;    };&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; reroot&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;reroot&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cout &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&amp;lt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;min_element&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;begin&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(),&lt;&#x2F;span&gt;&lt;span&gt; f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;end&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;())&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; endl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;dobosio&quot;&gt;도보시오&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codeforces.com&#x2F;topic&#x2F;76681&#x2F;en17&quot;&gt;Codeforces - Rerooting Technique&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;nicotina04.tistory.com&#x2F;169&quot;&gt;nicotina04 - Rerooting Tequnique on Tree&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codeforces.com&#x2F;blog&#x2F;entry&#x2F;76150&quot;&gt;Codeforces - Online Query Based Rerooting Technique&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>Docker를 이용한 리눅스 실습 환경 구축</title>
          <pubDate>Tue, 29 Aug 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://zlfn.space/blog/linux-demo-docker/</link>
          <guid>https://zlfn.space/blog/linux-demo-docker/</guid>
          <description xml:base="https://zlfn.space/blog/linux-demo-docker/">&lt;p&gt;동아리에서 후배들에게 리눅스 세미나를 하게 되었습니다. 그러면 실습 환경 구축을 해야겠죠.&lt;&#x2F;p&gt;
&lt;p&gt;제작년에는 선배들이 버추얼 박스를 설치해 오라고 시켰고, 작년에는 똑같이 제가 세미나를 맡아서 후배들에게 제 리눅스 서버 계정을 하나씩 넘겨주는 방식으로 실습을 했는데요,&lt;&#x2F;p&gt;
&lt;p&gt;올해는 제 리눅스랑 가상화 지식이 많이 늘기도 했고, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zlfn.space&#x2F;blog&#x2F;rocky-linux&quot;&gt;서버도 깔끔하게 재구축했으니&lt;&#x2F;a&gt; 가상화를 통해 1인 1서버를 주는 걸 만들어보기로 했습니다.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gugeulring&quot;&gt;구글링&lt;&#x2F;h3&gt;
&lt;p&gt;원래는 컨테이너를 여러개 열어서 SSH 리버스 프록시나 점프 포워드로 구축해 보려고 했는데, 생각보다 어려워서 고전하던 중, 아래 글을 발견하게 되었습니다.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;unix.stackexchange.com&#x2F;questions&#x2F;126426&#x2F;replicate-and-isolating-user-environments-on-the-fly&quot;&gt;Replicate and Isolationg user environments on the fly&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;제가 딱 원하던거여서, 이 내용을 기반으로 환경에 맞게 수정해서 구축하기로 했습니다.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;imiji-mandeulgi&quot;&gt;이미지 만들기&lt;&#x2F;h3&gt;
&lt;p&gt;위 글에서는 컨테이너를 수정하고 그걸 다시 이미지로 만드는 과정을 거쳤는데, 그건 너무 귀찮아서  Dockerfile로 구성하기로 했습니다.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;docker&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;# Dockerfile&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;FROM&lt;&#x2F;span&gt;&lt;span&gt; ubuntu:latest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; apt-get update&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; apt-get install -y vim sudo man-db gcc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; yes | unminimize&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; useradd -ms &#x2F;bin&#x2F;bash guest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; echo &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;#39;guest:password&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; | chpasswd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; usermod -a -G sudo guest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;USER&lt;&#x2F;span&gt;&lt;span&gt; guest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;WORKDIR&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;home&#x2F;guest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;실습에 필요한 패키지인 &lt;code&gt;vim&lt;&#x2F;code&gt;, &lt;code&gt;sudo&lt;&#x2F;code&gt;, &lt;code&gt;man-db&lt;&#x2F;code&gt;, &lt;code&gt;gcc&lt;&#x2F;code&gt; 를 깔고, &lt;code&gt;unminimize&lt;&#x2F;code&gt;를 수행해서 &lt;code&gt;man&lt;&#x2F;code&gt;이 동작하게 만듭니다.&lt;&#x2F;p&gt;
&lt;p&gt;그리고 guest 라는 유저를 만들어서 컨테이너에 접속하게 되면 루트가 아니라 유저로서 접속하게 합니다. 이러면 ssh로 직접 접속하는거랑 더 비슷한 느낌을 줄 수 있겠죠.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;docker&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; build --tag sandbox .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;로 이미지를 빌드합니다.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;yujeo-mandeulgi&quot;&gt;유저 만들기&lt;&#x2F;h3&gt;
&lt;p&gt;이제 유저를 만들어서, SSH로 접속하게 되면 가짜 셸에 접속하게 합니다.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;mkdir&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &#x2F;home&#x2F;guest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;cat&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &#x2F;home&#x2F;guest&#x2F;sandbox&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;EOF&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;#!&#x2F;bin&#x2F;sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;exec docker run -t -i --rm=true sandbox &#x2F;bin&#x2F;bash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;EOF&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;chmod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; +x &#x2F;home&#x2F;guest&#x2F;sandbox&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;# useradd guest -g docker -s &#x2F;home&#x2F;guest&#x2F;sandbox &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;useradd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; guest -s &#x2F;home&#x2F;guest&#x2F;sandbox&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;chown&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; guest &#x2F;home&#x2F;guest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;passwd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; guest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;저는 Docker가 아니라 Podman 환경이어서, 유저에게 &lt;code&gt;docker&lt;&#x2F;code&gt; 그룹을 주지 않아도 &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;access.redhat.com&#x2F;documentation&#x2F;ko-kr&#x2F;red_hat_enterprise_linux&#x2F;8&#x2F;html&#x2F;building_running_and_managing_containers&#x2F;proc_setting-up-rootless-containers_assembly_starting-with-containers&quot;&gt;Rootless Podman&lt;&#x2F;a&gt;을 실행할 수 있었습니다. Docker로 구성할 경우 &lt;code&gt;docker&lt;&#x2F;code&gt; 그룹을 주는게 필요하겠네요.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;docker&lt;&#x2F;code&gt; 명령어에는 &lt;code&gt;--rm=true&lt;&#x2F;code&gt; 인자를 붙혀서 도커 컨테이너에서 나갈 경우 바로 컨테이너가 삭제되도록 하고, 유저가 들어오면 가짜 셸을 실행해서 도커를 열게 합니다.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;wanseong&quot;&gt;완성&lt;&#x2F;h3&gt;
&lt;p&gt;위 설정대로 구축하고, &lt;code&gt;guest&lt;&#x2F;code&gt;유저로 ssh 접속하게 되면 임시 생성된 컨테이너에 가둬지게 됩니다.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;zlfn.space&#x2F;blog&#x2F;linux-demo-docker&#x2F;Screenshot_20230829_113449.png&quot; alt=&quot;Screenshot_20230829_113449&quot; title=&quot;Screenshot_20230829_113449&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;(블로그에 쓴 것과 유저 이름은 다릅니다.)&lt;&#x2F;p&gt;
&lt;p&gt;이 환경에서는 원하는 만큼 패키지를 설치하거나 (커널에 관련된 것만 아니면) 시스템을 수정할 수 있고, &lt;code&gt;sudo rm -rf &#x2F;&lt;&#x2F;code&gt;를 수행해도 컨테이너를 실행하는 시스템에는 아무런 영향이 가지 않습니다.&lt;&#x2F;p&gt;
&lt;p&gt;나왔다 들어오면 모든 내용이 초기화되고 새 컨테이너를 생성하니 실습하기 좋은 환경이죠.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo rm -rf --no-preserve-root &#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;을 실행해보고 시스템이 박살나지 않는지 확인해 봅시다.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2024-07-15-cuga&quot;&gt;2024.07.15 추가&lt;&#x2F;h3&gt;
&lt;p&gt;위와 같이 컨테이너를 구축하면 로그아웃 할 때 가끔 컨테이너가 제대로 지워지지 않는 문제, 로그인 할 시에 Refreshing Error가 발생하는 문제가 있습니다.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ERRO[0001] Refreshing container 2e3d121a75ec00add6a35694cdc26e6442bb98a7e993b918569dd7584597bca6: acquiring lock 0 for container 2e3d121a75ec00add6a35694cdc26e6442bb98a7e993b918569dd7584597bca6: file exists&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;로그아웃 할 때 컨테이너가 지워지지 않는 문제는 &lt;code&gt;guest&lt;&#x2F;code&gt; 계정의 &lt;code&gt;.bash_logout&lt;&#x2F;code&gt; 파일에 &lt;code&gt;docker stop sandbox&lt;&#x2F;code&gt;를 적었는데, 일단 확실하진 않지만 해결이 된 것 같고,
에러는 &lt;code&gt;loginctl enable-linger guest&lt;&#x2F;code&gt;를 통해 계정의 lingering mode를 허용해 주면 해결되는 듯 합니다.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>순차탐색과 이분탐색</title>
          <pubDate>Mon, 01 Nov 2021 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://zlfn.space/blog/binary-search/</link>
          <guid>https://zlfn.space/blog/binary-search/</guid>
          <description xml:base="https://zlfn.space/blog/binary-search/">&lt;blockquote&gt;
&lt;p&gt;!! 구 블로그 (Blogger) 에서 가져온 글입니다. 글 일부가 깨져보일 수 있습니다.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;tamsaegiran&quot;&gt;탐색이란?&lt;&#x2F;h2&gt;
&lt;p&gt;탐색이란 데이터 구조 안의 저장된 정보를 찾는 것입니다.&lt;&#x2F;p&gt;
&lt;p&gt;대표적인 탐색 알고리즘에는 3가지가 있습니다.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;순차탐색 (Sequential Search) — 혹은 선형탐색 (Linear Search)&lt;&#x2F;li&gt;
&lt;li&gt;이분탐색 (Binary Search)&lt;&#x2F;li&gt;
&lt;li&gt;해시탐색 (Hash Search)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;이 글에서는 순차탐색과 이분탐색만을 다룹니다. 해시탐색은 언젠가 다룰 예정...&lt;&#x2F;p&gt;
&lt;p&gt;+: 3년이라는 시간이 걸렸지만 다뤘습니다.
&lt;a href=&quot;&#x2F;blog&#x2F;dictionary-and-hashing&quot;&gt;딕셔너리와 맵, 해싱&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;suncatamsaeg-sequential-search&quot;&gt;순차탐색 (Sequential Search)&lt;&#x2F;h3&gt;
&lt;p&gt;순차탐색은 탐색알고리즘 중 가장 간단한 형태의 알고리즘이며, 선형탐색 (Linear Search) 라고도 합니다.&lt;&#x2F;p&gt;
&lt;p&gt;어떠한 데이터 배열이 있으면 데이터 배열의 처음부터 끝까지 모두 비교하여 자료를 찾아냅니다.&lt;&#x2F;p&gt;
&lt;p&gt;쉽게 말해서 그냥 배열 처음부터 끝까지 노가다.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;장점&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;정렬되지 않은 배열에서 사용할 수 있다.&lt;&#x2F;li&gt;
&lt;li&gt;구현이 간편하다.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;단점&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;데이터의 양이 많아지면 비효율적이다.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;순차탐색의 코드는 아래와 같습니다.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F9E2AF;&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &amp;lt;stdio.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F9E2AF;&quot;&gt;#define&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; SIZE_OF_ARRAY&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;SIZE_OF_ARRAY&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; main&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;  &#x2F;*array를 입력받는 코드 (전역변수이므로 초기값 0)*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  int&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F;x:배열에서 찾을 값&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;  scanf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;%d&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  int&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F;i:인덱스&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;SIZE_OF_ARRAY&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;  {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; printf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;%d&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F;만약 array에서 x값을 찾으면 인덱스 값 출력&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;위의 내용을 함수로 만든 코드 스니펫 (클릭)&lt;&#x2F;strong&gt;&lt;&#x2F;summary&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; SequentialSearch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;  &#x2F;&#x2F;arr:배열포인터, n:배열의 길이, x:찾을 값&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;  {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F;만약 x를 찾으면 인덱스를 반환&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F;찾지 못했으면 -1을 반환&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;details&gt;
&lt;h3 id=&quot;ibuntamsaeg-binary-search&quot;&gt;이분탐색 (Binary Search)&lt;&#x2F;h3&gt;
&lt;p&gt;이분탐색은 &lt;strong&gt;정렬된 데이터&lt;&#x2F;strong&gt;에서 쓸 수 있는 탐색 알고리즘으로, 찾고자 하는 값을 가운데 값과 비교해서 그 값이 왼쪽에 있는지 오른쪽에 있는지 파악하여 자료를 찾습니다.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;장점&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;순차탐색에 비해 탐색속도가 빠르다.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;단점&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;데이터가 미리 정렬되어 있어야 한다.&lt;&#x2F;li&gt;
&lt;li&gt;데이터의 임의접근(Random Access)이 가능해야한다. — 데이터에 몇개의 요소가 있는지에 관계없이, 모든 요소에 대해 같은 시간 내에 접근 할 수 있는 접근 방식, C언어의 배열은 임의접근이 가능하며, 연결리스트와 같은 특정 자료구조는 불가능하다. (어렵다면 지금은 무시해도 좋다.)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;이분탐색의 대략적인 의사코드는 다음과 같습니다.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;배열의 중앙값과 찾으려는 값을 비교한다.&lt;&#x2F;li&gt;
&lt;li&gt;만약 찾으려는 값이 더 작다면 왼쪽 부분, 더 크다면 오른쪽 부분을 선택한다. 같다면 탐색을 종료한다.&lt;&#x2F;li&gt;
&lt;li&gt;선택한 구간의 중앙값과 찾으려는 값을 비교한다. -&amp;gt; B로 돌아간다.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;zlfn.space&#x2F;blog&#x2F;binary-search&#x2F;binary-search.png&quot; alt=&quot;이분탐색 다이어그램&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;이분탐색은 재귀함수와 반복문, 두 가지 방법으로 구현할 수 있습니다.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;이분탐색의 반복문 구현&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F9E2AF;&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &amp;lt;stdio.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F9E2AF;&quot;&gt;#define&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; SIZE_OF_ARRAY&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;SIZE_OF_ARRAY&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; main&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;  &#x2F;*array를 입력받는 코드 (전역변수이므로 초기값 0)*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  int&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F;x:배열에서 찾을 값&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;  scanf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;%d&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  int&lt;&#x2F;span&gt;&lt;span&gt; left&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; right&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;SIZE_OF_ARRAY&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  while&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;left&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt;right&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F;left가 right 이하 일때 반복&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;  {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;left&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt;right&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; printf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;%d&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt;mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F;찾으면 index 출력&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    else if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; right&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    else if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; left&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;  printf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;Not Found&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F5C2E7;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F;찾지 못할 경우 출력&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;위의 내용을 함수로 만든 코드 스니펫 (클릭)&lt;&#x2F;strong&gt;&lt;&#x2F;summary&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; BinarySearch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;  &#x2F;&#x2F;arr:배열포인터, n:배열의 길이, x:찾을 값&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  int&lt;&#x2F;span&gt;&lt;span&gt; left&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; right&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  while&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;left&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt;right&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F;left가 right 이하 일때 반복&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;  {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;left&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt;right&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    else if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; right&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    else if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; left&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;details&gt;
&lt;p&gt;&lt;strong&gt;이분탐색의 재귀함수 구현&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F9E2AF;&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &amp;lt;stdio.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F9E2AF;&quot;&gt;#define&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; SIZE_OF_ARRAY&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;SIZE_OF_ARRAY&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; RecursiveBinarySearch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; left&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; right&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  int&lt;&#x2F;span&gt;&lt;span&gt; mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;left&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;right&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mid &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;left&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt;right&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt;array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;])&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  else if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; RecursiveBinarySearch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;left&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  else if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; RecursiveBinarySearch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; right&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; main&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;  &#x2F;*array를 입력받는 코드 (전역변수이므로 초기값 0)*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  int&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt; &#x2F;&#x2F;x:배열에서 찾을 값&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;  scanf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;%d&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;  printf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;%d&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;RecursiveBinarySearch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt;SIZE_OF_ARRAY&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;위의 내용을 함수로 만든 코드 스니펫 (클릭)&lt;&#x2F;strong&gt;&lt;&#x2F;summary&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; BinarySearch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;    &#x2F;&#x2F;arr:배열포인터, n:배열의 길이, x:찾을 값&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  int&lt;&#x2F;span&gt;&lt;span&gt; mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;left&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;right&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mid &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;left&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt;right&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt;array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;])&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  else if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; BinarySearch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;left&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  else if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; BinarySearch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; right&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;details&gt;
</description>
      </item>
    </channel>
</rss>
