<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>niraaah.log</title>
        <link>https://velog.io/</link>
        <description>코딩천재</description>
        <lastBuildDate>Sun, 07 Jul 2024 12:29:45 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>niraaah.log</title>
            <url>https://velog.velcdn.com/images/meer_/profile/8432b3fa-c25d-4f4b-af77-3934284f50ee/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. niraaah.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/meer_" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[해결] 스타듀밸리 맥 M1 M2 컨트롤러 이슈]]></title>
            <link>https://velog.io/@meer_/%ED%95%B4%EA%B2%B0-%EC%8A%A4%ED%83%80%EB%93%80%EB%B0%B8%EB%A6%AC-%EB%A7%A5-M1-M2-%EC%BB%A8%ED%8A%B8%EB%A1%A4%EB%9F%AC-%EC%9D%B4%EC%8A%88</link>
            <guid>https://velog.io/@meer_/%ED%95%B4%EA%B2%B0-%EC%8A%A4%ED%83%80%EB%93%80%EB%B0%B8%EB%A6%AC-%EB%A7%A5-M1-M2-%EC%BB%A8%ED%8A%B8%EB%A1%A4%EB%9F%AC-%EC%9D%B4%EC%8A%88</guid>
            <pubDate>Sun, 07 Jul 2024 12:29:45 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/meer_/post/df8d4d91-aef0-48c3-91f0-44600306b48d/image.png" alt=""></p>
<p>이 게시글은 애플 실리콘을 사용하는 M1과 M2에게 해당되는 해결방법입니다!
이 게시글은 언젠가 포맷을 하게된 미래의 niraaah를 위해 작성되었습니다.</p>
<ol>
<li><a href="https://forums.stardewvalley.net/attachments/libsdl2-2-0-0-dylib-zip.18662/">파일</a> 다운로드 해서 해당 파일 압축 해제</li>
<li>파인더 새 창 열어서 경로 이동:
<code>/사용자/[본인의 사용자 이름]/라이브러리/Application Support/Steam/steamapps/common/Stardew Valley/Contents/MacOS</code></li>
<li>2번의 경로에 있는 파일들 중 &quot;libSDL2-2.0.0.dylib&quot; 라는 이름을 가진 파일 찾아서 이름 변경:
<code>&quot;libSDL2-2.0.0.dylib&quot; &gt; &quot;libSDL2-2.0.0.dylib.orig&quot;</code>
<del>(뭔가 문제가 되었을 때 추가했던 파일을 삭제하고 이름 바꿨던 파일의 이름에서 &quot;.orig&quot;만 지워주면 원상복구가 가능하게 하기 위함임. 이름을 변경하지 않고 기존 파일을 아얘 지워버려도 상관은 없을 듯 하지만 절대 권장하지 않음)</del></li>
<li>1번에서 압축 해제해둔 &quot;libSDL2-2.0.0.dylib&quot; 파일을 2번의 경로에 옮겨준다.</li>
<li>스듀를 정상적으로 재실행시켜보면... 해결 완!</li>
</ol>
<p><a href="https://forums.stardewvalley.net/threads/no-sound-with-libsdl2-2-0-0-controller-fix.14450/#post-115714">출처: 스타듀밸리 포럼</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[🐢 파이썬 기초의 모든 것 🐢]]></title>
            <link>https://velog.io/@meer_/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EA%B8%B0%EC%B4%88%EC%9D%98-%EB%AA%A8%EB%93%A0</link>
            <guid>https://velog.io/@meer_/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EA%B8%B0%EC%B4%88%EC%9D%98-%EB%AA%A8%EB%93%A0</guid>
            <pubDate>Fri, 13 Oct 2023 05:13:50 GMT</pubDate>
            <description><![CDATA[<h2 id="리스트--인덱스를-기반으로-값을-저장">[리스트] : ‘인덱스’를 기반으로 값을 저장</h2>
<pre><code class="language-python">
# IndexError 예외: 리스트의 길이를 넘는 인덱스로 요소에 접근하고자 할 때 발생

# ---------------------------------------- #

listA = [1,2,3]
listB = [4,5,6]

print(listA + listB) # [1,2,3,4,5,6]
print(listA * 3) # [1,2,3,1,2,3,1,2,3]
print(len(listA)) # 3

listA.extend(listB) # (연결 연산자 &#39;+&#39; 와 달리) &#39;파괴적 처리&#39;
print(listA) # [1,2,3,4,5,6]

# ---------------------------------------- #

listA = [1,2,3]
listB = [4,5,6]
listC = [4,5,6]

listA.append(4) # 리스트 뒤에 요소 추가
print(listA) # [1,2,3,4]

# 비교하기) 둘 다 &#39;파괴적 처리&#39;다.
# listB.append(listA) -&gt; [4,5,6,[1,2,3]]
# listC += listA -&gt; [4,5,6,1,2,3]

listA.insert(0,10) # 리스트 중간에 요소 추가
print(listA) # [10,1,2,3,4] 

# ---------------------------------------- #

#인덱스로 요소 제거

listA = [0,1,2,3,4,5]

del listA[1]
print(listA) # [0,2,3,4,5]

listA.pop()
print(listA) # [0,2,3,4]
listA.pop(2)
print(listA) # [0,2,4]

listB = [0,1,2,3,4,5,6]
listC = [0,1,2,3,4,5,6]
listD = [0,1,2,3,4,5,6]

del listB[3:6]
print(listB) # [0,1,2,6]
del listC[:3]
print(listC) # [3,4,5,6]
del listD[3:]
print(listD) # [0,1,2]

# ---------------------------------------- #

# &lt;슬라이싱&gt;
# 형식&gt;&gt; 리스트_이름 [ 시작_인덱스 : 끝_인덱스 : 단계 ]

numbers1 = [1,2,3,4,5,6,7,8]
numbers2 = [1,2,3,4,5,6,7,8]

print(numbers1[0:5:2]) # [1,3,5]
print(numbers2[::-1]) # [8,7,6,5,4,3,2,1]

# ---------------------------------------- #

# 값으로 제거

listA = [1,2,1,2]
listB = [0,1,2,3,4,5]

listA.remove(2)
print(listA) # [1,1,2]
# 리스트에 중복된 여러개의 값을 모두 제거하려면 반복문과 조합해서 사용해야함
# while 2 in listC:
#     listC.remove(2)
#     print(listC)

listB.clear()
print(listB) # []

# ---------------------------------------- #

# 요소 정렬하기

listA = [52, 273, 103, 32, 275, 1, 7]
listA.sort() # 오름차순
print(listA) # [1,7,32,52,103,273,275]
listA.sort(reverse = True) # 내림차순
print(listA) # [275,273,103,52,32,7,1]

# ---------------------------------------- #

# in / not in 연산자
# 특정 값이 내부에 있는지 확인

listA = [273,32,103,57,52]

print(273 in listA) # True
print(10 in listA) # False
print(273 not in listA) # False
print(10 not in listA) # True

# ---------------------------------------- #

# for와 리스트

array = [273,32,103,57,52]

for element in array:
    print(element)
# 출력 결과:
# 273
# 32
# 103
# 57
# 52

for character in &quot;안녕하세요&quot;:
    print(&quot;-&quot;, character)
# 출력 결과:
# - 안
# - 녕
# - 하
# - 세
# - 요

listOfList = [
    [1,2,3],
    [4,5,6,7],
    [8,9]
]

for items in listOfList:
    for item in items:
        print(item)
# 출력 결과:
# 1
# 2
# 3
# 4
# 5
# 6
# 7
# 8
# 9

# ---------------------------------------- #

# 전개 연산자 &#39;*&#39;

listA = [1, 2, 3, 4]

listB = [*listA, *listA]
listC = [*listA, 5]
listD = [listA, listA]

print(listA) # [1, 2, 3, 4]
print(listB) # [1, 2, 3, 4, 1, 2, 3, 4]
print(listC) # [1, 2, 3, 4, 5]
print(listD) # [[1, 2, 3, 4], [1, 2, 3, 4]]


# ---------------------------------------- #

# min(리스트_이름): 리스트 내부의 최솟&#39;값&#39; 반환
# max(리스트_이름): 리스트 내부의 최댓&#39;값&#39; 반환

&gt;&gt;&gt; max(iterable, *iterables, key=None, default=None)
&gt;&gt;&gt; min(iterable, *iterables, key=None, default=None)

- iterable: 찾을 대상인 하나의 반복 가능한 객체 (필수)
- *iterables: 추가적인 iterable (선택)
- key: 함수를 인자로 받아 각 요소의 정렬 순서를 결정하는데 사용
- default: itrable이 비어있을 때 반환될 값 (비 지정시 ValueError 발생)

# sum(리스트_이름): 리스트 내부의 값을 모두 더한 &#39;값&#39;을 반환

# ---------------------------------------- #

# reversed(리스트_이름): 뒤집어진 &#39;이터레이터&#39;를 반환
# 반환 결과가 &#39;리스트&#39;가 아님을 기억하자!

numbers = [1,2,3,4,5]
for i in reversed(numbers):
    print(&#39;반복문: {}&#39;.format(i))

# 실행 결과
# 반복문: 5
# 반복문: 4
# 반복문: 3
# 반복문: 2
# 반복문: 1

# ---------------------------------------- #

# enumerate(리스트_이름)
# : 리스트의 요소를 반복할 때 인덱스가 몇 번째인지 확인하기 위해 사용 

exampleList = [&#39;A&#39;,&#39;B&#39;,&#39;C&#39;]

print(&#39;# 단순 출력&#39;)
print(exampleList)
print(&#39;-&#39;)

print(&#39;# enumerate()함수 적용&#39;)
print(enumerate(exampleList))
print(&#39;-&#39;)

print(&#39;# list() 함수로 강제 변환 출력&#39;)
print(list(enumerate(exampleList)))
print(&#39;-&#39;)

print(&#39;# 반복문과 조합하기&#39;)
for i, value in enumerate(exampleList): # for 와 in 사이에 변수가 두 개가 들어감
    print(&#39;{}번째 요소는 {}입니다.&#39;.format(i,value))

# 출력 결과

# # 단순 출력
# [&#39;A&#39;, &#39;B&#39;, &#39;C&#39;]
# -
# # enumerate()함수 적용
# &lt;enumerate object at 0x000001E037044DC0&gt;
# -
# # list() 함수로 강제 변환 출력
# [(0, &#39;A&#39;), (1, &#39;B&#39;), (2, &#39;C&#39;)]
# -
# # 반복문과 조합하기
# 0번째 요소는 A입니다.
# 1번째 요소는 B입니다.
# 2번째 요소는 C입니다.</code></pre>
<h2 id="리스트-내포">[리스트 내포]</h2>
<pre><code class="language-python"># 리스트_이름 = [ 표현식 for 반복자 in 반복할_수_있는_것 ]
# 리스트_이름 = [ 표현식 for 반복자 in 반복할_수_있는_것 if 조건문 ]

array1=[]
for i in range(0,20,2):
    array1.append(i * i)
print(array1)

# 대신

array2 = [i * i for i in range(0,20,2)]
# 해석: range(0,20,2)의 요소를 i라고 할 때 i * i로 리스트를 재조합해 줘
print(array2)

# ---------------------------------------- #

array = [&#39;apple&#39;,&#39;plum&#39;,&#39;chocolate&#39;,&#39;banana&#39;,&#39;cherry&#39;]

# output = [fruit for fruit in array if fruit != &#39;chocolate&#39;] 또는
output = [fruit 
    for fruit in array 
    if fruit != &#39;chocolate&#39;]

print(output) # [&#39;apple&#39;, &#39;plum&#39;, &#39;banana&#39;, &#39;cherry&#39;]</code></pre>
<h2 id="딕셔너리--키를-기반으로-값을-저장">[딕셔너리] : ‘키’를 기반으로 값을 저장</h2>
<pre><code class="language-python">myDic = {
    &quot;name&quot; : &quot;7D mango&quot;,
    &quot;type&quot; : &quot;fruit&quot;,
    &quot;ingredient&quot; : [&quot;mango&quot;, &quot;sugar&quot;, &quot;salt&quot;, &quot;color&quot;],
    &quot;origin&quot; : &quot;Philippines&quot;
}

print(&quot;name:&quot;,myDic[&quot;name&quot;])
print(&quot;type:&quot;,myDic[&quot;type&quot;])
print(&quot;ingredient:&quot;,myDic[&quot;ingredient&quot;])
print(myDic[&quot;ingredient&quot;][1])
print(&quot;origin:&quot;,myDic[&quot;origin&quot;])
print()

# 출력 결과
# name: 7D mango
# type: fruit
# ingredient: [&#39;mango&#39;, &#39;sugar&#39;, &#39;salt&#39;, &#39;color&#39;]
# sugar
# origin: Philippines

myDic[&quot;name&quot;] = &quot;8D mango&quot; # 값을 수정
print(&quot;name:&quot;,myDic[&quot;name&quot;]) # name: 8D mango

myDic[&quot;price&quot;] = 5000 # 키와 값을 추가
print(myDic)

# 출력 결과
# {&#39;name&#39;: &#39;8D mango&#39;, &#39;type&#39;: &#39;fruit&#39;,
# &#39;ingredient&#39;: [&#39;mango&#39;, &#39;sugar&#39;, &#39;salt&#39;, &#39;color&#39;],
# &#39;origin&#39;: &#39;Philippines&#39;, &#39;price&#39;: 5000}

del myDic[&#39;type&#39;] # 키와 값을 제거
print(myDic)

# 출력 결과
# {&#39;name&#39;: &#39;8D mango&#39;, &#39;type&#39;: &#39;fruit&#39;,
# &#39;ingredient&#39;: [&#39;mango&#39;, &#39;sugar&#39;, &#39;salt&#39;, &#39;color&#39;],
# &#39;origin&#39;: &#39;Philippines&#39;}

# ---------------------------------------- #

myDic = {}
print(&#39;요소 추가 이전:&#39;,myDic)
myDic[&#39;name&#39;] = &#39;new name&#39;
myDic[&#39;head&#39;] = &#39;new spirit&#39;
myDic[&#39;body&#39;] = &#39;new body&#39;

print(&#39;요소 추가 이후:&#39;,myDic)

# 출력 결과
# 요소 추가 이전: {}
# 요소 추가 이후: {&#39;name&#39;: &#39;new name&#39;, &#39;head&#39;: &#39;new spirit&#39;, &#39;body&#39;: &#39;new body&#39;}

# ---------------------------------------- #

# KeyError : 존재하지 않는 키에 접근시 발생

# ---------------------------------------- #

myDic = {
    &quot;name&quot; : &quot;7D mango&quot;,
    &quot;type&quot; : &quot;fruit&quot;,
    &quot;ingredient&quot; : [&quot;mango&quot;, &quot;sugar&quot;, &quot;salt&quot;, &quot;color&quot;],
    &quot;origin&quot; : &quot;Philippines&quot;
}

key = input(&#39;&gt; 접근하고자 하는 키: &#39;)

if key in myDic:
    print(myDic[key])
else:
    print(&quot;존재하지 않는 키에 접근하고 있습니다.&quot;)

# ---------------------------------------- #

# get() : &#39;딕셔너리_이름 [ 키 ]&#39; 와 같은 기능을 하는데
# 존재하지 않는 키에 접근할 경우 KeyError 발생 대신 None 출력

value = myDic.get(&#39;존재하지 않는 키&#39;)
print(&#39;값:&#39;,value)

if value == None:
    print(&quot;존재하지 않는 키에 접근했었습니다.&quot;)

# 출력 결과
# 값: None
# 존재하지 않는 키에 접근했었습니다.

# ---------------------------------------- #

# for문과 딕셔너리

for key in myDic:
    print(key,&#39;:&#39;,myDic[key])

# 출력 결과
# {&#39;name&#39;: &#39;8D mango&#39;, &#39;type&#39;: &#39;fruit&#39;,
# &#39;ingredient&#39;: [&#39;mango&#39;, &#39;sugar&#39;, &#39;salt&#39;, &#39;color&#39;],
# &#39;origin&#39;: &#39;Philippines&#39;}

# ---------------------------------------- #

# 딕셔너리_이름.item() 활용

exDic = {
    &#39;keyA&#39;:&#39;valueA&#39;,
    &#39;keyB&#39;:&#39;valueB&#39;,
    &#39;keyC&#39;:&#39;valueC&#39;
}

print(exDic.items())

# 출력 결과
# dict_items([(&#39;keyA&#39;, &#39;valueA&#39;), (&#39;keyB&#39;, &#39;valueB&#39;), (&#39;keyC&#39;, &#39;valueC&#39;)])

for key, element in exDic.items():
    print(key,&#39;:&#39;,element)

# 출력 결과
# keyA : valueA
# keyB : valueB
# keyC : valueC</code></pre>
<aside>
💡 파이썬에서 범위를 지정할 때 범위의 끝으로 입력한 숫자는 포함되지 않는다!
ex) range(0,10) ⇒ ‘0 부터 9 까지’ 를 의미함!!

</aside>

<h2 id="역반복문">[역반복문]</h2>
<pre><code class="language-python">for i in range(4,-1,-1): # range(4,0-1,-1)  표현으로 강조할 수도 있음
    print(&quot;현재 반복 변수: {}&quot;.format(i))

for i in reversed(range(5)):
    print(&quot;현재 반복 변수: {}&quot;.format(i))

# 실행 결과
# 현재 반복 변수: 4
# 현재 반복 변수: 3
# 현재 반복 변수: 2
# 현재 반복 변수: 1
# 현재 반복 변수: 0</code></pre>
<h2 id="중첩-반복문으로-별-쌓기">[중첩 반복문으로 별 쌓기]</h2>
<pre><code class="language-python">output = &#39;&#39;

for i in range(1,11):
    for j in range(i):
        output+=&#39;*&#39;
    output += &#39;\n&#39;

print(output)

# 출력결과
# *
# **
# ***
# ****
# *****
# ******
# *******
# ********
# *********
# **********

# ---------------------------------------- #

output = &#39;&#39;
for i in range(1,11):
    for j in range(11-i):
        output += &#39; &#39;
    for k in range(2 * i - 1):
        output += &#39;*&#39;
    output += &#39;\n&#39;
print(output)

# 출력 결과
#           *
#          ***
#         *****
#        *******
#       *********
#      ***********
#     *************
#    ***************
#   *****************
#  *******************</code></pre>
<h2 id="시간-기반-반복">[시간 기반 반복]</h2>
<pre><code class="language-python">import time
number = 0

targetTick = time.time() + 5
while time.time() &lt; targetTick:
    number += 1
print(&#39;5초 동안 {}번 반복했습니다.&#39;.format(number))

# 출력 결과
# 5초 동안 29396701번 반복했습니다.

# ---------------------------------------- #

#10초 타이머 만들기

import time

count = 1
maxTime = time.time() + 10
while True:
    time.sleep(1)
    print(count)
    if time.time() &gt; maxTime:
        break
    count += 1</code></pre>
<h2 id="break--continue">[break / continue]</h2>
<pre><code class="language-python">i = 1
while True:
    print(&#39;{}번째 반복문입니다.&#39;.format(i))
    i += 1
    inputText = input(&#39;&gt; 종료하시겠습니까?(y/n): &#39;)
    if inputText in [&#39;y&#39;,&#39;Y&#39;]:
        print(&#39;반복을 종료합니다&#39;)
        break

# &#39;y&#39; 또는 &#39;Y&#39;가 입력될 때까지 반복
# &#39;y&#39; 또는 &#39;Y&#39;가 입력되면 프로그램 종료

# ---------------------------------------- #

# 이중 루프 탈출

i = 1
while True:
    print(&#39;{}번째 반복문입니다.&#39;.format(i))
    i += 1
    while True:
        inputText = input(&#39;종료하시겠습니까? (y/n) : &#39;)
        if inputText in [&#39;y&#39;,&#39;Y&#39;]:
            print(&#39;반복을 종료합니다.&#39;)
            break
        elif inputText in [&#39;n&#39;, &#39;N&#39;]:
            break
        else:
            print(&#39;올바른 입력이 아닙니다!&#39;)
            continue
    if inputText in [&#39;y&#39;, &#39;Y&#39;]:
        break

# ---------------------------------------- #

numbers = [5,15,6,20,7,25]

for number in numbers:
    if number &lt; 10:
        continue
    print(number)

# 출력 결과
# 15
# 20
# 25</code></pre>
<h2 id="여러-줄의-문자열-처리">[여러 줄의 문자열 처리]</h2>
<pre><code class="language-python">test = (
    &#39;이렇게 입력해도 &#39;
    &#39;하나의 문자열로 연결되어 &#39;
    &#39;생성됩니다.&#39;
)

print(test) # 이렇게 입력해도 하나의 문자열로 연결되어 생성됩니다.
print(type(test)) # &lt;class &#39;str&#39;&gt;

# ---------------------------------------- #

# 문자열.join(문자열로_구성된_리스트)

print(&#39;::&#39;.join([&#39;1&#39;,&#39;2&#39;,&#39;3&#39;,&#39;4&#39;,&#39;5&#39;])) # 1::2::3::4::5

# 응용:
number = int(input(&#39;정수 입력&gt; &#39;))

if number % 2 == 0:
    print(&#39;\n&#39;.join([
        &#39;입력한 문자열은 {}입니다.&#39;,
        &#39;{}는(은) 짝수입니다.&#39;
    ]).format(number, number))
else:
    print(&#39;\n&#39;.join([
        &#39;입력한 문자열은 {}입니다.&#39;,
        &#39;{}는(은) 홀수입니다.&#39;
    ]).format(number, number))

# 더 간단하게는

number = int(input(&#39;정수 입력&gt;&gt; &#39;))

answer = [
        &#39;입력한 문자열은{}입니다&#39;,
        &#39;{}는(은) {}입니다.&#39;
    ]
if number % 2 == 0:
    print(&#39;\n&#39;.join(answer).format(number, number, &#39;even&#39;))
else:
    print(&#39;\n&#39;.join(answer).format(number, number, &#39;odd&#39;))
</code></pre>
<h2 id="이터레이터">[이터레이터]</h2>
<pre><code class="language-python"># reversed() 함수와 이터레이터

numbers = [1,2,3,4,5,6]
rNum = reversed(numbers)

print(rNum)
print(next(rNum))
print(next(rNum))
print(next(rNum))
print(next(rNum))
print(next(rNum))
print(next(rNum))

# 실행 결과
# &lt;list_reverseiterator object at 0x000001E037012D90&gt;
# 6
# 5
# 4
# 3
# 2
# 1</code></pre>
<aside>
💡 왜 reversed() 함수는 리스트를 바로 리턴해 주지 않고 이터레이터를 리턴해 주는 걸까?
: 메모리의 효율성을 위해서! 수많은 요소가 들어있는 리스트를 복제한 뒤 뒤집어서 맅턴하는 것보다 기존에 있던 리스트를 활용해서 작업하는 것이 훨씬 효율적이기 때문.

</aside>

<hr>
<h2 id="가변-매개변수-함수">[가변 매개변수 함수]</h2>
<pre><code class="language-python">def printNtimes(n, *values):
    for i in range(n):
        for value in values:
            print(value)
        print(&#39;-&#39;) 
printNtimes(3, &#39;hello&#39;, &#39;world&#39;, &#39;good&#39;, &#39;morning&#39;)
print()
def printNtimes(n, *values):
    for i in range(n):
        for value in values:
            print(value)
        print(&#39;-&#39;) 
printNtimes(3, [&#39;hello&#39;, &#39;world&#39;, &#39;good&#39;, &#39;morning&#39;])
print()
def printNtimes(n, values):
    for i in range(n):
        for value in values:
            print(value)
        print(&#39;-&#39;)

printNtimes(3, [&#39;hello&#39;, &#39;world&#39;, &#39;good&#39;, &#39;morning&#39;])

# 출력 결과
# hello
# world
# good
# morning
# -
# hello
# world
# good
# morning
# -
# hello
# world
# good
# morning
# -
# 
# [&#39;hello&#39;, &#39;world&#39;, &#39;good&#39;, &#39;morning&#39;]
# -
# [&#39;hello&#39;, &#39;world&#39;, &#39;good&#39;, &#39;morning&#39;]
# -
# [&#39;hello&#39;, &#39;world&#39;, &#39;good&#39;, &#39;morning&#39;]
# -
# 
# hello
# world
# good
# morning
# -
# hello
# world
# good
# morning
# -
# hello
# world
# good
# morning
# -</code></pre>
<h2 id="키워드-매개변수">[키워드 매개변수]</h2>
<pre><code class="language-python">def printNtimes(*values, n = 2):
    for i in range(n):
        for value in values:
            print(value)
        print(&#39;-&#39;)

printNtimes(&#39;hello,&#39;,&#39;world!&#39;,&#39;good&#39;,&#39;morning!&#39;,n = 3)

# 출력 결과
# hello,
# world!
# good
# morning!
# -
# hello,
# world!
# good
# morning!
# -
# hello,
# world!
# good
# morning!
# -

# ---------------------------------------- #

def test(a,b = 10,c = 100):
    print(a + b + c)

# a는 일반 매개변수이므로 해당 위치에 반드시 입력해야함
# 기본 매개변수는 필요한 것만 키워드를 지정해서 입력해주는 편

test(10,20,30) 
test(a = 10,b = 100,c = 200)
test(c = 10,a = 100,b = 200)
test(10,c = 200)

# 출력 결과
# 60
# 310
# 310
# 220

# ---------------------------------------- #

def sumAll(start = 0,end = 100,step = 1):
    output = 0
    for i in range(start,end + 1,step):
        output += i
    return output

print(&#39;a.&#39;,sumAll(10,70,10))
print(&#39;b.&#39;,sumAll(end = 99))
print(&#39;c.&#39;,sumAll(end = 99,step = 2))

# 출력 결과
# a. 280
# b. 4950
# c. 2450</code></pre>
<h2 id="리스트-평탄화">[리스트 평탄화]</h2>
<pre><code class="language-python">def flatten(data):
    output = []
    for item in data:
        if type(item) == list:
            output += flatten(item)
        else:
            output.append(item)
    return output

example = [[1, 2, 3], [4, [5, 6]], 7, [8, 9]]
print(&#39;원본: {}&#39;.format(example))
print(&#39;변환: {}&#39;.format(flatten(example)))

# 출력 결과:
# 원본: [[1, 2, 3], [4, [5, 6]], 7, [8, 9]]
# 변환: [1, 2, 3, 4, 5, 6, 7, 8, 9]</code></pre>
<ul>
<li>함수의 변수는 함수 호출마다 따로따로 만들어진다.</li>
<li>함수가 끝나면 (리턴 되면) 함수를 호출했던 위치로 돌아옵니다.</li>
</ul>
<h2 id="튜플">[튜플]</h2>
<pre><code class="language-python"># 괄호를 생략해도 튜플로 인식할 수 있는 경우는 괄호를 생략해도 된다.
tupleTest = 10, 20, 30, 40
print(&#39;tupleTest: {}&#39;.format(tupleTest))
print(&#39;type(tupleTest): {}&#39;.format(type(tupleTest)))

a, b, c = 10, 20, 30
print(&quot;a: {}, b: {}, c: {}&quot;.format(a, b, c))

# ---------------------------------------- #

****# 함수의 리턴에 튜플을 사용하면 여러 개의 값을 리턴하고 할당할 수 있다.
def test():
    return (10, 20)
a, b = test()

print(&#39;a: {}, b: {}&#39;.format(a, b))****

# ---------------------------------------- #

# &lt;튜플의 활용&gt;

for i, value in enumerate([&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;, &#39;e&#39;, &#39;f&#39;]):
    print(&#39;{}번째 요소는 {}입니다.&#39;.format(i, value))

# 출력 결과:
# 0번째 요소는 a입니다.
# 1번째 요소는 b입니다.
# 2번째 요소는 c입니다.
# 3번째 요소는 d입니다.
# 4번째 요소는 e입니다.
# 5번째 요소는 f입니다.

# ---------------------------------------- #

# 몫과 나머지를 구하는 divmod() 함수: 튜플을 리턴

a, b = 97, 40
print(divmod(a, b))
x, y = divmod(a, b)
print(&#39;x: {}, y: {}&#39;.format(x, y))

# 출력 결과
# (2, 17)
# x: 2, y: 17</code></pre>
<h2 id="콜백-함수">[콜백 함수]</h2>
<p>: 함수의 매개변수에 사용하는 함수</p>
<pre><code class="language-python"># 매개변수로 받은 함수를 10번 호출
def call_3_times(func):
    for i in range(3):
        func()
def printHello():
    print(&#39;Hello&#39;)

# 조합하기
call_3_times(printHello)

# 출력 결과:
# Hello
# Hello
# Hello</code></pre>
<h2 id="람다">[람다]</h2>
<pre><code class="language-python"># map(): 리스트의 요소를 함수에 넣고 리턴된 값으로 새로운 리스트를 구성
# filter(): 리스트의 요소를 함수에 넣고 리턴된 값이 True인 것으로, 새로운 리스트를 구성
# 형식: map(함수_명, 리스트_명) | filter(함수_명, 리스트_명)

def power(item):
    return item * item
def under3(item):
    return item &lt; 3

# 대신

power = lambda x: x * x
under3 = lambda x: x &lt; 3

# 람다 사용법 &gt;&gt; lambda 매개변수_명 : 리턴값

listInputA = [1,2,3,4,5]

outputA = map(power, listInputA)
print(&#39;map(power, listInputA):&#39;, outputA)
print(&#39;map(power, listInputA):&#39;, list(outputA))

outputB = filter(under3, listInputA)
print(&#39;filter(under3, listInputA):&#39;, outputB)
print(&#39;filter(under3, listInputA):&#39;, list(outputB))

# 출력 결과:
# map(power, listInputA): &lt;map object at 0x000001D4560B7C70&gt;
# map(power, listInputA): [1, 4, 9, 16, 25]
# filter(under3, listInputA): &lt;filter object at 0x000001D456C4B7C0&gt;
# filter(under3, listInputA): [1, 2]

# ---------------------------------------- #

# 인라인 람다
# 함수를 선언하지도 않고 매개변수로 바로 입력

outputA = map(lambda x: x * x, listInputA)
outputB = filter(lambda x: x &lt; 3, listInputA)</code></pre>
<h2 id="파일-입출력">[파일 입출력]</h2>
<pre><code class="language-python"># &lt;쓰기&gt;

file = open(&#39;basic.txt&#39;, &#39;w&#39;)
file.write(&#39;Hi there!&#39;)
file.close()
# 또는
with open(&#39;basic.txt&#39;, &#39;w&#39;) as file:
    file.write(&#39;Hi there!&#39;)

# ---------------------------------------- #

# &lt;읽기&gt;

file = open(&#39;basic.txt&#39;, &#39;r&#39;)
contents = file.read()
print(contents)
# 또는
with open(&#39;basic.txt&#39;, &#39;r&#39;) as file:
    contents = file.read()
print(contents)

# ---------------------------------------- #

import random as rand

hanguls = list(&#39;가나다라마바사아자차카타파하&#39;)

with open(&#39;info.txt&#39;, &#39;w&#39;) as file:
    for i in range(1000):
        name = rand.choice(hanguls) + rand.choice(hanguls)
        weight = rand.randrange(40, 100)
        height = rand.randrange(140, 200)

        file.write(&#39;{}, {}, {}\n&#39;.format(name, weight, height))

with open(&#39;info.txt&#39;, &#39;r&#39;) as file:
    for line in file:
        (name, weight, height) = line.strip().split(&#39;,&#39;)

        # 데이터가 문제가 없는지 확인합니다: 문제가 있으면 지나감
        if (not name) or (not weight) or (not height):
            continue

        bmi= int(weight) / (int(weight) / 100) ** 2
        result = &#39;&#39;
        if 25 &lt;= bmi:
            result = &#39;과체중&#39;
        elif 18.5 &lt;= bmi:
            result = &#39;정상 체중&#39;
        else:
            result = &#39;저체중&#39;

        print(&#39;\n&#39;.join([
            &#39;이름: {}&#39;, 
            &#39;몸무게: {}&#39;,
            &#39;키: {}&#39;,
            &#39;BMI: {:.2f}&#39;,
            &#39;결과: {}&#39;
        ]).format(name, weight, height, bmi, result))

# N줄만 출력하려면: count를 하나씩 늘려가서 N만큼 출력되면 break 되도록 수정하면 됨!</code></pre>
<h2 id="제너레이터">[제너레이터]</h2>
<p>: 함수의 코드를 조금씩 실행할 때 사용. 메모리 효율성을 위해서. 제너레이터와 이터레이터는 완전히 같지는 않지만 기본적인 단계에서는 거의 비슷하다고 봐도 무방함.</p>
<pre><code class="language-python">def test():
    print(&#39;A 지점 통과&#39;)
    yield 1
    print(&#39;B 지점 통과&#39;)
    yield 2
    print(&#39;C 지점 통과&#39;)

output = test()

print(&#39;D 지점 통과&#39;)
a = next(output)
print(a)

print(&#39;E 지점 통과&#39;)
b = next(output)
print(b)

print(&#39;F 지점 통과&#39;)
c = next(output)
print(c)

next(output)

# 실행 결과:
# D 지점 통과
# A 지점 통과
# 1
# E 지점 통과
# B 지점 통과
# 2
# F 지점 통과
# C 지점 통과
# ---------------------------------------------------------------------------
# StopIteration                             Traceback (most recent call last)
# ~\AppData\Local\Temp\ipykernel_21056\1173299310.py in &lt;module&gt;
#      17 
#      18 print(&#39;F 지점 통과&#39;)
# ---&gt; 19 c = next(output)
#      20 print(c)
#      21 
# 
# StopIteration:</code></pre>
<h2 id="global">[global]</h2>
<pre><code class="language-python">global a
a = 10

def func():
    global a 
    print(a) # 함수 내부에서 함수 외부에 있는 변수를 출력
    a = 20 # 함수 외부에 있는 번수의 값을 교체

func()
print(a)

# 실행 결과:
# 10
# 20

# global 키워드를 사용하지 않으면 &#39;UnboundLocalError&#39;를 발생시킴</code></pre>
<h2 id="예외-처리">[예외 처리]</h2>
<ul>
<li>예외 / 런타임 오류: 프로그램 실행 중에 발생하는 오류</li>
<li>방법<ul>
<li>조건문 사용</li>
<li>try 구문 사용</li>
</ul>
</li>
</ul>
<pre><code class="language-python">- 조건문 사용

userInputA = input(&#39;정수 입력&#39;)

if userInputA.isdigit(): # 0이상의 정수를 입력받았을 때만 작동
    numberInputA = int(userInputA)

    print(&#39;원의 반지름&gt;&gt;&#39;, numberInputA)
    print(&#39;원의 둘레&gt;&gt; {:.2f}&#39;.format(2 * 3.14 * numberInputA))
    print(&#39;원의 넓이&gt;&gt; {:.2f}&#39;.format(3.14 * numberInputA * numberInputA))
else:
    print(&#39;정수를 입력하지 않았습니다.&#39;)

# ---------------------------------------- #

- try except 구문

try:
    numberInputA = int(input(&#39;정수 입력&gt;&gt;&#39;))

    print(&#39;원의 반지름&gt;&gt;&#39;, numberInputA)
    print(&#39;원의 둘레&gt;&gt; {:.2f}&#39;.format(2 * 3.14 * numberInputA))
    print(&#39;원의 넓이&gt;&gt; {:.2f}&#39;.format(3.14 * numberInputA * numberInputA))
except:
    print(&#39;무언가 잘못되었습니다&#39;)

# ---------------------------------------- #

- try except else finally 구문

- 형식:
            try:
                예외가 발생할 가능성이 있는 코드
            except:
                예외가 발생했을 때 실행할 코드
            else:
                예외가 발생하지 않았을 때 실행할 코드
            finally:
                무조건 실행할 코드

try:
  numberInputA = int(input(&#39;정수 입력&gt;&gt;&#39;))

        print(&#39;원의 반지름&gt;&gt;&#39;, numberInputA)
      print(&#39;원의 둘레&gt;&gt; {:.2f}&#39;.format(2 * 3.14 * numberInputA))
      print(&#39;원의 넓이&gt;&gt; {:.2f}&#39;.format(3.14 * numberInputA * numberInputA))
except:
        print(&#39;정수를 입력하지 않았습니다!&#39;)
else:
      print(&#39;예외가 발생하지 않았습니다.&#39;)
finally:
        print(&#39;일단 프로그램이 어떻게든 끝났습니다.&#39;)

# 규칙:
# 1. try 구문은 단독으로 사용할 수 없으며, 반드시 except 구문 또는 finally 구문과 함께 사용
# 2. else 구문은 반드시 except 구문 뒤에 사용
# (즉, try else 구문은 불가능)

# finally 키워드는 굳이 없어도 되지만 코드 정리를 위해 사용한다
# try 구문 내부에서 return 키워드로 중간에서 탈출해도 finally 구문은 반드시 실행

def test():
    print(&#39;1st line of test()&#39;)
    try:
        print(&#39;try&#39;)
        return
        print(&#39;next to try&#39;)
    except:
        print(&#39;except&#39;)
    else:
        print(&#39;else&#39;)
    finally:
        print(&#39;finally&#39;)
    print(&#39;end line of test()&#39;)

test()

# 실행 결과:
# 1st line of test()
# try
# finally</code></pre>
<h2 id="예외-고급">[예외 고급]</h2>
<pre><code class="language-python">#예외 객체

try:
    numberInputA = int(input(&#39;정수 입력&gt;&gt;&#39;))

    print(&#39;원의 반지름&gt;&gt;&#39;, numberInputA)
    print(&#39;원의 둘레&gt;&gt; {:.2f}&#39;.format(2 * 3.14 * numberInputA))
    print(&#39;원의 넓이&gt;&gt; {:.2f}&#39;.format(3.14 * numberInputA * numberInputA))

except Exception as exception:
    print(&#39;type(exception):&#39;, type(exception))
    print(&#39;exception:&#39;, exception)

# 실행 결과:
# 정수 입력&gt;&gt; yes
# type(exception): &lt;class &#39;ValueError&#39;&gt;
# exception: invalid literal for int() with base 10: &#39;yes&#39;

# ---------------------------------------- #

# 예외 구분하기

listNumber = [52, 273, 32, 72, 100]

try:
    numberInput = int(input(&#39;정수 입력&gt;&gt;&#39;))
    print(&#39;{}번째 요소: {}&#39;.format(numberInput, listNumber[numberInput]))
except ValueError:
    print(&#39;정수를 입력해주세요!&#39;)
except IndexError:
    print(&#39;리스트의 인덱스를 벗어남.&#39;)

# ---------------------------------------- #

# 모든 예외 잡기

listNumber = [52, 273, 32, 72, 100]

try:
    numberInput = int(input(&#39;정수 입력&gt;&gt;&#39;))
    print(&#39;{}번째 요소: {}&#39;.format(numberInput, listNumber[numberInput]))
    예외.발생해주세요()

except ValueError as exception:
    print(&#39;정수를 입력해주세요!&#39;)
    print(type(exception), excpetion)
except IndexError as exception:
    print(&#39;리스트의 인덱스를 벗어남.&#39;)
    print(type(exception), excpetion)
except Exception as exception:
    print(&#39;미리 파악하지 못한 예외가 발생했습니다.&#39;)
    print(type(exception), exception)</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[C++ 중간고사 정리]]></title>
            <link>https://velog.io/@meer_/C-%EC%A4%91%EA%B0%84%EA%B3%A0%EC%82%AC-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@meer_/C-%EC%A4%91%EA%B0%84%EA%B3%A0%EC%82%AC-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Fri, 30 Jun 2023 00:07:03 GMT</pubDate>
            <description><![CDATA[<ol>
<li>챕터 3의 실습문제 2: find substr stoi 쓰는 법<pre><code class="language-cpp">Date::Date(string s) {
 int index = s.find(&#39;/&#39;);
 year = stoi(s.substr(0, index));
 s = s.substr(index + 1);
 index = s.find(&#39;/&#39;);
 month= stoi(s.substr(0, index));
 s = s.substr(index + 1);
 day = stoi(s);
}</code></pre>
</li>
<li>챕터 3의 실습문제 5: 일정 범위 내의 난수 생성</li>
</ol>
<ul>
<li>cstdlib ctime 포함시키기</li>
<li>srand((unsigned)time(0)); 으로 시드 초기화</li>
<li>rand() 로 난수 생성</li>
<li>a~b사이: rand() % (b - a + 1) + a<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;cstdlib&gt;
#include &lt;ctime&gt;
using namespace std;
</code></pre>
</li>
</ul>
<p>class Random {
public:
    Random();
    int next();
    int nextInRange(int, int);
};
Random::Random() {
    srand((unsigned)time(0));
} //시드 초기화
int Random::next() {
    return rand();
} //0<del>32767 사이의 난수
int Random::nextInRange(int a, int b) {
    return rand() % (b - a + 1) + a;
} //a</del>b 사이의 난수
int main() { //난수 10개 생성
    Random r;</p>
<pre><code>for (int i = 0; i &lt; 10; i++) {
    cout &lt;&lt; r.next() &lt;&lt; &#39; &#39;;
}
cout &lt;&lt; endl;
for (int i = 0; i &lt; 10; i++) {
    cout &lt;&lt; r.nextInRange(2, 4) &lt;&lt; &#39; &#39;;
}
cout &lt;&lt; endl;</code></pre><p>}</p>
<pre><code>3. 챕터 4의 실습문제 3(2): find 함수 사용하기
```cpp
#include &lt;iostream&gt;
#include &lt;string&gt;
using namespace std;

int main() {

    string str;
    int count = 0;
    cout &lt;&lt; &quot;문자열 입력&gt;&gt;&quot;;
    getline(cin, str);
    int found = str.find(&#39;a&#39;);
    while (found != -1) {
        count++;
        found = str.find(&#39;a&#39;, found + 1);
    }

    cout &lt;&lt; &quot;문자 a는 &quot; &lt;&lt; count &lt;&lt; &quot;개 있습니다.&quot; &lt;&lt; endl;

    return 0;
}</code></pre>]]></description>
        </item>
        <item>
            <link>https://velog.io/@meer_/1q193fhw</link>
            <guid>https://velog.io/@meer_/1q193fhw</guid>
            <pubDate>Sun, 11 Jun 2023 04:06:30 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/meer_/post/5a3b7aaf-e17e-4b46-9935-3f621b28eafa/image.jpg" alt=""></p>
]]></description>
        </item>
        <item>
            <link>https://velog.io/@meer_/o1b8v83h</link>
            <guid>https://velog.io/@meer_/o1b8v83h</guid>
            <pubDate>Sun, 11 Jun 2023 04:05:58 GMT</pubDate>
            <description><![CDATA[<p><img src="blob:https://velog.io/0c5c0a24-1bd3-42f9-8233-e2cf44d3232e" alt="업로드중.."></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[자료구조 기말고사]]></title>
            <link>https://velog.io/@meer_/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EA%B8%B0%EB%A7%90%EA%B3%A0%EC%82%AC</link>
            <guid>https://velog.io/@meer_/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EA%B8%B0%EB%A7%90%EA%B3%A0%EC%82%AC</guid>
            <pubDate>Fri, 09 Jun 2023 11:35:47 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-cpp">// 7.순환
int factorial(int n) {
    if (n == 1)return 1;
    else retrun n* factorial(n - 1);
}
int factorialIter(int n) {
    int result = 1;
    for (int k = n; k &gt; 0; k--)
        result = result * k;
    return result;
}
//순환:함수 호출 오버헤드
//반복: 수행속도 빠르지만 순환 구현 어려움
//순환 &gt;&gt; 반복 가능
//거듭제곱: 순환 O(logn) | 반복 O(n)
int fibo(int n) {
    if (n == 0)return 0;
    if (n == 1)return 1;
    else return fibo(n - 1) + fibo(n - 2);
} //O(n)

//8.트리
//포화 이진 트리: 각 레벨에 노드가 꽉 차있음(2^h-1)
//완전 이진 트리: 상위 레벨 꽉 차있고 마지막 레벨 왼쪽부터 순서대로
bool isLeaf() { return left == NULL &amp;&amp; right == NULL; }
bool isEmpty() { return root == NULL; }
int getCount() { return isEmpty() ? 0 : getCount(root); }
int getCount(BinaryNode* node) {
    if (node == NULL)return 0;
    return 1 + getCount(node-&gt;getLeft()) + getCount(node-&gt;getRight());
}
int getLeafCount() { return isEmpty() ? 0 : getLeafCount(root); }
int getLeafCount(BinaryNode* node) {
    if (node == NULL)return 0;
    if (node-&gt;isLeaf() == true) return 1;
    else getLeafCount(node-&gt;getLeft()) + getLeafCount(node-&gt;getRight());
}
int getHeight() { return isEmpty() ? 0 : getHeight(root); }
int getHeight(BinaryNode* node) {
    if (node == NULL) return 0;
    int hLeft = getHeight(node-&gt;getLeft());
    int hRight = getHeight(node-&gt;getRight());
    return hLeft &gt; hRight ? hLeft + 1 : hRight + 1;
} //트리 높이 = 서브 트리 높이 + 1

/*
- 전위: VLR    룻왼오
- 중위: LVR 왼룻오
- 후위: LRV 왼오룻
*/
class BinaryTree {
    //...
    void preorder() { preorder(root); }
    void preorder(BinaryNode* node) {
        if (node == NULL) {
            printf(&quot;%c&quot;, node-&gt;getData);
            if (node-&gt;getLeft() != NULL)preorder(node-&gt;getLeft);
            if (node-&gt;getRight() != NULL)preorder(node-&gt;getRight);
        }
    }
    void inorder() { inorder(root); }
    void inorder(BinaryNode* node) {
        if (node == NULL) {
            if (node-&gt;getLeft() != NULL)inorder(node-&gt;getLeft());
            printf(&quot;%c&quot;, node-&gt;getData());
            if (node-&gt;getRight() != NULL)inorder(node-&gt;getRight());
        }
    }
    void postorder() { postorder(root); }
    void postorder(BinaryNode* node) {
        if (node-&gt;getLeft() != NULL)postorder(node-&gt;getLeft());
        if (node-&gt;getRight() != NULL)postorder(node-&gt;getRight());
        printf(&quot;%c&quot;, node-&gt;getData());
    }
    void levelorder() {
        if (!isEmpty()) {
            CircularQueue q;
            while(!q.isEmpty()) {
                BinaryNode* n = q.dequeue();
                if (n != NULL) {
                    printf(&quot;%c&quot;, n-&gt;getData());
                    q.enqueue(n-&gt;getLeft());
                    q.enqueue(n-&gt;getRight());
                }
            }
        } //위에서부터 한줄한줄 읽기
        printf(&quot;\n&quot;);
    }
};
//수식 트리 계산
int evaluate() { return evaluate(root); }
int evaluate(BinaryNode* node) {
    if (node == NULL)return 0;
    else {
        int op1 = evaluate(node-&gt;getLeft());
        int op2 = evaluate(node-&gt;getRight());
        switch (node-&gt;getData()) {
            //...
        }
    }
    return 0;
}
//파일 용량 계산: 후위 순회
int calcSize(BinaryNode* node) {
    if (node == NULL)return 0;
    return node-&gt;getData() 
        + calcSize(node-&gt;getLeft()) 
        + calcSize(node-&gt;getRight());
}

//9. 이진 탐색 트리
//: 중위순회(inorder) = 오름차순 정렬
BinaryNode* searchRecur(BinaryNode* n, int key) {
    if (n == NULL)reutrn NULL;
    if (key == n-&gt;getData())return n;
    else if (key &lt; n-&gt;getData())
        searchRecur(n-&gt;getLeft(), key);
    else searchRecur(n-&gt;getRight(), key);
}
BinaryNode* searchIter(BinaryNode* n, int key) {
    while (n != NULL) {
        if (key == n-&gt;getData()) return n;
        else if (key &lt; n-&gt;getData())
            n = n-&gt;getLeft();
        else n = n-&gt;getRight();
    }
    return NULL;
}

//삭제 함수 중 삭제 하려는 노드가 자식을 하나만 가진 경우
else if (node-&gt;getLeft() == NULL || node-&gt;getRight() == NULL) {
    BinaryNode* child = (node-&gt;getLeft() != NULL) ? 
                        node-&gt;getLeft() : node-&gt;getRight();
    if (node == root)root = child;
    else {
        if (parent-&gt;getLeft() == node)
            parent-&gt;setLeft(child);
        else parent-&gt;setRight(child);
    }
}
/*
&gt;&gt; 이진 탐색 트리의
- 최선 : 균형, h = logn, O(logn)
- 최악: 경사, h = n, O(n)
*/
//사전
int compare(Record* n) { return compare(n-&gt;word); }
int compare(char* w) { return strcmp(w, word); }

//10. 우선 순위 큐: 힙으로 구현 - 완전 이진 트리, 반 정렬 상태 유지
void heapify(int current) { //최소 힙으로 변환
    int leftChild = 2 * current + 1;
    int rightChild = 2 * current + 2;
    int smallest = current;

    if (leftChild &lt; heap.size()
        &amp;&amp; heap[leftChild] &lt; heap[smallest])
            smallest = leftChild;
    if (rightChild &lt; heap.size()
        &amp;&amp; heap[rightChild] &lt; heap[smallest])
            smallest = rightChild;
    if (smallest != current) {
        swap(heap[current], heap[smallest]);
        heapify(smallest);
    }
}
void insert(int key) {//삽입: Upheap
    if (isFull())retrun;
    int i = ++size;

    /*
    트리 거슬러 올라가면서 부모 노드와 비교
    루트가 아니고 부모보다 키값이 크면 부모를 끌어내리고
    한 레벨 위로 상승
    */
    while (i != 1 &amp;&amp; key &gt; getParent(i).getKey()) {
        node[i] = getParent(i);
        i /= 2;
    }
    node[i].setKey(key); //최종 위치에 데이터 복사
}
HeapNode remove() { //삭제: Downheap - ;루트&#39;가 삭제됨
    if (isEmpty())error();
    HeapNode item = node[1]; //루트 노드 (꺼낼 요소)
    HeapNode last = node[size--]; //힙의 마지막 노드
    int parent = 1; //마지막 노드의 위치를 루트로 생각함
    int child = 2; //루트의 왼쪽 자식 위치
    while (child &lt;= size) { //힙 트리를 벗어나지 않는 동안
        if (child &lt; size    //큰 값을 오른쪽 자식이 갖고 있음
            &amp;&amp; getLeft(parent).getKey() &lt; getRight(parent).getKey())
                child++;
        if (last.getKey() &gt;= node[child].getKey())
            break;

        //한 단계 아래로 이동
        node[parent] = node[child];
        parent = child;
        child *= 2;
    }
    node[parent] = last; //마지막 노드를 최종 위치에 저장
    return item; //루트 노드 반환
}
/*
&lt;힙의 시간 복잡도&gt;
: 삽입 최악 = 삭제 최악 = O(logn)
-&gt; 힙 정렬: O(nlogn)
*/

//11.그래프
//완전그래프: 모든 정점이 연결돼있는 그래프
//간선 수: (n*(n-1))/2

//인접 행렬 이용
void insertVertex(char name) { //정점 삽입
    if (!isFull()) vertices[size++] = name;
    else printf(&quot;그래프 정점 개수 초과!&quot;);
}
void insertEdge(int u, int v) { //간선 삽입
    setEdge(u, v, 1);
    setEdge(v, u, 1);
}
class SrchAMGraph :public AdjMatGraph { //인접 행렬로 DFS
protected:
    bool visited[MAX_VTXS];
public:
    void resetVisited() {
        for (int i = 0; i &lt; size; i++)
            visited[i] = false;
    }
    bool isLinked(int u, int v) { return getEdge(u, v) != 0; }
    void DFS(int v) {
        visited[v] = true;
        printf(&quot;%c&quot;, getVertex(v));
        for (int w = 0; w &lt; size; w++) {
            if (isLinked(v, w) &amp;&amp; visited[w] == false) DFS(w);
        }
    }
};
void BFS(int v){ //인접 ㅎ행렬로 BFS 구현
    visited[v] = true;
    printf(&quot;%c&quot;, getVertex(v));
    CircularQueue q;
    q.enqueue(v);
    while (!q.isEmpty()) {
        int v = q.dequeue();
        for (int w = 0; w &lt; size; w++) {
            if (isLinked(v, w) &amp;&amp; visited[w] == false) {
                visited[w] = true;
                printf(&quot;%c&quot;, getVertex(w));
                q.enqueue(w);
            }
        }
    }
}
class ConnectedComponentGraph :public SrchAMGramp {
private:
    int label[MAX_VTXS];
public:
    void labelDFS(int v, int color) {
        visited[v] = true;
        label[v] = color;
        for (int w = 0; w &lt; size; w++) {
            if (isLinked(v, w) &amp;&amp; visited[w] == false)
                labelDFS(w, color);
        }
    }
    void findConnectedComponent() {
        int count = 0;
        for (int i = 0; i &lt; size; i++) {
            if (visited[i] == false)
                labelDFS(i, ++count);
        }
        printf(&quot;그래프 연결 성분 개수: %d\n&quot;, count);
        for (int i = 0; i &lt; size; i++)
            printf(&quot;%c = %d&quot;, getVertex(i), label[i]);
        printf(&quot;\n&quot;);
    }
};

//14. 탐색
/*
&lt;맵 구현&gt;
1. 정렬되지 않은 배열 사용
2. 정렬된 배열 사용
3. 이진탐색트리 이용 (AVL)**
4. 해싱 이용**

- 이진 탐색: 자료들이 배열에 저장 -&gt; 삽입/삭제 비효율
- 이진 탐색 트리: 빠르게 삽입/삭제

&lt;AVL&gt;
- 모든 노드의 왼쪽 오른쪽 서브트리 높이차가 1 이하인 이진 탐색 트리
- 스스로 재배치하여 균형 상태 유지

&lt;LL회전&gt;
1. B의 오른쪽 자식을 A의 왼쪽 자식으로 만든다
2. A를 B의 오른쪽 자식으로 만든다
*/
if (hDiff &gt; 1) {
    if (getHeightDiff(parent-&gt;getLeft()) &gt; 0)
        parent = rotateLL(parent);
    else parent = rotateLR(parent);
}
BinaryNode* rotateLL(BinaryNode* parent) {
    BinaryNode* child = parent-&gt;getRight();
    child-&gt;setRight(parent);
    return child;
}
void insert(int data) {
    if (isEmpty()) root = new BinaryNode(data);
    else root = insertAVL(root, data);
}
BinaryNode* insertAVL(BinaryNode* parent, int data) {
    if (data &lt; parent-&gt;getData()) {
        if (parent-&gt;getLeft() != NULL)
            parent-&gt;setLeft(insertAVL(parent-&gt;getLeft(), data));
        else parent-&gt;setLeft(new BinaryNode(data));
        return reBalance(parent);
    }
    else if (data &gt; parent-&gt;getData()) {
        if (parent-&gt;getLeft() != NULL)
            parent-&gt;setRight(insertAVL(parent-&gt;getRight(), data));
        else parent-&gt;setRight(new BinaryNode(data));
        return reBalance(parent);
    }
    else {
        printf(&quot;중복 키 에러!&quot;);
        return NULL;
    }
}
/*
&lt;해싱&gt;
- 좋은 해시 함수의 조건
    1. 충돌이 적어야함
    2. 함수 값이 테이블 주소 영역 내에 고르게 분포
    3. 계산이 빨라야함
- 오버플로우 처리 방법
    1. 선형 조사법
    : 충돌이 일어난 해시 테이블의 다른 위치를 찾아 저장
    -&gt; 간단하지만 군집화 현상으로 효율 저하
    -&gt; 이차 조사법, 이중 해싱법(재해싱)
    2. 체이닝
    : 각 버킷에 삽입/삭제가 용이한 &#39;연결 리스트&#39; 할당
*/</code></pre>
<hr>
<h2 id="a순환">A.순환</h2>
<ul>
<li>순환: O(logn) | 함수 호출 오버헤드</li>
<li>반복: O(n) | for/while을 이용해 수행속도가 빠르지만 순환적인 문제에서 프로그램 작성이 복잡함</li>
<li>순환 -&gt; 반복 가능<blockquote>
<p>피보나치 수열
: 순환호출이 비효율적임 &lt;- 같은 항 중복 계산</p>
</blockquote>
<pre><code class="language-cpp">  int fib(int n){
      if(n == 0) return 0;
      if(n == 1) return 1;
      return (fib(n-1) + fib(n-2));
  }</code></pre>
<h2 id="b트리---이진트리">B.트리 - 이진트리</h2>
</li>
<li>차수: 노드의 자식 노드의 개수</li>
</ul>
<ol>
<li>n개의 노드를 가진 트리는 n-1개의 간선을 가짐</li>
<li>높이가 h: 최소 h개, 최대 2^h-1개의 노드를 가짐</li>
<li>n개의 노드를 가진 트리의 최대 높이는 n, 최소 높이는 |log(n+1)|</li>
</ol>
<pre><code class="language-cpp">&gt;    bool isLeaf() { return left == NULL 
                        &amp;&amp; right == NULL; }</code></pre>
<ul>
<li><p>이진트리의 기본 순회
  a) 전위(preorder): 루트 - 왼쪽 - 오른쪽 (VLR)
  b) 중위(inorder): 왼쪽 - 루트 - 오른쪽 (LVR)
  c) 후위(postorder): 왼쪽 - 오른쪽 - 루트 (LRV)</p>
<pre><code class="language-cpp">  [예시]: inorder
  void inorder(BinaryNode* node{
      if(node != NULL){
          if(node-&gt;getLeft() != NULL){
              inorder(node-&gt;getLeft());
          }

          printf(&quot; [%c] &quot;, node-&gt;getData());

          if(node-&gt;getRight() != NULL){
              inorder(node-&gt;getRight());
          }
      }
  }

  [예시]: levelorder - &#39;큐&#39; 사용
  void levelorder(){
      if(!isEmpty()){
          CircularQueue q;
          q.enqueue(root);
          while(!q.isEmpty()){
              BinaryNode* n = q.dequeue();
              if(n != NULL){
                  printf(&quot; [%c] &quot;, n-&gt;getData());
                  q.enqueue(n-&gt;getLeft());
                  q.enqueue(n-&gt;getRight());
              }
          }
      }
      printf(&quot;\n&quot;);
     }</code></pre>
<p><img src="https://velog.velcdn.com/images/meer_/post/444c7aa4-2ff2-479e-b928-e994297665a3/image.png" alt=""></p>
</li>
<li><p>노드 개수 계산 - getCount()함수</p>
<pre><code class="language-cpp">  int getCount(){ return isEmpty() ? 0 : getCount(root); }
  int getCount(BinaryNode* node){
      if(node == NULL) return 0;

      return 1 + getCount(node-&gt;getLeft())
               + getCount(node-&gt;getRight());
  }</code></pre>
</li>
<li><p>단말 노드 개수 계산 - getLeafCount()함수</p>
<pre><code class="language-cpp">  int getLeafCount(){ return isEmpty() ? 0 : getLeafCount(root); }
  int getLeafCount(){
      if(node == NULL) return 0;

      if(node-&gt;isLeaf()) retrun 1;

      else return getLeafCount(node-&gt;getLeft())
                  + getLeafCount(node-&gt;getRight());
  }</code></pre>
</li>
<li><p>트리 높이: 서브트리 높이 + 1</p>
<pre><code class="language-cpp">  int getHeight(){ return isEmpty() ? 0 : getHeight(root); }
  int getHeight(BinaryNode* node){
      if(node == NULL) return 0;

      int hLeft = getHeight(node-&gt;getLeft());
      int hRight = getHeight(node-&gt;getRight());

      return (hLeft &gt; hRight) ? hLeft + 1 : hRight + 1;
  }

  +) hLeft == hRight인 경우: root 노드만 있을 때</code></pre>
</li>
<li><p>수식트리의 계산</p>
<pre><code class="language-cpp">  int evaluate() { return evaluate(root); }
  int evaluate(BinaryNode* node){
      if(node == NULL) return 0;
      else{
          int op1 = evaluate(node-&gt;getLeft());
          int op2 = evaluate(node-&gt;getRight());
          switch(node-&gt;getData){
              ...
          }
          return 0;
      }
  }</code></pre>
</li>
<li><p>폴더 용량 계산: 후위 순회</p>
<pre><code class="language-cpp">  int calcSize(BinaryNode* node){
      if(node == NULL) return 0;

      return node-&gt;getData()
              + calcSize(node-&gt;getLeft())
              + calcSize(node-&gt;getRight());
  }</code></pre>
<h2 id="c-이진-탐색-트리">c. 이진 탐색 트리</h2>
</li>
<li><p>왼쪽서브트리key &lt;= 루트key &lt;= 오른쪽서브트리key</p>
</li>
<li><p><strong>중위 순회 -&gt; 오름차순으로 정렬</strong></p>
</li>
<li><p>탐색 연산
  a) 키값이 루트와 같으면: 탐색 끝!
  b) 키값이 루트보다 작으면: 왼쪽 자식 기준으로 재탐색
  c) 키값이 루트보다 크면: 오른쪽 자식 기준으로 재탐색</p>
<pre><code class="language-cpp">  [반복으로 구현한 탐색 함수]
  BinaryNode* searchlter(BinaryNode* n, int key){
      while(n != NULL){
          if(key == n-&gt;getData()) return n;
          else if(key &lt; n-&gt;getData()) n = n-&gt;getLeft();
          else n = n-&gt;getRight();
      }
      return NULL;
  }

  [순환으로 구현한 탐색 함수]
  void insertRecur(BinaryNode* r, BinaryNode* n){
      if(n-&gt;getData() == r-&gt;getData()) return;
      elseif(n-&gt;getData() &lt; r-&gt;getData()){
          if(r-&gt;getLeft() == NULL) r-&gt;setLeft(n);
          else insertRecur(r-&gt;getLeft(), n);
      }
      else{
          if(r-&gt;getRight() == NULL) r-&gt;setRight(n);
          else insertRecur(r-&gt;getRight(), n));
      ]
  }

  [삭제함수에서...] 
  삭제하려는 노드가 왼쪽 또는 오른쪽 자식만 가진 경우 
  -&gt; 부모 노드의 자식으로 자식노드의 자식을 직접 연결
      if(node == root) root = child;</code></pre>
</li>
<li><p>성능 분석
  a) 최선: h = logn | O(logn)
  b) 최악: h = n | O(n)</p>
</li>
</ul>
<p>[영어사전]</p>
<ul>
<li>오름차순(inorder)으로 출력<pre><code class="language-cpp">  int compare(Record* n) { return compare(n-&gt;word); }
  int compare(char* w) { return strcmp(w, word) }</code></pre>
</li>
<li>탐색/삽입에서<pre><code class="language-cpp">  ...
  if(n-&gt;compare(r) == 0) return;
  else if(n-&gt;compare(r) &gt; 0)
  ...</code></pre>
</li>
<li>삭제에서<pre><code class="language-cpp">  ...
  while(node != NULL &amp;&amp; node-&gt;compare(data) != 0){
      parent = node;
      node = (node-&gt;compare(data) &lt; 0) ? 
              node-&gt;getleft() : node-&gt;getright();
 ...</code></pre>
<h2 id="d-우선순위-큐---힙">D. 우선순위 큐 - 힙</h2>
  a) 완전이진트리의 일종
  b) 우선순위 큐를 위해 만들어진 자료구조
  c) 일종의 &#39;반 정렬 상태&#39; 유지
  d) 삽입/삭제 모두 최악의 경우에 O(logn)
  e) 최대 힙: 부모노드키값 &gt;= 자식노드키값<pre><code>    최소 힙: 부모노드키값 &lt;= 자식노드키값
 f) n개의 노드를 가지고 있는 힙의 높이는 O(logn)</code></pre>  g) 전체 정렬 보다는 가장 큰 값 몇게만 필요할 때 유용함</li>
<li>삽입 -&gt;  Upheap<pre><code class="language-cpp">  ...
  while(i != 1 &amp;&amp; key-&gt;getParent.getKey()){
      node[i] = getParent(i);
      i /= 2;
  }
  ...</code></pre>
</li>
<li>삭제: 항상 루트(가장 큰 값을 가진 노드)가 삭제됨! -&gt; Downheap<pre><code class="language-cpp">  ...
  if(child &lt; size &amp;&amp;
          getLeft(parent).getKey() &lt; getright(parent).getKey())
      child++;                    //큰 값을 오른쪽 자식이 갖고 있음
     if(last.getKey() &gt;= node[child].getKey()) 
      break;
  ...
</code></pre>
</li>
</ul>
<pre><code>- 힙 정렬
```cpp
    void heapSort(int a[], int n){
        MaxHeap h;
        ...
        //최대힙에서는 삭제시 가장 큰 값이 반환되므로
        //오름차순으로 정렬하기 위해서
        //삭제 항목을 배열의 끝부터 앞으로 채워나감
        for(int i = n-1; i &gt;= 0; i--)
            a[i] = h.remove()-&gt;getKey();
    }</code></pre><h2 id="e-그래프">E. 그래프</h2>
<ul>
<li><p>오일러 정리: 모든 정점에 연결된 간선의 수가 짝수이면 오일러 경로 존재함.</p>
</li>
<li><p>완전 그래프의 간선 수: (n x (n-1)) / 2</p>
<h5 id="1-인접-행렬adjacency-matrix">1. 인접 행렬(adjacency matrix)</h5>
<pre><code class="language-cpp">  void insertVertex(char name){
      if(!isFull()) vertices[size++] = name;
      else printf(&quot;Error: 그래프 정점 개수 초과!\n&quot;);
  }
  void insertEdge(int u, int v){
      setEdge(u,v,1);
      setEdge(v,u,1);
  }
  void display(FILE* fp = stdout){
      ...
     }</code></pre>
</li>
<li><p>DFS 구현</p>
<pre><code class="language-cpp">  class SrchAMGraph : public AdjMatGraph{
  protected:
      bool visited[MAX_VTXS];
  public:
      void resetVisited(){
          for(int i = 0; i &lt; size; i++)
              visited[i] = false;
      }
      bool isLinked(int u, int v){ return getEdge(u, v) != 0; }
      void DFS(int v){
          fisited[v] = true;
          printf(&quot;%c &quot;, getVertex(v));
          for(int w = 0; w &lt; size; w++)
              if(isLinked(v, w) &amp;&amp; visited[w] == false)
                  DFS(w);
      }
  }</code></pre>
</li>
<li><p>BFS 구현</p>
<pre><code class="language-cpp">  #include &quot;AdjListGraph.h&quot;
  #include &quot;CircularQueue.h&quot;
  ...
  void BFS(int v){
      visited[v] = true;
      printf(&quot;%c &quot;, getVertex(v));

      CircularQueue que;
      que.enqueue(v);
      while(!que.isEmpty()){
          int v = que.dequeue();
          for(int w = 0; w &lt; size; w++)
              if(isLinked(v, w) &amp;&amp; visited[w] == false){
                  visited[w] = true;
                  printf(&quot;%c &quot;, getVertex(w));
                  que,enqueue(w);
              }
      }
  }</code></pre>
<h5 id="2-인접-리스트---x">2. 인접 리스트 -&gt; X</h5>
<h2 id="f-탐색">F. 탐색</h2>
<h2 id="g-avl-트리">G. AVL 트리</h2>
<p>  a) 스스로 노드를 재배치하여 균형 상태 유지
  b) 평균/최선/최악: O(logn)
  c) 탐색 연산: 이진탐색트리와 동일
  d) 삽입/삭제 연산: 균형상태가 깨질 수 있음</p>
<pre><code>  -&gt; 불균형 상태로 변한 가장 가까운 조상 노드의 
     서브 트리들에 대해 다시 균형을 맞춤</code></pre></li>
<li><p>균형 인수(bf, balance factor)
: = 왼쪽 서브트리 높이 - 오른쪽 서브트리 높이
: 모든 노드의 균형 인수가 -1 ~ 1 이면 AVL 트리</p>
<h4 id="ll타입">&gt;&gt; LL타입</h4>
<p>: 가장 가까우면서 균형 인수가 ±2인 조상노드의 왼쪽 서브트리(L)의 왼쪽서브트리(L)에 삽입</p>
</li>
<li><blockquote>
<p><strong>LL회전</strong>(= 오른쪽 회전)
   : a) B의 오른쪽 자식을 A의 왼쪽 자식으로 만든다
   : b) A를 B의 오른쪽 자식의 노드로 만든다
   <img src="https://velog.velcdn.com/images/meer_/post/379e431a-3b3f-4538-82e7-8531374064da/image.png" alt=""></p>
</blockquote>
<pre><code class="language-cpp">   BinaryNode* reBalance(BinaryNode* parent){
       int hDiff = getHeightDiff(parent);
       if(hDiff &gt; 1){
       if(getHeightDiff(parent-&gt;getLeft()) &gt; 0)
           parent = rotateLL(parent);
       else parent = rotateLR(parent);
       ...
   }

   BinaryNode* rotateLL(BinaryNode* parent){
       BinaryNode* child = parent-&gt;getLeft();
       parent-&gt;setLeft(child-&gt;getRight());
       child-&gt;setRight(parent);
       return child;
   }

   Void insert(int data){
       if(isEmpty()) root = new BinaryNode(data);
       else root = insertAVL(root, data);
   }

   BinaryNode* insertAVL(BinaryNode* parent, int data){
       if(data &lt; parent-&gt;getData()){
           if(parent-&gt;getLeft() != NULL)
               parent-&gt;setLeft(insertAVL(parent-&gt;getLeft(),data));
           else parent-&gt;setLeft(new BinaryNode(data));
           return reBalance(parent);
       }
       else if(data &gt; parent-&gt;getData()){
           if(parent-&gt;getRight() != NULL)
               parent-&gt;setRight(insertAVL(parent-&gt;getRight(), data));
           else parent-&gt;setRight(new BinaryNode(data));
           return reBalance(parent);
       }
       else{ printf(&quot;중복 키 에러!\n&quot;); return NULL; }
   }</code></pre>
<h2 id="h-해싱">H. 해싱</h2>
</li>
<li><p>이상적인 해싱 함수: O(1)</p>
</li>
<li><p>좋은 해시 함수의 조건
  a) 충돌이 적어야 함
  b) 함수 값이 테이블의 주소 영역 내에 고르게 분포
  c) 계산이 빨라야 함</p>
</li>
<li><p>구조적 문제 해결법
  a) 선형 조사법
  b) 이차 조사법</p>
<pre><code> c) 체이닝</code></pre></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[그리드 Vs 테이블]]></title>
            <link>https://velog.io/@meer_/%EA%B7%B8%EB%A6%AC%EB%93%9C-Vs-%ED%85%8C%EC%9D%B4%EB%B8%94</link>
            <guid>https://velog.io/@meer_/%EA%B7%B8%EB%A6%AC%EB%93%9C-Vs-%ED%85%8C%EC%9D%B4%EB%B8%94</guid>
            <pubDate>Fri, 02 Jun 2023 11:20:09 GMT</pubDate>
            <description><![CDATA[<p>  그리드와 테이블은 데이터를 구성하는 두 가지 다른 형식입니다.</p>
<p>  테이블은 행과 열로 구성된 2차원 데이터 구조입니다. 각 행은 레코드 또는 엔트리라고 불리며, 각 열은 해당 레코드의 특정 속성을 나타냅니다. 예를 들어, 고객 정보를 포함하는 테이블은 각 행이 개별 고객을 나타내고, 각 열은 이름, 주소, 전화번호 등과 같은 특정 고객 속성을 포함합니다. 테이블은 일반적으로 데이터베이스에서 사용되며, 데이터를 구조화하고 검색 및 관리하기 위해 사용됩니다.</p>
<p>  반면에 그리드는 행과 열이 규칙적으로 배치된 2차원 그래픽 형식입니다. 그리드는 주로 데이터를 시각적으로 표현하는 데 사용됩니다. 예를 들어, 스케줄을 나타내는 그리드는 행이 시간대를 나타내고 열이 요일을 나타내며, 각 셀은 해당 시간대와 요일에 예정된 일정을 표시합니다. 그리드는 주로 스프레드시트 프로그램이나 데이터 시각화 도구에서 사용되며, 데이터의 시각적 표현과 분석에 유용합니다.</p>
<p>  요약하면, 테이블은 데이터를 구조화하고 조직화하는 데 사용되는 2차원 데이터 형식이며, 그리드는 데이터를 시각적으로 표현하고 분석하는 데 사용되는 2차원 그래픽 형식입니다.</p>
<p>(by 챗GPT)</p>
<p>테이블은 정적이지만 그리드는 동적 연결리스트인데 그리드를 고정하는 방법도 있어서 요즘에는 굳이 테이블 쓰지 않음. (by 챗tahnPT)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[For-Each]]></title>
            <link>https://velog.io/@meer_/For-Each</link>
            <guid>https://velog.io/@meer_/For-Each</guid>
            <pubDate>Sat, 13 May 2023 06:48:50 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-java">    [형식]
        for (Type Var_Name : ArrayList또는Array)</code></pre>
<hr>
<pre><code class="language-java">예시)

    String[] numbers = {&quot;one&quot;, &quot;two&quot;, &quot;three&quot;};
    for(int i=0; i&lt;numbers.length; i++) {
        System.out.println(numbers[i]);
    }

    를 for-each 문으로 바꾸면

    String[] numbers = {&quot;one&quot;, &quot;two&quot;, &quot;three&quot;};
    for(String number: numbers) {
        System.out.println(number);
    }

    출력 결과는 똑같다.

    one
    two
    three</code></pre>
<p><a href="https://wikidocs.net/264">출처: 점프 투 자바</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[:->]]></title>
            <link>https://velog.io/@meer_/-</link>
            <guid>https://velog.io/@meer_/-</guid>
            <pubDate>Thu, 11 May 2023 07:47:54 GMT</pubDate>
            <description><![CDATA[<ul>
<li><h3 id="-도트-연산자">. (도트 연산자)</h3>
<p>: 클래스의 멤버를 직접 접근</p>
</li>
<li><h3 id="--화살표-연산자">-&gt; (화살표 연산자)</h3>
<p>: 클래스의 멤버를 간접 접근</p>
</li>
</ul>
<pre><code class="language-cpp">#include &lt;iostream&gt;

class MyClass {
public:
    int myVariable;
    int myFunction() {
        return myVariable;
        // 멤버 함수의 구현
    }
};

int main() {
    MyClass object;
    MyClass* pointer = &amp;object;

    object.myVariable = 10;
    // 도트 연산자로 멤버 변수에 접근
    std::cout &lt;&lt; object.myFunction();
    // 도트 연산자로 멤버 함수 호출

    printf(&quot;\n&quot;);

    pointer-&gt;myVariable = 20;
    // 화살표 연산자로 포인터를 통해 멤버 변수에 접근
    std::cout &lt;&lt; pointer-&gt;myFunction();
    // 화살표 연산자로 포인터를 통해 멤버 함수 호출

    return 0;
}

[실행결과]
10
20
</code></pre>
<p><a href="https://dbstndi6316.tistory.com/386">출처: 코딩뚠뚠</a>
[출처: ChatGPT]</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Collection<E>]]></title>
            <link>https://velog.io/@meer_/Collection</link>
            <guid>https://velog.io/@meer_/Collection</guid>
            <pubDate>Mon, 08 May 2023 09:30:04 GMT</pubDate>
            <description><![CDATA[<p>모두 import java.util.*; 해줘야 함!</p>
<h2 id="1-vectore-클래스">1. Vector&lt;E&gt; 클래스</h2>
<p><img src="https://velog.velcdn.com/images/meer_/post/19e58da1-608e-47bd-a570-8bc1dfeabe42/image.png" alt=""></p>
<h2 id="2-arrayliste-클래스">2. ArrayList&lt;E&gt; 클래스</h2>
<p><img src="https://velog.velcdn.com/images/meer_/post/f96e106d-7d36-4cf9-a67f-4084e55d0365/image.png" alt=""></p>
<h2 id="3-iteratore-인터페이스">3. Iterator&lt;E&gt; 인터페이스</h2>
<p><img src="https://velog.velcdn.com/images/meer_/post/3598203d-d1f4-486e-98d3-4cb7aa13a320/image.png" alt=""></p>
<pre><code class="language-cpp">[사용법]
    Vector&lt;Integer&gt; v = new Vector&lt;Integer&gt;();
    Iterator&lt;Integer&gt; it = v.iterator();
    while(it.hasNext()) { // 모든 요소 방문 
    int n = it.next(); // 다음 요소 리턴 ...}</code></pre>
<h2 id="4-hashmapkv-클래스">4. HashMap&lt;K,V&gt; 클래스</h2>
<ul>
<li>HashMap은 Key와 Value의 쌍으로 구성되어있고 put()하는 값이 순서대로 저장되지 않기 때문에 출력 역시 입력한 순서대로 되지 않는다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/meer_/post/5186d777-388b-4097-84c5-5abb20ce1b26/image.png" alt=""></p>
<h2 id="5-linkedliste-클래스">5. LinkedList&lt;E&gt; 클래스</h2>
<p><img src="https://velog.velcdn.com/images/meer_/post/a80bb218-092d-4ee6-93a6-509eb1557f9a/image.png" alt=""></p>
<h2 id="6-collection-클래스">6. Collection 클래스</h2>
<p>: 모든메소드는 static 타입이므로 Collection 객체를 생성할 필요가 없다.</p>
<ul>
<li>sort() : 요소를 오름차순으로 정렬</li>
<li>reverse() : 요소를 내림차순으로 정렬</li>
<li>max(), min() : 요소들의 최댓값과 최솟값 찾아내기  </li>
<li>binarySearch() : 이진 검색<pre><code class="language-cpp">[사용예시]
  Collections.sort(myList);
  int index = Collections.binarySearch(myList, &quot;A&quot;);</code></pre>
</li>
</ul>
<hr>
<blockquote>
<p>[참고]
Vector와 ArrayList는 거의 동일한 컬랙션 클래스지만,</p>
</blockquote>
<ul>
<li>ArrayList의 단점: <strong>스레드 간에 동기화를 지원하지 않</strong>기 때문에, 다수의 스레드가 동시에 ArrayList에 요소를 삽입하거나 삭제할 때 ArrayList의 데이터가 훼손될 우려가 있음.</li>
<li>ArrayList의 장점: 멀티스레드 동기화를 위한 시간 소모가 없기 때문에, Vector보다 속도가 빨라 <strong>단일 스레드 응용에는 더 효과적</strong>임.
<img src="https://velog.velcdn.com/images/meer_/post/98ea8257-75be-4c67-b12a-3197bd1c2e0d/image.png" alt=""></li>
</ul>
<p>출처: 명품 JAVA
<a href="https://www.geeksforgeeks.org/vector-vs-arraylist-java/">출처: GeeksForGeeks</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[& and *]]></title>
            <link>https://velog.io/@meer_/pnr</link>
            <guid>https://velog.io/@meer_/pnr</guid>
            <pubDate>Wed, 03 May 2023 09:22:44 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h2 id="참조">&amp; (참조)</h2>
<p>: 주소값 반환</p>
</blockquote>
<pre><code class="language-cpp">#include&lt;iostream&gt;
int main(){
    int a1 = 3;
    int &amp;a2 = a1; 
    // a1를 참조하는 a2
    // a1과 a2는 같은 주소를 갖는다. 
    a2 = 5;
    // 그래서 a2를 수정하면 a1도 바뀜!
    printf(&quot;a1 = %d\n&quot;, a1);
    printf(&quot;a2 = %d\n&quot;, a2);
    return 0;
[출력결과]
    a1 = 5
    a2 = 5
}</code></pre>
<p>[조건]</p>
<ul>
<li>상수를 참조할 수 없음. ( int &amp;num = 2; )</li>
<li>참조하는 값이 없는 경우 선언 불가. ( int &num; )</li>
<li>NULL값 참조 불가. ( int &amp;num = NULL; )</li>
</ul>
<blockquote>
<h2 id="-포인터">* (포인터)</h2>
</blockquote>
<ol>
<li>포인터 변수 선언 (형식: 형* 포인터이름)</li>
<li>포인터가 가리키는 주소의 &#39;값&#39; (형식: *포인터 이름)<pre><code class="language-cpp"> [예시]
 int* ptr1; == int형 변수를 가리킬 수 있는 ptr1
 *ptr2 == ptr2가 가리키고 있는 주소에 있는 값</code></pre>
</li>
</ol>
<p><a href="https://kyoe.tistory.com/115">출처: 하루 세번</a>
<a href="https://velog.io/@changhee1016/%EC%B0%B8%EC%A1%B0%EC%9E%90%EC%99%80-%ED%8F%AC%EC%9D%B8%ED%84%B0-%EC%B0%A8%EC%9D%B4C">출처: Jo.log</a>
<a href="https://copycode.tistory.com/82">출처: ITstory</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[# C++ 키워드]]></title>
            <link>https://velog.io/@meer_/C-%ED%82%A4%EC%9B%8C%EB%93%9C</link>
            <guid>https://velog.io/@meer_/C-%ED%82%A4%EC%9B%8C%EB%93%9C</guid>
            <pubDate>Tue, 02 May 2023 05:07:10 GMT</pubDate>
            <description><![CDATA[<h3 id="1-lambda"><strong>1. Lambda</strong></h3>
<p><img src="https://velog.velcdn.com/images/meer_/post/d505f45a-170f-4fa4-a1e4-23f2af54f9b2/image.webp" alt="">
: 익명 함수를 정의할 수 있는 기능.</p>
<ul>
<li>형식 :  개시자 + 인자 + 반환 타입 + 함수의 몸통</li>
<li>다른 함수나 객체의 인자로 전달되거나 반환되는 함수 객체를 생성하는 데 사용.</li>
<li>함수 객체로 구현할 경우 번거롭게 구조체를 먼저 정의해서 사용할 필요가 없기 때문에 간단하게 표현이 가능하다.
```cpp
// 개시자 없음, 인자 없음, 리턴 타입 없음.
#include <iostream>
int main() {
  <a href=""></a> { std::cout &lt;&lt; &quot;Hello lambda!&quot; &lt;&lt; std::endl; }();
  return 0;
}</li>
<li>// 개시자 없음, 리턴 타입 없음.
#include <iostream>
int main() {
   [](std::string name) {<pre><code>   std::cout &lt;&lt; &quot;My name is &quot; &lt;&lt; name &lt;&lt; std::endl;</code></pre>   }(&quot;Dangdang&quot;);
   return 0;
}</li>
<li>// std::function에 대입 가능.
#include <iostream>
#include <functional>
int main() {
   // std::function&lt;void (std::string)&gt;
   auto introduce = [](std::string name) {<pre><code>   std::cout &lt;&lt; &quot;My name is &quot; &lt;&lt; name &lt;&lt; std::endl;</code></pre>   };
   introduce(&quot;Jinsoo Heo&quot;);
   return 0;
}</li>
</ul>
<pre><code>### **2. Predicate**        &gt;&gt; 몰루입니다ㅠ
: 조건자. true/false 또는 int를 리턴하는 함수.
### **3. Array vs Pointer**
- array의 배열 변수가 보유한 주소는 배열의 첫번째 요소의 주소.
- arr = 배열의 시작 원소를 가리킴
- &amp;arr = 배열 자체를 가리키는 포인터
```cpp
    #include &lt;iostream&gt;
    using namespace std;
    void foo(int* arr){
        cout &lt;&lt; sizeof(arr);
    }
    int main(){
        int arr[3] = { 1, 2, 3 };
        cout &lt;&lt; sizeof(arr);
        foo(arr);
        return 0;
    }
    [출력 결과]: 12 4</code></pre><h3 id="4-pointer-vs-reference"><strong>4. Pointer vs Reference</strong></h3>
<p>: <a href="https://velog.io/@meer_/Pointer">이미 정리함</a></p>
<h3 id="5-smart-pointer"><strong>5. Smart Pointer</strong></h3>
<p>: 포인터처럼 동작하는 클래스 템플릿. new 키워드가 반환하는 주소값을 대입하면, 따로 메모리를 해제할 필요가 없음. (사용이 끝난 메모리를 자동으로 해제해줌!)</p>
<p><strong>a. unique_ptr : ** 하나의 스마트 포인터만이 특정 객체를 소유할 수 있도록, 객체에 **소유권</strong> 개념을 도입한 스마트 포인터.</p>
<ul>
<li>해당 객체의 소유권을 가지고 있을 때만, 소멸자가 해당 객체를 삭제할 수 있음.</li>
<li>move() 멤버 함수를 통해 소유권을 이전할 수는 있지만, 복사할 수는 없음.</li>
<li>소유권이 이전되면, 이전 unique_ptr 인스턴스는 더는 해당 객체를 소유하지 않게 재설정됨.</li>
</ul>
<pre><code class="language-cpp">    unique_ptr&lt;int&gt; ptr01(new int(5));
    // int형 unique_ptr 선언
    auto ptr02 = move(ptr01);
    // ptr01에서 ptr02로 소유권 이전
    ptr02.reset();    
    // ptr02가 가리키고 있는 메모리 영역을 삭제
    ptr01.reset();    
    // ptr01가 가리키고 있는 메모리 영역을 삭제</code></pre>
<p>*<em>b. shared_ptr : *</em> 하나의 특정 객체를 참조하는 스마트 포인터가 총 몇 개인지를 참조하는 스마트 포인터.</p>
<ul>
<li><p>참조 횟수는 특정 객체에 새로운 shared_ptr이 추가될 때마다 1씩 증가하며, 수명이 다할 때마다 1씩 감소함.</p>
</li>
<li><p>use_count() : shared_ptr 객체가 현재 가리키고 있는 리소스를 참조 중인 소유자의 수를 반환</p>
</li>
<li><p>make_shared(): shared_ptr 인스턴스를 안전하게 생성</p>
<pre><code class="language-cpp">  shared_ptr&lt;Person&gt; a = make_shared&lt;Person&gt;(&quot;A&quot;, 30);
  cout &lt;&lt; a.use_count() &lt;&lt; endl;
  auto b = a;
  cout &lt;&lt; a.use_count() &lt;&lt; endl
  b.reset(); // shared_ptr인 b를 해제함.
  cout &lt;&lt; a.use_count() &lt;&lt; endl; 
  [출력 결과]
  1
  2
  1</code></pre>
</li>
<li><p><em>c. weak_ptr: *</em> 하나 이상의 shared_ptr 인스턴스가 소유하는 객체에 대한 접근을 제공하지만, 소유자의 수에는 포함되지 않는 스마트 포인터.</p>
</li>
<li><p>서로 상대방을 가리키는 shared_ptr 인스턴스 사이의 순환 참조를 제거하기 위해 사용.</p>
<h3 id="6-lvalue-vs-rvalue"><strong>6. lvalue vs rvalue</strong></h3>
<p>a. lvalue : 단일 표현식 이후에도 사라지지않고 지속되는 객체. 
b. rvalue : 표현식이 종료된이후에는 더이상 존재하지 않는 임시적인 값.</p>
<pre><code class="language-cpp">  [예시]
  a = b + c; 에서
  &quot;a&quot;는 lvalue, &quot;b + c&quot;는 rvalue</code></pre>
<h3 id="7-char-vs-stdstring"><strong>7. Char vs std::string</strong></h3>
<p>a. char : 문자. ASCII 코드로 해석되는 1byte의 정수.
b. std::string : &quot;&quot;를 이용해 표현되는 문자열 상수.
  (이름을 가지고 있지 않으며 문자열의 내용 또한 변경할 수 없기 때문.)</p>
<h3 id="8-literal-constant"><strong>8. Literal constant</strong></h3>
<p>: &#39;상수&#39;. 코드에 직접 삽입된 값. 변경할 수 없음.</p>
</li>
<li><p>숫자 리터럴에서는 유형을 결정하는 접미사가 포함될 수 있고 선택사항으로 생략하면 컴파일러는 의도하는 것이 어떤 종류의 상수인지 유추함.</p>
</li>
<li><p>문자와 문자열 리터럴도 있음. </p>
<h3 id="9-function-overloading"><strong>9. Function Overloading</strong></h3>
<p>: 다른 매개 변수를 가진 같은 이름의 여러 함수를 만듦.</p>
<pre><code class="language-cpp">  void Display(const char* str, int n){
      for (int i = 0; i &lt; n; i++){
          printf(str);
      }
  }
  void Display(const char* str1, const char* str2){
      printf(str1 + str2);
  }
  void Display(int x, int y){
      printf(x * y);
  }
  void Display(double x, double y){
      printf(x / y);
  }
  // 여기서 Display(4.2, 3); 을 하면
  // 함수가 두개 호출 가능해 컴파일 오류 발생.</code></pre>
<h3 id="10-operator-overloading"><strong>10. Operator Overloading</strong></h3>
<p>: 기존에 제공하고 있는 연산자를 전역 함수 또는 클래스로 재정의하여 사용자 정의해 사용하는 것.</p>
</li>
<li><p>새로운 연산자를 정의할 수 없음.</p>
</li>
<li><p>기본 제공 데이터 형식에 적용할 때 연산자의 의미를 다시 정의할 수 없음.</p>
</li>
<li><p>오버로드 된 연산자는 non-static 클래스 멤버 함수거나 전역 함수여야 함.</p>
</li>
<li><p>단항 연산자 또는 이항 연산자(&amp;, *, +, -)로 오버로드 가능하며 각 사용을 별도로 오버로드 할 수 있음.</p>
</li>
<li><p>멤버함수로 오버로드된 연산자의 첫번째 파라미터는 항상 연산자가 호출되는 객체의 클래스 형식.</p>
</li>
<li><p>오버로드 할 수 없는 연산자: . .* :: ?: # ##</p>
<pre><code class="language-cpp">  #include &lt;iostream&gt;
  using namespace std;
  class Point{
  private:
      int x, y;
  public:
      Point(int x_, int y_){
          x = x_;
          y = y_;
      }
      void print(){
          cout &lt;&lt; &quot;x : &quot; &lt;&lt; x &lt;&lt; &quot;, y : &quot; &lt;&lt; y &lt;&lt; &quot;\n&quot;;
      }
      Point operator + (Point&amp; p){
          x = x + p.x;
          y = y + p.y;
          return Point(x, y);
      }
  };

  int main(){
      Point p1 = { 1, 1 };
      Point p2(2, 2);

      Point p3 = p1 + p2;

      p3.print();
      return 0;
  }

  [출력 결과]
  x: 3, y: 3</code></pre>
<h3 id="11-constructor-copy-constructor"><strong>11. Constructor, Copy constructor</strong></h3>
</li>
<li><p><em>a. 생성자 :*</em> 해당 클래스의 객체가 인스턴스화될 때 자동으로 호출되는 특수한 종류의 멤버 함수.</p>
</li>
<li><p>일반적으로 클래스의 멤버 변수를 적절한 기본값 또는 사용자 제공 값으로 초기화하거나 클래스를 사용하는 데 필요한 설정(ex. 파일 열기 등)이 필요한 경우 사용.</p>
</li>
<li><p>생성자 이름은 클래스와 이름이 같아야함.</p>
</li>
<li><p>생성자는 리턴타입이 없다. (void도 X)</p>
</li>
</ul>
<p><strong>b. 복사 생성자 :</strong> 객체의 복사본을 생성할 때 호출되는 생성자.</p>
<ul>
<li><p>자신과 같은 클래스 타입의 다른 객체에 대한 참조를 인수로 전달받아, 그 참조를 가지고 자신을 초기화 하는 방법.</p>
</li>
<li><p>새롭게 생성되는 객체가 원본 객체와 같으면서도 완전한 독립성을 갖게 함. (복사 생성자를 이용한 대입은 깊은복사이기 때문!)
c. 복사 대입 연산자 : 같은 타입의 객체를 이미 생성되어 이쓴 객체에 값을 복사할 때 사용.</p>
</li>
<li><p>객체가 함수에 인수로 전달될 때</p>
</li>
<li><p>함수가 객체를 반환값으로 반환할 때</p>
</li>
<li><p>새로운 객체를 같은 클래스 타입의 기존 객체와 똑같이 초기화 할 때</p>
<pre><code class="language-cpp">      #include &lt;iostream&gt;

  using namespace std;

  class Person{
  public:
      int age;
      char* name;
      Person(int _age, const char* _name){
          age = _age;
          name = new char[strlen(_name) + 1];
          strcpy(name, _name);
      }

    Person(const Person&amp; p){ //복사 생성자로 깊은 복사하기
             age = p.age;
          name = new char[strlen(p.name) + 1];
             strcpy(name, p.name);
      }

      void infoPerson(){
          cout &lt;&lt; &quot;이름: &quot; &lt;&lt; name &lt;&lt; endl;
          cout &lt;&lt; &quot;나이: &quot; &lt;&lt; age &lt;&lt; endl;
      }
  };

  void main(){
      Person A(20, &quot;홍길동&quot;);
      Person B = A;

         B.age = 30;
      strcpy(B.name, &quot;이순신&quot;);

      A.infoPerson();
      B.infoPerson();
  }
  [출력 결과]
  이름: 홍길동
  나이: 20
  이름: 이순신
  나이: 30
</code></pre>
</li>
</ul>
<pre><code>[참고: 얕은 복사 &amp; 깊은 복사](https://velog.io/@meer_/%EC%96%95%EC%9D%80-%EB%AC%BC-%EA%B9%8A%EC%9D%80-%EB%AC%BC)
### **12. Abstract class**
a. 순수 가상 함수 : 파생 클래스에서 재정의할 것으로 기대하는, &#39;반드시 재정의 되어야만 하는&#39; 멤버 함수.
- 형식: virtual 멤버함수원형 = 0;
```cpp
    예시: virtual void foo() = 0;</code></pre><p>b. 추상 클래스 : 하나 이상의 순수 가상 함수를 포함하는 클래스.</p>
<ul>
<li><p>반드시 사용되어야 하는 멤버 함수를 추상 클래스에 순수 가상 함수로 선언해 놓으면, 이 클래스로부터 파생된 모든 클래스에서는 이 가상 함수를 반드시 재정의해야 함.</p>
</li>
<li><p>동작이 정의되지 않은 순수 가상 함수를 포함하고 있으므로, 인스턴스 생성 X.</p>
<pre><code class="language-cpp">  class Animal{
  public:
      virtual ~Animal(){}        // 가상 소멸자 선언
      virtual void Cry() = 0;    //순수 가상 함수 선언
  class Dog : public Animal{
  public:
      virtual void Cry(){ cout &lt;&lt; &quot;멍멍!&quot; &lt;&lt; endl; }
  }
  class Cat : public Animal{
  public:
      virtual void Cry(){ cout &lt;&lt; &quot;야옹!&quot; &lt;&lt; endl; }
  }
  int main(){
      Dog myDog;
      myDog.Cry();
      Cat myCat;
      myCat.Cry();
      return 0;
  }
  [출력 결과]
  멍멍!
  야옹!
  /*
  Animal 클래스를 상속받는 파생 클래스인
  Dog 클래스와 Cat 클래스는
  Cry() 함수를 오버라이딩해야만
  인스턴스를 생성할 수 있음
  */</code></pre>
<h3 id="13-inheritance"><strong>13. Inheritance</strong></h3>
<p>: 상속. </p>
<pre><code class="language-cpp">  [형식]
  class 자식클래스이름 : 접근제한자 부모클래스이름 {...}</code></pre>
<p>a. private 상속</p>
<pre><code class="language-cpp">  #include &lt;iostream&gt;
  using namespace std;

  class A {
  private:
      int a;
  protected:
      int b;
  public:
      int c;
  };

  class B : private A { 
  //b,c맴버 변수는 private 맴버로 접근 범위 졻혀짐
  };

</code></pre>
</li>
</ul>
<pre><code>int main() {
    B b;
    //a = private, b = private, c = private
    b.a;
    b.b;
    b.c;
}</code></pre><pre><code>b. protected 상속
```cpp
    #include &lt;iostream&gt;
    using namespace std;

    class A {
    private:
        int a;
    protected:
        int b;
    public:
        int c;
    };

    class B : protected A { 
    //c맴버 변수는 protected 맴버로 접근 범위 졻혀짐
    };


    int main() {
        B b;
        //a = private, b = protected, c = protected
        b.a;
        b.b;
        b.c;
    }</code></pre><p>c. public 상속</p>
<pre><code class="language-cpp">    #include &lt;iostream&gt;
    using namespace std;

    class A {
    private:
        int a;
    protected:
        int b;
    public:
        int c;
    };

    class B : public A {
    //맴버 변수의 접근 제한에 변화없음
    };


    int main() {
        B b;
        //a = private, b = protected, c = public
        b.a;
        b.b;
        b.c;
    }</code></pre>
<h3 id="14-virtual-function"><strong>14. virtual function</strong></h3>
<p>: 가상함수를 선언할 때 사용하는 키워드.</p>
<pre><code class="language-cpp">    [형식]
    virtual 반환형 함수이름();</code></pre>
<ul>
<li>가상함수로 선언하면 동적 바인딩이 되어서 포인터의 타입이 아닌 포인터가 가리키는 객체의 타입에 따라 멤버 함수를 선택하게 됨.</li>
<li>클래스의 public 섹션에 선언.</li>
<li>static 또는 friend 불가.</li>
<li>기본 클래스의 포인터 또는 참조를 통해 access 해야함.</li>
<li>반환형과 매개변수는 기본 클래스와 파생 클래스에서 동일.</li>
<li>override 시에는 virtual 키워드를 붙여도 되고 안붙여도 됨.</li>
<li>가상 소멸자를 가질 수 있지만 가상 생성자를 가질 수 없음.</li>
</ul>
<h3 id="15-override"><strong>15. override</strong></h3>
<p>: 상속받았을 때 부모 클래스의 함수를 사용하지 않고 다른 기능을 사용할 때 함수를 자식 클래스에서 같은 이름, 같은 매개변수로 재정의해서 사용하는 것. 
cf) 오버로딩: 함수 중복 정의- 같은 이름의 함수에 매개변수를 다르게 사용해 매개변수에 따라 다른 함수가 실행되는 것.</p>
<ul>
<li><p>오버라이드 하고자 하는 메소드가 상위 클래스에 존재해야 함.</p>
</li>
<li><p>메소드 이름이 같아야함.</p>
</li>
<li><p>파라미터 개수와 자료형이 같아야함.</p>
</li>
<li><p>리턴형이 같아야함.</p>
</li>
<li><p>상위 메소드와 동일하거나 내용이 추가 되어야 함.</p>
<h3 id="16-polymorphism"><strong>16. Polymorphism</strong></h3>
<p>: 다형성(여러가지 형태를 갖는 성질).</p>
</li>
<li><p>함수의 기능적 다형성과 상속에 의해 만들어진 계층 관계를 활용하는 기술</p>
</li>
<li><p>상속구조를 가지고 있는 경우 상위 클래스의 포인터나 참조자로 하위 클래스의 기능과 자료를 사용할 수 있다.</p>
</li>
<li><p>상위 클래스에 가상 멤버 변수가 하나 이상 있어야함.</p>
</li>
<li><p>하위 클래스에서 오버라이딩 할 멤버 함수가 없다면 상위 클래스의 소멸자를 가상함수로 만들고 객체는 상위 클래스의 포인터나 참조자로 만들어야함.
a. 가상 함수 : 부모 클래스와 자식 클래스에 동일한 이름의 함수의 다른 작동
b. 함수 템플릿 : 동일한 이름의 함수가 다양한 자료형을 처리
c. 함수 오버로드 : 동일한 이름의 함수가 다른 작동
d. 연산자 오버로드 : 한가지 연산자가 다양한 작동</p>
<h3 id="17-up-casting-down-casting"><strong>17. up-casting, down-casting</strong></h3>
</li>
<li><p><em>a. up-casting*</em> : 파생 클래스의 객체를 기본 클래스의 포인터로 가리키는 것.</p>
<pre><code class="language-cpp">   예시:
       Pizza cheesePizza;
       Pizza* pp = &amp;cheesePizza;
       Circle cc = pp;    // 업캐스팅</code></pre>
</li>
<li><p><em>b. down-casting*</em> : 기본 클래스 포인터가 가리키는 객체를 파생 클래스의 포인터로 가리키는 것. 업캐스팅에서 다시 원래 형으로 되돌려주는 작업. 업캐스팅과 달리 &#39;명시적 타입 변환&#39;을 지정해야 함.</p>
<pre><code class="language-cpp">   예시:
       pp = (Pizza*) cc;</code></pre>
<h3 id="18-template"><strong>18. Template</strong></h3>
<pre><code class="language-cpp">   [형식]
   template &lt;typename 이름&gt;</code></pre>
</li>
<li><p>컴파일러가 인자값으로 들어가는 자료형을 보고 타입을 유추하여 유연하게 함수에 적용</p>
</li>
<li><p><em>a. Class Template*</em></p>
<pre><code class="language-cpp">   #include &lt;iostream&gt;
   using namespace std;
   template &lt;typename T&gt;

   T add(T x, T y) {
       return x + y;
   }
   int main()
   {
       int num1 = 10, num2 = 20;
       cout &lt;&lt; add(num1, num2) &lt;&lt; endl;

       double num3 = 10.52, num4 = 20.24;
       cout &lt;&lt; add(num3, num4) &lt;&lt; endl;

       return 0;
   }</code></pre>
</li>
<li><p><em>b. Function Template*</em></p>
<pre><code class="language-cpp">   #include &lt;iostream&gt;
   using namespace std;
   template &lt;class T&gt;
   //template &lt;typename T&gt; 와 같은 표현
   class Calcu
   {
   private:
       T num1;
       T num2;
   public:
       Calcu(T num1, T num2) {
           this-&gt;num1 = num1;
           this-&gt;num2 = num2;
       }
       T GetAdd() {
           return num1 + num2;
       }
   };
   int main()
   {
       Calcu&lt;int&gt; calcu1(10, 20);
       cout &lt;&lt; calcu1.GetAdd() &lt;&lt; endl;

       Calcu&lt;double&gt; calcu2(10.52, 20.24);
       cout &lt;&lt; calcu2.GetAdd() &lt;&lt; endl;
   }</code></pre>
</li>
<li><p><em>c. variadic functions*</em> : 가변 길이 템플릿</p>
<pre><code class="language-cpp">   #include &lt;iostream&gt;

   template &lt;typename T&gt;
   void print(T arg) {
     std::cout &lt;&lt; arg &lt;&lt; std::endl;
   }

   template &lt;typename T, typename... Types&gt;
   void print(T arg, Types... args) {
     std::cout &lt;&lt; arg &lt;&lt; &quot;, &quot;;
     print(args...);
   }

   int main() {
     print(1, 3.1, &quot;abc&quot;);
     print(1, 2, 3, 4, 5, 6, 7);
   }</code></pre>
<h3 id="19-exception"><strong>19. Exception</strong></h3>
</li>
<li><p><em>a. try-catch / throw*</em>
<a href="https://velog.io/@meer_/Try-Catch-Finally">&gt;&gt; JAVA로 정리했었다!</a></p>
</li>
<li><p><em>b. std::exception*</em> </p>
<pre><code class="language-cpp">   #include &lt;exception&gt; 해야함</code></pre>
</li>
<li><p>logic_error
  invalid_argument
  domain_error
  length_error
  out_of_range
  future_error(C++11)</p>
</li>
<li><p>runtime_error
  range_error
  overflow_error
  underflow_error
  regex_error(C++11)
  system_error(C++11)</p>
<pre><code>  ios_base::failure(C++11)</code></pre></li>
<li><p>bad_typeid</p>
</li>
<li><p>bad_weak_ptr(C++11)</p>
</li>
<li><p>bad_function_call(C++11)</p>
</li>
<li><p>bad_alloc
  bad_array_new_length(C++11)</p>
</li>
<li><p>bad_exception</p>
</li>
<li><p>ios_base::failure(until C++11)</p>
</li>
</ul>
<p>[출처]</p>
<p><a href="https://modoocode.com/196">람다 - 모두코드</a>
<a href="https://blog.koriel.kr/modern-cpp-lambdayi-teugjinggwa-sayongbeob/">람다 - devkoriel</a>
<a href="https://mayple.tistory.com/entry/CSTL3%EC%9E%A5-%ED%95%A8%EC%88%98function%EC%99%80-%EC%A1%B0%EA%B1%B4%EC%9E%90predicate">조건자 - Maple story</a>
<a href="https://boycoding.tistory.com/201">배열과 포인터 - 소년코딩</a>
<a href="https://kangworld.tistory.com/50">배열과 포인터 - kangworld</a>
<a href="http://www.tcpschool.com/cpp/cpp_template_smartPointer">스마트 포인터 - TCP school</a>
<a href="https://effort4137.tistory.com/entry/Lvalue-Rvalue">Lvalue &amp; Rvalue - 별이 빛나는 세상</a>
<a href="https://boycoding.tistory.com/154">문자 - 소년코딩</a>
<a href="https://dkanxmstmdgml.tistory.com/396">문자열 - 달려라 승이</a>
<a href="https://boycoding.tistory.com/155">리터럴 - 소년코딩</a>
<a href="http://www.tcpschool.com/cpp/cpp_cppFunction_overloading">함수 오버로딩 - TCP school</a>
<a href="https://yeolco.tistory.com/119">연산자 오버로딩 - 열코</a>
<a href="https://boycoding.tistory.com/244">생성자 - 소년코딩</a>
<a href="http://www.tcpschool.com/cpp/cpp_conDestructor_copyConstructor">복사 생성자 - TCP school</a>
<a href="https://coding-factory.tistory.com/701">복사 생성자 - 코딩 팩토리</a>
<a href="http://www.tcpschool.com/cpp/cpp_polymorphism_abstract">추상 클래스 - TCP school</a>
<a href="https://hwan-shell.tistory.com/223">추상 클래스 - HwanShell</a>
<a href="https://blog.hexabrain.net/173">상속 - 끝나지 않는 프로그래밍 일기</a>
<a href="https://reakwon.tistory.com/143">상속 - reakwon</a>
<a href="https://yeolco.tistory.com/125">가상 클래스 - 열코</a>
<a href="https://coding-factory.tistory.com/699">가상 클래스 - 코딩 팩토리</a>
<a href="https://hwan1402.tistory.com/87">오버라이드 - Insert Brain Here</a>
<a href="https://wikidocs.net/113499">다형성 - C++이야기</a>
<a href="https://younggwan.tistory.com/50">다형성 - 꽈이의 게임개발</a>
<a href="https://lesslate.github.io/cpp/%EC%97%85-%EC%BA%90%EC%8A%A4%ED%8C%85-%EB%8B%A4%EC%9A%B4-%EC%BA%90%EC%8A%A4%ED%8C%85/">lesslate</a>
<a href="https://coding-factory.tistory.com/696">템플릿 - 코딩 팩토리</a>
<a href="https://modoocode.com/290">가변 길이 템플릿 - 모두의 코드</a>
<a href="https://ansohxxn.github.io/cpp/chapter14-4/">exception - 평생 공부</a>
<a href="https://wikidocs.net/145744">exception - C++ 이야기</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Call me by your name]]></title>
            <link>https://velog.io/@meer_/Call-me-by-your-name</link>
            <guid>https://velog.io/@meer_/Call-me-by-your-name</guid>
            <pubDate>Mon, 01 May 2023 05:49:52 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h2 id="call-by-value">[Call by Value]</h2>
<p>: 값에 의한 호출. 복사해 처리하므로 원래의 값이 보존됨.</p>
</blockquote>
<blockquote>
<h2 id="call-by-reference">[Call by Reference]</h2>
<p>: 함수에서 값이 아닌 주솟값을 전달하는 방식. 복사하지 않고 직접 참조. 원래 값이 영향을 받음. (C언어에서는 call by address라고 함.) 값을 전부 복사할 필요가 없으므로 자원 낭비를 확실히 줄일 수 있다.</p>
</blockquote>
<pre><code class="language-c">[c언어에서]
#include &lt;stdio.h&gt;

void swap1 (int a, int b){
    int temp;

    temp = a;
    a = b;
    b = temp;
}
void swap2 (int* a, int* b){
    int temp;

    temp = *a;
    *a = *b;
    *b = temp;
}
int main(){
    int a, b, c, d;
    a = 10;
    b = 20;
    c = 10;
    d = 20;
    printf(&quot;%d, %d, %d, %d&quot;, a, b, c, d);

    swap (a, b);    // 내부적으로 데이터가 처리되지만 a와 b에게 전달 X!
    swap (&amp;c, &amp;d);    // 함수 내부에서 주소를 바꿔버려서 c와 d 자체가 교체됨!

    printf(&quot;%d, %d, %d, %d&quot;, a, b, c, d);

    return 0;
}

[출력결과]
10, 20, 10, 20
10, 20, 20, 10</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[자료구조 중간고사]]></title>
            <link>https://velog.io/@meer_/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%A4%91%EA%B0%84%EA%B3%A0%EC%82%AC</link>
            <guid>https://velog.io/@meer_/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%A4%91%EA%B0%84%EA%B3%A0%EC%82%AC</guid>
            <pubDate>Wed, 26 Apr 2023 13:27:11 GMT</pubDate>
            <description><![CDATA[<p>교수님 저는 말하는 감자입니다.
교수님 저는 말하는 배터리입니다.</p>
<hr>
<blockquote>
<h3 id="빅오-크기-비교">빅오 크기 비교:</h3>
<p>1 &lt; logn &lt; n &lt; nlogn &lt; n^2 &lt; n^3 &lt; n^k &lt; 2^n &lt; n!</p>
</blockquote>
<pre><code class="language-cpp">[예시1]
int algorithm(int n){
    int k = 0;
    while (n &gt; 1){
        n = n/2;
        k++;
    }
    return k;
}
[결과] O(logn)
-
[예시2]
sub함수의 시간복잡도가 O(n)일때
for(i = 1; i &lt; n; i *= 2)
    sub();
의 시간복잡도는?
[답] O(nlogn)</code></pre>
<hr>
<h3 id="a-스택">A. 스택</h3>
<p>: LIFO (후입선출)</p>
<pre><code class="language-cpp">// 오류 처리 함수
inline void error(char *message){
    printf(&quot;%s\n&quot;, message);
    exit(1);
}</code></pre>
<pre><code class="language-cpp">bool isEmpty(){ return top == -1 }
bool isFull(){ return top == MAX_STACK_SIZE-1; }</code></pre>
<pre><code class="language-cpp">void push (int e){
    if (isFull()) error(&quot;스택 포화 에러&quot;);
    data[++top] = e;
}

int pop(){
    if (isEmpty()) error(&quot;스택 공백 에러&quot;);
    return data[top--];

int peek(){
    if (isEmpty()) error(&quot;스택 공백 에러&quot;);
    return data[top];</code></pre>
<pre><code class="language-cpp">[괄호검사 프로그램]

FILE *fp = fopen(filename, &quot;r&quot;);
if(fp == NULL) error(&quot;Error!\n&quot;);

while ((ch = getc(fp)) != EOF{...}</code></pre>
<ol>
<li>중위표기 수식 -&gt; 후위표기 수식 변환<ul>
<li>연산자(operator) 스택</li>
</ul>
</li>
<li>후위표기 수식 -&gt; 계산<ul>
<li>피연산자(operand) 스택</li>
</ul>
</li>
</ol>
<pre><code class="language-cpp">[ungetc()]: 방금 읽은 문자를 입력 버퍼로 되돌려줌

else if (c &gt;= &#39;0&#39; &amp;&amp; c &lt;= &#39;9&#39;){
    ungetc (c, fp);
    double val;
    fscanf (fp, &quot;%lf&quot;, &amp;val);
    st.push (val);
}</code></pre>
<p>[ INFIX TO POSTFIX ]</p>
<ul>
<li>피연산자(숫자) 만나면 그대로 출력</li>
<li>연산자(op)를 만나면
  : 입력op의 우선순위가 스택op의 우선순위보다<ul>
<li>같거나 낮으면 pop하고 출력하고 입력op 스택에 push</li>
<li>높으면 입력op를 push</li>
</ul>
</li>
<li>왼쪽 괄호는 스택에 push</li>
<li>오른쪽 괄호는 스택에서 왼쪽 괄호 위에 쌓여있는 모든 연산자를 출력</li>
</ul>
<pre><code class="language-cpp">int precedence (char op){
    switch (op){
        case &#39;(&#39;: case &#39;)&#39;: return 0;
        case &#39;+&#39;: case &#39;-&#39;: return 1;
        case &#39;*&#39;: case &#39;/&#39;: return 2;
    }
    return -1;
}</code></pre>
<pre><code class="language-cpp">[미로 탐색]

bool isValidLoc (int r, int c){
    if (r &lt; 0||c &lt; 0||r &gt;= MAZE_SIZE||c &gt;= MAZE_SIZE)
        return 0;
    else return map[r][c] == &#39;0&#39; || map[r][c] == &#39;x&#39;;</code></pre>
<hr>
<h3 id="b-큐">B. 큐</h3>
<p>: FIFO (선입선출)</p>
<ul>
<li>선형 큐의 문제점: 삽입을 위해서는 O(n)의 시간이 걸림</li>
<li>원형큐: 공백/포화 상태 구별을 위해 한칸을 비워둔다<ul>
<li>공백상태: front == rear</li>
<li>포화상태: front = (rear + 1) % M</li>
</ul>
</li>
</ul>
<pre><code class="language-cpp">void enqueue (int val){        // 큐에 삽입
    if (isFull()) error(&quot;포화!\n&quot;);
    else{
        rear = (rear + 1) % MAX_QUEUE_SIZE;
        data[rear] = val;
    }
}

int dequeue (){        // 첫 항목을 큐에서 빼서 반환
    if (isEmpty()) error(&quot;공백!\n&quot;);
    else{
        front = (front + 1) % MAX_QUEUE_SIZE;
        return data[front];
    }
}</code></pre>
<hr>
<h3 id="c-덱">C. 덱</h3>
<p>: 최근에 들어온 걸 우선순위를 주고 싶을 때</p>
<pre><code class="language-cpp">[원형덱]

class CircularDeque: Public CircularQueue{
public:
    CircularDeque() {}
    void addRear(int val){ enqueue(val); }
    int deleteFront(){ return dequeue(); }
    int getFront(){ return peek(); }

    void display(){ // CQ의 display() 재정의
        int maxi = (front &lt; rear) ? rear: rear + MAX_Q_SIZE;
        for(int i = front + 1; i &lt;= maxi; i++)
            printf(&quot;[%2d] &quot;, data[i % MAX_Q_SIZE]);
    }

    int getRear(){
        if (isEmpty()) error(&quot;공백!\n&quot;);
        else return data[rear];
    }

    void addFront(int val){
        if (isFull()) error(&quot;포화!\n&quot;);
        else{
            data[front] = val;
            front = (front - 1 + MAX_Q_SIZE) % MAX_Q_SIZE;
        }
    }

    int deleteRear(){
        if (isEmpty()) error(&quot;공백!\n&quot;);
        else{
            int ret = data[rear];
            rear = (rear -1 + MAX_Q_SIZE) % MAX_Q_SIZE;
            return ret;
        }
    }
}</code></pre>
<h3 id="d-연결-리스트">D. 연결 리스트</h3>
<ul>
<li><p>포인터</p>
<ul>
<li>&amp;: 변수의 주소 추출<ul>
<li>*: 포인터가 가리키는 곳의 내용 추출<pre><code class="language-cpp">[자기 참조 구조체]
typedef struct ListNote{
char data[10];
struct ListNode* link;
} Node;</code></pre>
</li>
</ul>
</li>
</ul>
</li>
<li><p>포인터는 NULL로 초기화하자! ( int* p = NULL; )</p>
</li>
<li><p>연결리스트의 삽입/삭제 시간복잡도: O(1)</p>
</li>
<li><p>내가 가리키는 노드의 바로 앞 노드를 알고자 한다면</p>
<ul>
<li>Singly: O(n)<ul>
<li>Doubly: O(1)<pre><code class="language-cpp">// 소멸자
~LinkedStack(){ while(!isEmpty()) delete pop();}</code></pre>
</li>
</ul>
</li>
</ul>
<h3 id="e-리스트">E. 리스트</h3>
<p>: 자료의 접근 위치 - 임의의 위치에서도 삽입/삭제 가능
: <strong>배열</strong>로 - <strong>삽입삭제시 오버헤드</strong>
: 연결리스트로 - 삽입/삭제 효율적.</p>
</li>
</ul>
<h4 id="a-배열로-구현한-리스트">a) 배열로 구현한 리스트</h4>
<ul>
<li>생성자에서 length = 0 설정</li>
<li>공백: length == 0;</li>
<li>포화: length == MAX_L_SIZE;</li>
<li>a.k.a. <strong>밑빠진독</strong>
: 배열이 꽉 찼는데 삽입 하고 싶으면 앞으로 n-1개 옮기고 n번째에 넣기 - O(n)</li>
</ul>
<pre><code class="language-cpp">void insert( int post, int e ){
    if (!isFull() &amp;&amp; pos &gt;= 0 &amp;&amp; pos &lt;= length){
        for(int i = length; i &gt; pos; i--)
            data[i] = data[i-1];
        data[pos] = e;
        length++;
    }
    else error(&quot;포화 또는 삽입 위치 오류!&quot;);
}
-
void remove( int pos ){
    if (!isEmpty() &amp;&amp; 0 &lt;= pos &amp;&amp; pos &lt; length){
        for (int i = pos + 1; i &lt; length; i++)
            data[i - 1] = data[i];
        length--;
    }
    else error(&quot;공백 또는 삭제 위치 오류!&quot;);
}
int getEntry( int pos ){ return data[pos]; }
-
bool find( int item ){
    for (int i = 0; i &lt; length; i++){
        if( data[i] == item) return true;
    return false;
void replace(int pos, int e){
    data[pos] = e;
}
-
// 기출변형 1: item의 인덱스 찾아주는 함수
int where( int item ){
    for ( int i = 0; i &lt; length; i++ ){
        if ( data[i] == item ) return i;
    }
    return -1;
}
-
// 기출변형 2: item을 찾아서 e로 바꿔주는 함수                // 수정 필요!!!
void findAndReplace( int item, int e){
    for( int i = 0; i &lt; length; i++ ){
        if ( data[i] == item ) data[i] = e;
    }
}
</code></pre>
<h4 id="b-연결리스트로-구현한-리스트">b) 연결리스트로 구현한 리스트</h4>
<p>by 단순 연결 리스트</p>
<ul>
<li>하나의 링크필드 이용</li>
<li>마지막 노드의 링크값은 NULL</li>
</ul>
<pre><code class="language-cpp">[노드 클래스] 에서
-
#include&lt;iostream&gt;

class Node {
    Node* link;
    int data;
public:
    Node(int val = 0) : data(val), link(NULL){}    // 멤버를 초기화
    Node* getLink() { return link; }
    void setLink(Node* next) { link = next; }
    void display() { printf(&quot;&lt;%2d&gt;&quot;, data); }
    bool hasData(int val) { return data == val; }
    void insertNext(Node* n) {
        if (n != NULL) {
            n -&gt; link = link;
            link = n;
        }
    }
    Node* removeNext() {
        Node* removed = link;
        if (removed != NULL)
            link = removed -&gt; link;
        return removed;
    }
};
-
-
[연결리스트 클래스] 에서        // 수정 필요
-
void clear(){
    while(!isEmpty())
        delete remove(0);
}
-
Node* getEntry(int pos){
    Node* n = &amp;org;
    for (int i = -1; i &lt; pos; i++, n = n -&gt; getLink())
    // i = -1
        if (n == NULL) break;
    return n;
}
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[String 객체 사용법]]></title>
            <link>https://velog.io/@meer_/String-%EA%B0%9D%EC%B2%B4-%EC%82%AC%EC%9A%A9%EB%B2%95</link>
            <guid>https://velog.io/@meer_/String-%EA%B0%9D%EC%B2%B4-%EC%82%AC%EC%9A%A9%EB%B2%95</guid>
            <pubDate>Mon, 24 Apr 2023 14:17:00 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-java">public class StringEx {
    public static void main(String[] args) {
        String a = new String(&quot; C#&quot;);
        String b = new String(&quot;,c++ &quot;);

        // the length of String
        System.out.println(&quot;the length of &quot; + a + &quot; is &quot; + a.length());

        // is there &quot;String&quot; in the String?
        System.out.println(a.contains(&quot;#&quot;));

        a = a.concat(b);    // connect String
        System.out.println(a);

        // remove space at the front and end of String
        a = a.trim();        
        System.out.println(a);

        a = a.replace(&quot;C#&quot;,&quot;Java&quot;);    // replace A into B
        System.out.println(a);

        String s[] = a.split(&quot;,&quot;);    // split String
        for (int i = 0; i &lt; s.length; i++)
            System.out.println(&quot;split string&quot; + i + &quot;: &quot; + s[i]);

        // return index n to the end as a String
        a = a.substring(5);        
        System.out.println(a);

        char c = a.charAt(2);    // return index m-th char
        System.out.println(c);

    }
}

&gt;&gt;결과:
the length of  C# is 3
true
 C#,c++ 
C#,c++
Java,c++
split string0: Java
split string1: c++
c++
+
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[toString]]></title>
            <link>https://velog.io/@meer_/toString</link>
            <guid>https://velog.io/@meer_/toString</guid>
            <pubDate>Mon, 24 Apr 2023 13:50:18 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-java">class Car {
    public String name;
    public String color;

    Car(String name, String color) {
        this.name = name;
        this.color = color;
    }
    @Override
    public String toString() {
        return &quot;the name is &quot; + name + &quot;, the color is &quot; + color + &quot;.&quot;;
    }
}

public class Operator{
    public static void main(String[] args) {
        Car myCar = new Car(&quot;dang&quot;, &quot;blue&quot;);
        System.out.println(myCar.toString());
    }
}

&gt;&gt;결과:
the name is dang, the color is blue.</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[이진 탐색 Binary Search]]></title>
            <link>https://velog.io/@meer_/BinarySearch</link>
            <guid>https://velog.io/@meer_/BinarySearch</guid>
            <pubDate>Tue, 18 Apr 2023 02:28:43 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/meer_/post/237eb34a-dcdd-4731-b4b4-c0429f7f2e03/image.png" alt=""></p>
<blockquote>
<p>: 정렬된 자료를 반으로 계속해서 나누어 탐색하는 방법</p>
</blockquote>
<pre><code class="language-cpp">&gt;&gt; 코드:

int* binarySearch(int key, const int *target, size_t length) {
    int first = 0, last = length - 1, middle = (first + last) / 2;
    while (first &lt;= last) {
        if (target[middle] == key)     
            return target + middle;

        if (target[middle] &gt; key) 
            last = middle - 1;
        else             
            first = middle + 1;

        middle = (first + last) / 2;
    }      

    return NULL;
}</code></pre>
<blockquote>
<p>시간 복잡도:<img src="https://velog.velcdn.com/images/meer_/post/3083f548-7004-41d8-9cbf-d9d81db07e11/image.png" alt=""></p>
</blockquote>
<p><a href="https://jwoop.tistory.com/9">출처: Learning Never Stops</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JAVA _ next() vs nextLine()]]></title>
            <link>https://velog.io/@meer_/JAVA-next-vs-nextLine</link>
            <guid>https://velog.io/@meer_/JAVA-next-vs-nextLine</guid>
            <pubDate>Mon, 17 Apr 2023 13:17:55 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><strong>next()</strong>
: 문자 또는 문자열을 공백 기준으로 한단어 또는 한문자씩 입력받는다.</p>
</blockquote>
<blockquote>
<p><strong>nextLine()</strong>
: 문자 또는 문장 한 라인 전체를 입력받는다.</p>
</blockquote>
<p>따라서 &quot;Hello World!&quot;를 입력할 경우
<strong><em>next()</em></strong>는 &quot;Hello&quot;만 입력받고 &quot;World!&quot;는 사라진다.
하지만 <strong><em>nextLine()</em></strong>은 &quot;Hello World!&quot; 전체를 입력받는다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JAVA _ 매개변수 몇 개인지 몰?루]]></title>
            <link>https://velog.io/@meer_/JAVA-%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98-%EB%AA%87-%EA%B0%9C%EC%9D%B8%EC%A7%80-%EB%AA%B0%EB%A3%A8</link>
            <guid>https://velog.io/@meer_/JAVA-%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98-%EB%AA%87-%EA%B0%9C%EC%9D%B8%EC%A7%80-%EB%AA%B0%EB%A3%A8</guid>
            <pubDate>Mon, 17 Apr 2023 07:27:42 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-java">예시)

public class Computer {
    int sum1(int[] values){        // [방법 1]
        int sum = 0;
        for(int i = 0; i &lt; values.length; i++){
            sum += values[i];
        }
        return sum;
    }

    int sum2(int ... values){        // [방법 2]
        int sum = 0;
        for(int i = 0; i &lt; values.length; i++){
            sum += values[i];
        }
        return sum;
    }
}

public class ComputerExample {
    public static void main(String[] args){
        Computer myCom = new Computer();

        int[] values1 = {1, 2, 3};
        int result1 = myCom.sum1(values1);
        System.out.println(&quot;result1: &quot;+result1);

        int result2 = myCom.sum1(new int[] {1, 2, 3, 4, 5});
        System.out.println(&quot;result2: &quot;+result2);

        int result3 = myCom.sum2(1, 2, 3);
        System.out.println(&quot;result3: &quot;+result3);

        int result4 = myCom.sum2(1, 2, 3, 4, 5);
        System.out.println(&quot;result4: &quot;+result4);
    }
}

// sum1()과 sum2() 메소드의 실행문은 완전 일치함.
// 매개 변수의 선언 방법만 다를 뿐,
// 매개 변수의 타입이 배열이므로 처리 내용이 같을 수밖에!
</code></pre>
<p>출처: 혼자 공부하는 자바 p.253</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[P와 P와 P, 그리고 친구.]]></title>
            <link>https://velog.io/@meer_/P-P-P</link>
            <guid>https://velog.io/@meer_/P-P-P</guid>
            <pubDate>Fri, 14 Apr 2023 06:08:43 GMT</pubDate>
            <description><![CDATA[<p>&lt;접근 제어 지시자&gt;</p>
<p>A. <strong>Public</strong>: 어디서든 접근 가능
B. <strong>Protected</strong>: 상속관계일 때 접근 가능
C. <strong>Private</strong>: 해당 클래스에서만 접근 가능</p>
<blockquote>
<ul>
<li>굳이 사용하는 이유
: 의도치 않은 코드의 수정을 막고 객체와 객체간의 간섭이 최대한 없도록 하기 위함</li>
</ul>
</blockquote>
<hr>
<pre><code class="language-cpp">[C언어]

#include&lt;iostream&gt;

using namespace std;

class A {
public:
    int num1;

    A() : num1(5), num2(6), num3(7) {}
protected:
    int num2;
private:
    int num3;

};

class B : public A {    
/*A를 상속받은 B
즉, A: 부모 클래스
    B: 자식 클래스*/

public:
    void setNum() {
        num1 = 10;   //컴파일 OK!!
        num2 = 100;  //컴파일 OK!!
        num3 = 1000; //컴파일 Error!!
    }
};

int main(void) {
    A a;

    cout &lt;&lt; a.num1 &lt;&lt; endl; //컴파일 OK!!
    cout &lt;&lt; a.num2 &lt;&lt; endl; //컴파일 Error!!
    cout &lt;&lt; a.num3 &lt;&lt; endl; //컴파일 Error!!
}</code></pre>
<hr>
<blockquote>
<ul>
<li><h3 id="friend-클래스"><strong>friend 클래스</strong></h3>
: friend로 선언된 다른 클래스의 private 및 protected 멤버에 접근할 수 있게 함. 특정 상황에서 클래스 내에 접근하지 못하도록 private 제한을 두었는데, 필요의 경우 해당 클래스나 함수에서 접근이 가능하도록 하는 것.</li>
</ul>
</blockquote>
<pre><code class="language-cpp"></code></pre>
<hr>
<p><a href="https://hwan-shell.tistory.com/25">HwanShell</a></p>
]]></description>
        </item>
    </channel>
</rss>