<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>All is well</title>
    <link>https://alizwldyl.tistory.com/</link>
    <description>!Y</description>
    <language>ko</language>
    <pubDate>Mon, 18 May 2026 18:04:00 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>D0YUN</managingEditor>
    <image>
      <title>All is well</title>
      <url>https://tistory1.daumcdn.net/tistory/7502021/attach/d7ac234e6b544369817a282225a59aef</url>
      <link>https://alizwldyl.tistory.com</link>
    </image>
    <item>
      <title>[오늘의 에러/GitBash] fatal: invalid reference: / error: The following untracked working tree files would be overwritten by merge:</title>
      <link>https://alizwldyl.tistory.com/48</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;오늘의 에러1&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1742519913709&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;fatal: invalid reference: ProductDataTable_fin&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;580&quot; data-origin-height=&quot;58&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdVox6/btsMRkqMHLi/q9lmqaIEmu1IaPKSinGfkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdVox6/btsMRkqMHLi/q9lmqaIEmu1IaPKSinGfkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdVox6/btsMRkqMHLi/q9lmqaIEmu1IaPKSinGfkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcdVox6%2FbtsMRkqMHLi%2Fq9lmqaIEmu1IaPKSinGfkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;580&quot; height=&quot;58&quot; data-origin-width=&quot;580&quot; data-origin-height=&quot;58&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;575&quot; data-origin-height=&quot;116&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPsXbH/btsMR2izm8W/aMGXSnXkd3UeD24sAwVBck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPsXbH/btsMR2izm8W/aMGXSnXkd3UeD24sAwVBck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPsXbH/btsMR2izm8W/aMGXSnXkd3UeD24sAwVBck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPsXbH%2FbtsMR2izm8W%2FaMGXSnXkd3UeD24sAwVBck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;575&quot; height=&quot;116&quot; data-origin-width=&quot;575&quot; data-origin-height=&quot;116&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-start=&quot;110&quot; data-end=&quot;122&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;오류 원인&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-start=&quot;242&quot; data-end=&quot;264&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;해결 방법 (선택지 2가지)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://wakestand.tistory.com/808&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://wakestand.tistory.com/808&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1742520553759&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Git local에 없는 branch switch 하는 방법&quot; data-og-description=&quot;Git에 만들어져 있는 branch이긴 한데 local에 다운로드 받지 않았을 경우 git switch branch명으로 branch 변경이 되지 않는데 $ git switch branch명 fatal: invalid reference: branch명 이런 식의 에러가 뜨게 된다 여&quot; data-og-host=&quot;wakestand.tistory.com&quot; data-og-source-url=&quot;https://wakestand.tistory.com/808&quot; data-og-url=&quot;https://wakestand.tistory.com/808&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/pH5sD/hyYrQkMWD1/vIeDEUScLQR6WQMUWTq7w1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/pH5sD/hyYrQkMWD1/vIeDEUScLQR6WQMUWTq7w1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://wakestand.tistory.com/808&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://wakestand.tistory.com/808&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/pH5sD/hyYrQkMWD1/vIeDEUScLQR6WQMUWTq7w1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/pH5sD/hyYrQkMWD1/vIeDEUScLQR6WQMUWTq7w1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Git local에 없는 branch switch 하는 방법&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Git에 만들어져 있는 branch이긴 한데 local에 다운로드 받지 않았을 경우 git switch branch명으로 branch 변경이 되지 않는데 $ git switch branch명 fatal: invalid reference: branch명 이런 식의 에러가 뜨게 된다 여&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;wakestand.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;오늘의 에러2&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1742520041932&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;error: The following untracked working tree files would be overwritten by merge:&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;576&quot; data-origin-height=&quot;234&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7Vetx/btsMRlXnVLv/q9ckeK7fv3eL2BiJxNHTEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7Vetx/btsMRlXnVLv/q9ckeK7fv3eL2BiJxNHTEk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7Vetx/btsMRlXnVLv/q9ckeK7fv3eL2BiJxNHTEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7Vetx%2FbtsMRlXnVLv%2Fq9ckeK7fv3eL2BiJxNHTEk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;576&quot; height=&quot;234&quot; data-origin-width=&quot;576&quot; data-origin-height=&quot;234&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;122&quot; data-start=&quot;110&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;오류 원인&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;240&quot; data-start=&quot;123&quot; data-ke-size=&quot;size16&quot;&gt;Git은 파일을 병합하는 과정에서 &lt;b&gt;로컬에서 수정되지 않은 파일은 덮어쓸 수 있지만, Git이 추적하고 있지 않은(untracked) 파일이 존재하면 덮어쓰기를 방지&lt;/b&gt;한다. 그래서 에러가 발생했다.&lt;/p&gt;
&lt;p data-end=&quot;240&quot; data-start=&quot;123&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;264&quot; data-start=&quot;242&quot; data-ke-size=&quot;size23&quot;&gt;해결 방법 (선택지 2가지)&lt;/h3&gt;
&lt;h3 data-end=&quot;264&quot; data-start=&quot;242&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;방법1) 로컬 경로의 파일 삭제하기 (로컬 변경 사항 무시)&lt;/b&gt;&lt;br /&gt;만약 원격 저장소의 파일로 덮어써도 상관없다면, 로컬의 해당 파일을 삭제하면 됩니다.그런 다음 다시 병합을 시도합니다.&lt;/h3&gt;
&lt;pre id=&quot;code_1742520132249&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;rm Content/DYL/Blueprints/BP_SuperGameMode.uasset&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 병합 시도&lt;/p&gt;
&lt;pre id=&quot;code_1742520154326&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git pull&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;방법2) Git의 원격 저장소 파일 삭제하기 (원격 저장소 변경 사항 무시)&lt;/b&gt;&lt;br /&gt;만약 로컬 파일이 더 중요하고 원격 저장소에서 해당 파일을 업데이트하지 않기를 원한다면, 원격 저장소에서 해당 파일을 삭제하거나 .gitignore로 무시하도록 설정할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;907&quot; data-start=&quot;636&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;907&quot; data-start=&quot;636&quot;&gt;.gitignore에 추가하는 방법 (추적하지 않도록 설정)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1742520208235&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;echo &quot;Content/DYL/Blueprints/BP_SuperGameMode.uasset&quot; &amp;gt;&amp;gt; .gitignore
git rm --cached Content/DYL/Blueprints/BP_SuperGameMode.uasset
git commit -m &quot;Ignore BP_SuperGameMode.uasset file&quot;
git push&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;해결 과정&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;578&quot; data-origin-height=&quot;74&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cKZYOq/btsMQRCs9K0/tmnkLTEpC5AwC6WSwa0KdK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cKZYOq/btsMQRCs9K0/tmnkLTEpC5AwC6WSwa0KdK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cKZYOq/btsMQRCs9K0/tmnkLTEpC5AwC6WSwa0KdK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcKZYOq%2FbtsMQRCs9K0%2FtmnkLTEpC5AwC6WSwa0KdK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;578&quot; height=&quot;74&quot; data-origin-width=&quot;578&quot; data-origin-height=&quot;74&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;578&quot; data-origin-height=&quot;130&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pR6Tq/btsMRSgbvkn/2BuCH0TBGBTLbwamoYIBN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pR6Tq/btsMRSgbvkn/2BuCH0TBGBTLbwamoYIBN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pR6Tq/btsMRSgbvkn/2BuCH0TBGBTLbwamoYIBN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpR6Tq%2FbtsMRSgbvkn%2F2BuCH0TBGBTLbwamoYIBN0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;578&quot; height=&quot;130&quot; data-origin-width=&quot;578&quot; data-origin-height=&quot;130&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;해결 완료&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;576&quot; data-origin-height=&quot;31&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zNap6/btsMSGeWQVI/TIOpZQHQKtJb9tq9gk6m2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zNap6/btsMSGeWQVI/TIOpZQHQKtJb9tq9gk6m2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zNap6/btsMSGeWQVI/TIOpZQHQKtJb9tq9gk6m2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzNap6%2FbtsMSGeWQVI%2FTIOpZQHQKtJb9tq9gk6m2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;576&quot; height=&quot;31&quot; data-origin-width=&quot;576&quot; data-origin-height=&quot;31&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>오늘의 에러</category>
      <category>git</category>
      <category>gitbash</category>
      <category>git브랜치변경</category>
      <category>git원격브랜치를로컬브랜치로가져오기</category>
      <category>git충돌해결</category>
      <category>버전관리</category>
      <category>오늘의에러</category>
      <author>D0YUN</author>
      <guid isPermaLink="true">https://alizwldyl.tistory.com/48</guid>
      <comments>https://alizwldyl.tistory.com/48#entry48comment</comments>
      <pubDate>Fri, 21 Mar 2025 10:32:04 +0900</pubDate>
    </item>
    <item>
      <title>[오늘의에러/UE] fatal error C1083: 포함 파일을 열 수 없습니다. 'Character/CCharacter.h': No such file or directory (헤더 파일과 소스 파일을 한 폴더에 담았을 때 소스 파일이 헤더 파일을 인식하지 못하는 경우)</title>
      <link>https://alizwldyl.tistory.com/47</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;오늘의 에러&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1742101784831&quot; class=&quot;routeros&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;fatal error C1083: 포함 파일을 열 수 없습니다. 'Character/CCharacter.h': No such file or directory&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;클론 코딩하다가 소스 파일이 헤더 파일을 인식하지 못하는 에러를 만났다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;에러 발생&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1911&quot; data-origin-height=&quot;1079&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/buV4hO/btsMMI5xeMO/SALnHjkv80kl3tXXETzmd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/buV4hO/btsMMI5xeMO/SALnHjkv80kl3tXXETzmd1/img.png&quot; data-alt=&quot;CCharacter.cpp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/buV4hO/btsMMI5xeMO/SALnHjkv80kl3tXXETzmd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbuV4hO%2FbtsMMI5xeMO%2FSALnHjkv80kl3tXXETzmd1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1911&quot; height=&quot;1079&quot; data-origin-width=&quot;1911&quot; data-origin-height=&quot;1079&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;CCharacter.cpp&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;언리얼에서 Player 역할을 할 `CCharacter` 파일을 생성하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이때 Public, Private 폴더에 각각 헤더 파일과 소스 파일을 추가하는 것 대신 &lt;b&gt;Character라는 폴더에서 한번에 관리&lt;/b&gt;하기 위해 Character 폴더 하위에 두 파일이 생성되도록 설정을 하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;같은 폴더 안에 있으면 당연하게 인식을 해야 하는데 &lt;b&gt;소스 파일이 헤더 파일을 인식하지 못하&lt;/b&gt;여 당황스러웠다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;에러 원인&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 이 에러는 주로 &lt;b&gt;`#include` 경로 문제&lt;/b&gt;에서 발생한다고 한다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 케이스는 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Unreal Engine의 빌드 시스템이 &lt;/span&gt;`Character.h`와 `Character.cpp`가 들어 있는&lt;b&gt; Character 폴더의 경로를 제대로 인식하지 못해서&lt;/b&gt; 발생했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; Unreal에서는 보통 `Source/프로젝트이름/` 아래 `Public`과 `Private` 폴더를 두고 관리하며, `Public`에 있는 헤더는 `#include &quot;CCharacter.h&quot;`처럼 단순 이름으로 접근하는 것이 일반적이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;그런데 Character 폴더에 두 파일을 함께 담았을 경우 U&lt;b&gt;nreal Engine의 Public 또는 Private 폴더 구조를 고려하지 않았기 때문&lt;/b&gt;에 제&lt;b&gt;대로 인식하지 못하게&lt;/b&gt; 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;u&gt;이를 인식시키기 위해서는&lt;b&gt; `CCharacter.h`가 있는 폴더를 `Build.cs` 파일에서 추가&lt;/b&gt;해서 Unreal Build System이 해당 파일을 찾을 수 있도록 해줘야 한다.&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;해결 방법&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1868&quot; data-origin-height=&quot;740&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLR8x7/btsMLMacIEr/pRmzUckN9XsLVFgfPOfKNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLR8x7/btsMLMacIEr/pRmzUckN9XsLVFgfPOfKNK/img.png&quot; data-alt=&quot;Odyssey.Build.cs&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLR8x7/btsMLMacIEr/pRmzUckN9XsLVFgfPOfKNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLR8x7%2FbtsMLMacIEr%2FpRmzUckN9XsLVFgfPOfKNK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1868&quot; height=&quot;740&quot; data-origin-width=&quot;1868&quot; data-origin-height=&quot;740&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Odyssey.Build.cs&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 이 에러를 해결하려면 프로젝트의 `Build.cs` 파일에서 `PublicIncludePaths`에 올바른 헤더 경로를 추가해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;방법은 두 가지다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;방법1&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1742102165366&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;PublicIncludePaths.Add(ModuleDirectory);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 방법을 이용하면 `ModuleDirectory`를 추가하여 &lt;b&gt;`Source/Odyssey/` 전체를 포함&lt;/b&gt;할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1863&quot; data-origin-height=&quot;753&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tVcdj/btsMLOr9gHF/Kqc4RG0Mr5JYjLGGDUC051/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tVcdj/btsMLOr9gHF/Kqc4RG0Mr5JYjLGGDUC051/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tVcdj/btsMLOr9gHF/Kqc4RG0Mr5JYjLGGDUC051/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtVcdj%2FbtsMLOr9gHF%2FKqc4RG0Mr5JYjLGGDUC051%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1863&quot; height=&quot;753&quot; data-origin-width=&quot;1863&quot; data-origin-height=&quot;753&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;973&quot; data-start=&quot;846&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;901&quot; data-start=&quot;846&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`#include &quot;CCharacter.h&quot;`처럼 &lt;b&gt;간략한 경로로 헤더를 포함&lt;/b&gt;할 수 있고&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;973&quot; data-start=&quot;904&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`Character` 폴더를 따로 지정하지 않아도 `ModuleDirectory` 아래에 있는 모든 헤더 파일을 검색할 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;방법2&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1742104266463&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;PublicIncludePaths.Add(Path.Combine(ModuleDirectory, &quot;Character&quot;));&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 이 방법을 사용하면 `&lt;b&gt;Character` 디렉터리만 포함 경로에 추가&lt;/b&gt;할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`Character` 폴더만 포함 경로에 추가되므로, &lt;b&gt;헤더 검색 범위를 최소화&lt;/b&gt;할 수 있고&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이를 통해 빌드 속도를 조금 더 최적화할 가능성이 생긴다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;모든 C++ 파일을 Public, Private을 나누지 않고 기능 별로 묶어 한 폴더에서 관리할 예정이라 방법1을 선택하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;추가 개념 정리&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h4 data-end=&quot;186&quot; data-start=&quot;153&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// PublicIncludePaths&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;317&quot; data-start=&quot;187&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Unreal Build System에서 헤더 파일을 검색하는 경로 목록이다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;317&quot; data-start=&quot;187&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;여기에 추가된 경로는 다른 모듈에서도 접근할 수 있는 `Public` 헤더 파일들의 포함 경로로 사용된다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1742103914511&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;PublicIncludePaths.Add(ModuleDirectory);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 위와 같이 설정하면, &lt;b&gt;ModuleDirectory 내부의 모든 폴더가 검색 경로로 추가&lt;/b&gt;된다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이를 통해 `#include &quot;파일명.h&quot; `형식으로 간략하게 불러올 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;449&quot; data-start=&quot;419&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// ModuleDirectory&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-end=&quot;504&quot; data-start=&quot;450&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`ModuleDirectory`는 현재 모듈의 &lt;b&gt;루트 디렉터리 경로&lt;/b&gt;를 나타내는 문자열이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;504&quot; data-start=&quot;450&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 프로젝트의 구조를 빌려 설명하자면&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1742104817663&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Odyssey/
 ├── Source/
 │   ├── Odyssey/   (ModuleDirectory)
 │   │   ├── Character/
 │   │   │   ├── CCharacter.h
 │   │   │   ├── CCharacter.cpp&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;504&quot; data-start=&quot;450&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`ModuleDirectory` = `&quot;Source/Odyssey&quot;`&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`PublicIncludePaths.Add(ModuleDirectory);`를 추가하면 &lt;b&gt;`Source/Odyssey/` 내부의 모든 폴더&lt;/b&gt;에서 헤더를 찾을 수 있다. &lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1742104879397&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &quot;CCharacter.h&quot;  // 정상적으로 인식 가능&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;642&quot; data-origin-height=&quot;40&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qEM61/btsMLzotYc3/yNdpWDiDhUjBULTEWCJ6y0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qEM61/btsMLzotYc3/yNdpWDiDhUjBULTEWCJ6y0/img.png&quot; data-alt=&quot;해결완료&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qEM61/btsMLzotYc3/yNdpWDiDhUjBULTEWCJ6y0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqEM61%2FbtsMLzotYc3%2FyNdpWDiDhUjBULTEWCJ6y0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;642&quot; height=&quot;40&quot; data-origin-width=&quot;642&quot; data-origin-height=&quot;40&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;해결완료&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>오늘의 에러</category>
      <category>C++</category>
      <category>UE</category>
      <category>VisualStudio</category>
      <category>경로에러</category>
      <category>오늘의에러</category>
      <author>D0YUN</author>
      <guid isPermaLink="true">https://alizwldyl.tistory.com/47</guid>
      <comments>https://alizwldyl.tistory.com/47#entry47comment</comments>
      <pubDate>Sun, 16 Mar 2025 15:04:27 +0900</pubDate>
    </item>
    <item>
      <title>[YYBASIC0401/얌얌코딩] std::string 클래스 만들어보기</title>
      <link>https://alizwldyl.tistory.com/44</link>
      <description>&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;

namespace ya
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;class string
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 기본 생성자: mStr을 nullptr로 초기화하여 정의되지 않은 동작을 방지
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 멤버 이니셜라이저(:)를 사용하여 mStr을 직접 초기화함으로써 불필요한 대입을 방지하고 성능 최적화
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;string() : mStr(nullptr)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::cout &amp;lt;&amp;lt; &quot;nullptr\n&quot;;&amp;nbsp;&amp;nbsp;// 디버깅용: 기본 생성자가 호출되었음을 알림
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// C 스타일 문자열을 사용하여 객체를 초기화하는 생성자
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 멤버 이니셜라이저(:)를 사용하여 mStr을 nullptr로 초기화한 후, 동적 할당을 통해 문자열을 저장
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;string(const char* str) : mStr(nullptr)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// str이 null이 아님을 가정하고, 입력 문자열의 길이를 계산
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int len = strlen(str);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 문자열과 널 종료문자('\0')를 저장할 메모리를 동적으로 할당
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mStr = new char[len + 1];

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 문자열을 한 글자씩 복사
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for (size_t i = 0; i &amp;lt; len; i++)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mStr[i] = str[i];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::cout &amp;lt;&amp;lt; mStr[i] &amp;lt;&amp;lt; '\n';&amp;nbsp;&amp;nbsp;// 디버깅용: 복사되는 문자 출력
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::cout &amp;lt;&amp;lt; &quot;\n&quot;;&amp;nbsp;&amp;nbsp;// 디버깅용: 복사 완료 후 줄바꿈 출력

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 문자열 끝에 널 종료문자('\0')를 추가하여 올바른 문자열 형식을 유지
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mStr[len] = '\0';
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 소멸자: 동적으로 할당된 메모리를 해제하여 메모리 누수를 방지
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;~string()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;delete[] mStr;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 문자열을 저장하는 동적 할당된 메모리의 포인터
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;char* mStr;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};
}

int main()
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 표준 라이브러리의 std::string을 선언 및 초기화
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::string hello = &quot;Hello!&quot;;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 기본 생성자로 ya::string 객체를 생성 (mStr이 nullptr로 초기화됨)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ya::string yaHello1;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 기본 생성자를 사용한 임시 객체를 생성한 후, 이를 yaHello2에 복사하여 초기화
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 주의: 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 1. C++ 컴파일러는 최적화를 통해 불필요한 복사를 줄이는 RVO(Return Value Optimization)를 수행할 수도 있음
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 2. 하지만 일부 컴파일러나 특정 상황에서는 RVO가 적용되지 않아 객체가 복사될 가능성이 있음
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 3. 즉, yaHello2는 ya::string()을 호출하여 생성된 임시 객체에서 복사되지만, 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RVO가 적용되지 않으면 불필요한 복사 생성자가 호출될 수도 있으므로 권장되지 않음
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ya::string yaHello2 = ya::string();

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// C 스타일 문자열을 사용하여 ya::string 객체를 초기화
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ya::string yaHello3 = &quot;Hello!&quot;;&amp;nbsp;&amp;nbsp;// 문자열을 받는 생성자 호출
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ya::string yaHello4(&quot;Hello!&quot;);&amp;nbsp;&amp;nbsp; // 동일한 방식의 객체 초기화

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return 0;
}&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;// 디버깅용 코드 실행 결과&lt;/b&gt;&lt;/h4&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1857&quot; data-origin-height=&quot;1118&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSq1Uz/btsMIsCt7qN/d6oxlqYaQWngMQ8D0CS5VK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSq1Uz/btsMIsCt7qN/d6oxlqYaQWngMQ8D0CS5VK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSq1Uz/btsMIsCt7qN/d6oxlqYaQWngMQ8D0CS5VK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSq1Uz%2FbtsMIsCt7qN%2Fd6oxlqYaQWngMQ8D0CS5VK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1857&quot; height=&quot;1118&quot; data-origin-width=&quot;1857&quot; data-origin-height=&quot;1118&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1855&quot; data-origin-height=&quot;1104&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTPjHF/btsMJ41qU7l/MA7PoMXvfB6HkvvgMmd031/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTPjHF/btsMJ41qU7l/MA7PoMXvfB6HkvvgMmd031/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTPjHF/btsMJ41qU7l/MA7PoMXvfB6HkvvgMmd031/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTPjHF%2FbtsMJ41qU7l%2FMA7PoMXvfB6HkvvgMmd031%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1855&quot; height=&quot;1104&quot; data-origin-width=&quot;1855&quot; data-origin-height=&quot;1104&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1853&quot; data-origin-height=&quot;1096&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bM5mdG/btsMIGncd6Y/1TheFNTxclBHkmlFIrxVE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bM5mdG/btsMIGncd6Y/1TheFNTxclBHkmlFIrxVE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bM5mdG/btsMIGncd6Y/1TheFNTxclBHkmlFIrxVE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbM5mdG%2FbtsMIGncd6Y%2F1TheFNTxclBHkmlFIrxVE1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1853&quot; height=&quot;1096&quot; data-origin-width=&quot;1853&quot; data-origin-height=&quot;1096&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1854&quot; data-origin-height=&quot;1097&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6YsOO/btsMJJQMyQQ/UhcCL14i2OZM1gC8E5Lf10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6YsOO/btsMJJQMyQQ/UhcCL14i2OZM1gC8E5Lf10/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6YsOO/btsMJJQMyQQ/UhcCL14i2OZM1gC8E5Lf10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6YsOO%2FbtsMJJQMyQQ%2FUhcCL14i2OZM1gC8E5Lf10%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1854&quot; height=&quot;1097&quot; data-origin-width=&quot;1854&quot; data-origin-height=&quot;1097&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=evQbRsNbjFk&quot; target=&quot;_self&quot;&gt;&lt;span&gt;LV12 string 클래스 만들어보기&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=evQbRsNbjFk&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/M3DHj/hyYrQcISDN/qz0kfpaCwEZ9mkxiYUX4wk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/FMcGB/hyYqVyPezI/xeLwyi6fgDm1dY8miAi7A1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-video-title=&quot;LV12 string 클래스 만들어보기&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/evQbRsNbjFk&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>C++/YYBASIC</category>
      <category>String</category>
      <category>개발</category>
      <category>게임프로그래밍</category>
      <category>얌얌코딩</category>
      <category>연산자오버로딩</category>
      <category>프로그래밍</category>
      <author>D0YUN</author>
      <guid isPermaLink="true">https://alizwldyl.tistory.com/44</guid>
      <comments>https://alizwldyl.tistory.com/44#entry44comment</comments>
      <pubDate>Fri, 14 Mar 2025 16:45:05 +0900</pubDate>
    </item>
    <item>
      <title>[백준/C++] 10988(팰린드롬인지 확인하기) (단순 인덱스 비교 / 캐시 최적화 / reverse() / deque / 투 포인터 / 재귀)</title>
      <link>https://alizwldyl.tistory.com/42</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1116&quot; data-origin-height=&quot;1042&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mgCa8/btsMIM0PMxw/3fiTIIZhyRJS7IeBx5euhk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mgCa8/btsMIM0PMxw/3fiTIIZhyRJS7IeBx5euhk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mgCa8/btsMIM0PMxw/3fiTIIZhyRJS7IeBx5euhk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmgCa8%2FbtsMIM0PMxw%2F3fiTIIZhyRJS7IeBx5euhk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1116&quot; height=&quot;1042&quot; data-origin-width=&quot;1116&quot; data-origin-height=&quot;1042&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/10988&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/10988&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;내가 해냄 : 단순 인덱스 비교 방식&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1741736515353&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include&amp;lt;iostream&amp;gt;
using namespace std;

int main()
{
    // 문자열을 입력받는다.
    string s;
    cin &amp;gt;&amp;gt; s;

    // 문자열의 길이를 변수에 저장한다.
    int len = (int)s.size();

    // 문자열이 팰린드롬인지 확인하기 위해 절반만 검사한다.
    for (int i = 0; i &amp;lt; len / 2; i++)
    {
        // i번째 문자와 (len-1-i)번째 문자가 다르면 팰린드롬이 아니다.
        if (s[i] != s[len - 1 - i])
        {
            // 팰린드롬이 아님을 의미하는 0을 출력하고 프로그램을 종료한다.
            cout &amp;lt;&amp;lt; 0;
            return 0;
        }
    }

    // 모든 비교를 통과하면 팰린드롬이므로 1을 출력한다.
    cout &amp;lt;&amp;lt; 1;
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;사용한 핵심 개념&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;// &lt;b&gt;단순 인덱스 비교 방식&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;401&quot; data-start=&quot;200&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;261&quot; data-start=&quot;200&quot;&gt;문자열의 &lt;b&gt;앞쪽(s[i])과 뒤쪽(s[len - 1 - i])을 직접 인덱스로 접근&lt;/b&gt;하여 비교한다.&lt;/li&gt;
&lt;li data-end=&quot;314&quot; data-start=&quot;262&quot;&gt;반복문을 &lt;b&gt;문자열 길이의 절반(len / 2)까지만 실행&lt;/b&gt;하여 비교 횟수를 최소화 하였다.&lt;/li&gt;
&lt;li data-end=&quot;370&quot; data-start=&quot;315&quot;&gt;만약 &lt;b&gt;하나라도 다르면(대칭이 깨지면) 즉시 0을 출력하고 종료&lt;/b&gt; (`return 0;`)하여 추가적인 반복을 배제한다.&lt;/li&gt;
&lt;li data-end=&quot;401&quot; data-start=&quot;371&quot;&gt;모든 비교를 통과하면 팰린드롬이므로 1을 출력하고 함수를 종료한다.&lt;/li&gt;
&lt;li data-end=&quot;401&quot; data-start=&quot;371&quot;&gt;&lt;b&gt;투 포인터 방식과 비슷&lt;/b&gt;하지만, &lt;b&gt;두 개의 포인터를 따로 선언하지 않고 인덱스를 직접 계산하여 접근&lt;/b&gt;한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AI 피드백 : 캐시 효율 증가&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1741738009717&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
using namespace std;

int main() {
    // 문자열 입력
    string s;
    cin &amp;gt;&amp;gt; s;

    int len = (int)s.size();
    int half = len / 2; // 미리 계산하여 반복 조건을 줄임

    // 팰린드롬 검사
    for (int i = 0; i &amp;lt; half; i++) {
        char front = s[i], back = s[len - 1 - i]; // 변수에 저장하여 캐시 효율 증가
        if (front != back) {
            cout &amp;lt;&amp;lt; 0;
            return 0;
        }
    }

    cout &amp;lt;&amp;lt; 1;
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;주요 최적화 내용&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;// 반복문에서 반복 조건 계산 줄이기&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;232&quot; data-start=&quot;151&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;228&quot; data-start=&quot;151&quot;&gt;`len`을 반복문 내부에서 계속 참조하는 대신, 미리 `half = len / 2;`를 계산하여 반복 시 불필요한 연산을 줄인다&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;// for 문 내부에서 변수를 미리 선언하여 캐시 최적화&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;545&quot; data-start=&quot;466&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;545&quot; data-start=&quot;466&quot;&gt;루프 안에서 `s[i]`와 `s[len - 1 - i]`를 매번 접근하는 대신, 한 번 변수에 저장하여 CPU 캐시 효율을 높일 수 있다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;35&quot; data-start=&quot;0&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;루프 내부 변수 선언을 통한 캐시 최적화란?&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-end=&quot;55&quot; data-start=&quot;37&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;// 기존 방식&lt;/b&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741738161022&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for (int i = 0; i &amp;lt; len / 2; i++)
{
    if (s[i] != s[len - 1 - i]) // 매번 s[i]와 s[len - 1 - i]에 직접 접근
    {
        cout &amp;lt;&amp;lt; 0;
        return 0;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;367&quot; data-start=&quot;220&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;275&quot; data-start=&quot;220&quot;&gt;`s[i]`와 `s[len - 1 - i]`를 매번 &lt;b&gt;직접 배열 인덱싱&lt;/b&gt;하여 비교하는 방식이다.&lt;/li&gt;
&lt;li data-end=&quot;315&quot; data-start=&quot;276&quot;&gt;&lt;b&gt;문자열 s의 메모리 주소&lt;/b&gt;를 &lt;b&gt;반복적으로 참조&lt;/b&gt;하게 된다.&lt;/li&gt;
&lt;li data-end=&quot;367&quot; data-start=&quot;316&quot;&gt;&lt;b&gt;CPU 캐시에서 데이터를 불러오는 과정이 반복&lt;/b&gt;되므로 &lt;b&gt;성능이 미세하게 저하&lt;/b&gt;될 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;401&quot; data-start=&quot;374&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;// 캐시 최적화를 적용한 방식&lt;/b&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741738280504&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for (int i = 0; i &amp;lt; len / 2; i++) {
    char front = s[i], back = s[len - 1 - i]; // 변수에 저장하여 캐시 효율 증가
    if (front != back) {
        cout &amp;lt;&amp;lt; 0;
        return 0;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;748&quot; data-start=&quot;586&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;651&quot; data-start=&quot;586&quot;&gt;`s[i]`와 `s[len - 1 - i]`를 &lt;b&gt;변수(`front`, `back`)에 한 번만 저장&lt;/b&gt;한다.&lt;/li&gt;
&lt;li data-end=&quot;699&quot; data-start=&quot;652&quot;&gt;이후 &lt;b&gt;메모리에서 불러오는 대신 변수로 비교&lt;/b&gt;하므로 캐시 효율이 증가한다.&lt;/li&gt;
&lt;li data-end=&quot;748&quot; data-start=&quot;700&quot;&gt;&lt;b&gt;CPU&lt;/b&gt;가 &lt;b&gt;필요 없는 메모리 접근을 줄이게&lt;/b&gt; 되어 &lt;b&gt;성능이 미세하게 향상&lt;/b&gt;된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;776&quot; data-start=&quot;755&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;// 캐시 최적화의 원리&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1211&quot; data-start=&quot;777&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;911&quot; data-start=&quot;777&quot;&gt;&lt;b&gt;CPU 캐시(Cache)란?&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;911&quot; data-start=&quot;803&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;859&quot; data-start=&quot;803&quot;&gt;CPU는 데이터를 빠르게 읽기 위해 &lt;b&gt;캐시(Cache)&lt;/b&gt;라는 &lt;b&gt;작은 고속 메모리&lt;/b&gt;를 사용한다.&lt;/li&gt;
&lt;li data-end=&quot;911&quot; data-start=&quot;862&quot;&gt;하지만, &lt;b&gt;캐시에 없는 데이터&lt;/b&gt;는 &lt;b&gt;RAM&lt;/b&gt;에서 불러와야 하고, 이는 &lt;b&gt;상대적으로 느리다&lt;/b&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1081&quot; data-start=&quot;913&quot;&gt;&lt;b&gt;배열 접근과 캐시 미스(Cache Miss)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1081&quot; data-start=&quot;948&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1010&quot; data-start=&quot;948&quot;&gt;배열 인덱스를 여러 번 참조하면, &lt;b&gt;해당 데이터가 캐시에 없을 가능성이 높아진다&lt;/b&gt;(&lt;b&gt;캐시 미스 발생&lt;/b&gt;).&lt;/li&gt;
&lt;li data-end=&quot;1081&quot; data-start=&quot;1013&quot;&gt;따라서 반복문 안에서 동일한 값을 여러 번 참조하는 경우, &lt;b&gt;변수에 저장&lt;/b&gt;해두면 &lt;b&gt;캐시 접근을 최소화&lt;/b&gt;할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1211&quot; data-start=&quot;1083&quot;&gt;&lt;b&gt;변수를 활용한 최적화 효과&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1211&quot; data-start=&quot;1108&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1181&quot; data-start=&quot;1108&quot;&gt;`s[i]`와 `s[len - 1 - i]` 값을 &lt;b&gt;미리 변수에 저장&lt;/b&gt;하면 &lt;b&gt;CPU&lt;/b&gt;가 &lt;b&gt;캐시&lt;/b&gt;에서 빠르게 값을 읽을 수 있다.&lt;/li&gt;
&lt;li data-end=&quot;1211&quot; data-start=&quot;1184&quot;&gt;메모리 접근 비용을 줄여 성능이 향상된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;1248&quot; data-start=&quot;1218&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;// 성능 차이 분석 (실제 적용 효과)&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 59px;&quot; border=&quot;1&quot; data-end=&quot;1444&quot; data-start=&quot;1249&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 21.2791%; height: 19px;&quot;&gt;방식&lt;/td&gt;
&lt;td style=&quot;width: 42.3256%; height: 19px;&quot;&gt;&lt;span&gt;&lt;span&gt;메모리 접근 횟수&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 36.2791%; height: 19px;&quot;&gt;CPU 캐시 최적화 효과&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot; data-end=&quot;1389&quot; data-start=&quot;1329&quot;&gt;
&lt;td style=&quot;width: 21.2791%; height: 20px;&quot;&gt;기존 방식&lt;/td&gt;
&lt;td style=&quot;width: 42.3256%; height: 20px;&quot;&gt;&lt;span&gt;&lt;span&gt;O(N)&lt;/span&gt;&lt;/span&gt;&amp;nbsp;(반복문마다 s[i]와 s[len-1-i]에 접근)&lt;/td&gt;
&lt;td style=&quot;width: 36.2791%; height: 20px;&quot;&gt;낮음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot; data-end=&quot;1444&quot; data-start=&quot;1390&quot;&gt;
&lt;td style=&quot;width: 21.2791%; height: 20px;&quot;&gt;변수 저장 방식&lt;/td&gt;
&lt;td style=&quot;width: 42.3256%; height: 20px;&quot;&gt;&lt;span&gt;&lt;span&gt;O(N) &lt;/span&gt;&lt;/span&gt;(한 번만 배열 접근 후 변수로 비교)&lt;/td&gt;
&lt;td style=&quot;width: 36.2791%; height: 20px;&quot;&gt;높음&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1759&quot; data-start=&quot;1575&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1648&quot; data-start=&quot;1575&quot;&gt;기존 방식과의 성능 차이가 크지 않지만, &lt;b&gt;CPU 캐시 미스를 줄이려면 변수에 저장하여 비교하는 것&lt;/b&gt;이 &lt;b&gt;더 효율적&lt;/b&gt;이다.&lt;/li&gt;
&lt;li data-end=&quot;1759&quot; data-start=&quot;1706&quot;&gt;고성능이 중요한 환경에서는 &lt;b&gt;이런 작은 최적화들이 누적되면서 차이&lt;/b&gt;를 만들 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;또 다른 풀이 1 : `reverse()` 이용&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot; data-start=&quot;1007&quot; data-end=&quot;1104&quot;&gt;
&lt;li data-start=&quot;1007&quot; data-end=&quot;1043&quot;&gt;&lt;b&gt;문자열을 뒤집어서 원본 문자열과 비교하는 방식&lt;/b&gt;이다.&lt;/li&gt;
&lt;li data-start=&quot;1044&quot; data-end=&quot;1104&quot;&gt;C++의 reverse() 함수를 사용하여&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;빠르게 문자열을 뒤집고, 원본과 비교하면 된다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1741738756697&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;algorithm&amp;gt; // reverse() 함수 포함
using namespace std;

int main() {
    string s;
    cin &amp;gt;&amp;gt; s;

    string rev = s; // 원본 문자열을 복사
    reverse(rev.begin(), rev.end()); // 문자열을 뒤집음

    cout &amp;lt;&amp;lt; (s == rev ? 1 : 0); // 원본과 비교하여 출력
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;// 장점&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot; data-start=&quot;1401&quot; data-end=&quot;1452&quot;&gt;
&lt;li data-start=&quot;1401&quot; data-end=&quot;1427&quot;&gt;코드가 &lt;b&gt;매우 간결하고 직관적&lt;/b&gt;이다.&lt;/li&gt;
&lt;li data-start=&quot;1428&quot; data-end=&quot;1452&quot;&gt;STL을 활용하여 가독성이 높아진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;// 단점&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot; data-start=&quot;1466&quot; data-end=&quot;1564&quot;&gt;
&lt;li data-start=&quot;1466&quot; data-end=&quot;1509&quot;&gt;&lt;b&gt;문자열을 복사&lt;/b&gt;하는 과정에서 &lt;b&gt;O(N)의 추가적인 공간&lt;/b&gt;이 필요하다.&lt;/li&gt;
&lt;li data-start=&quot;1510&quot; data-end=&quot;1564&quot;&gt;`reverse()` 연산도 &lt;b&gt;O(N)&lt;/b&gt;이므로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;시간 복잡도가 O(N)으로 동일&lt;/b&gt;하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;또 다른 풀이 2 : `deque`(덱)를 이용한 풀이&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1834&quot; data-start=&quot;1689&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1734&quot; data-start=&quot;1689&quot;&gt;&lt;b&gt;deque(덱)&lt;/b&gt;를 사용하여 &lt;b&gt;문자열을 앞뒤에서 비교&lt;/b&gt;하는 방식이다.&lt;/li&gt;
&lt;li data-end=&quot;1834&quot; data-start=&quot;1735&quot;&gt;덱은 &lt;b&gt;양쪽에서 데이터를 추가 및 제거할 수 있는 자료구조&lt;/b&gt;이며, 이를 활용하면 투 포인터 방식처럼 &lt;b&gt;앞과 뒤를 비교하면서 값을 제거하는 방식&lt;/b&gt;으로 풀이 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1741739342376&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;deque&amp;gt;
using namespace std;

int main() {
    string s;
    cin &amp;gt;&amp;gt; s;
    
    deque&amp;lt;char&amp;gt; dq(s.begin(), s.end()); // 문자열을 덱에 저장

    while (dq.size() &amp;gt; 1) { // 덱의 크기가 1보다 클 때까지 비교
        if (dq.front() != dq.back()) { // 앞과 뒤가 다르면 팰린드롬 아님
            cout &amp;lt;&amp;lt; 0;
            return 0;
        }
        dq.pop_front(); // 앞 문자 제거
        dq.pop_back();  // 뒤 문자 제거
    }

    cout &amp;lt;&amp;lt; 1; // 팰린드롬이면 1 출력
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;// 장점&lt;/b&gt;&lt;/h4&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2392&quot; data-start=&quot;2309&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2356&quot; data-start=&quot;2309&quot;&gt;덱을 활용하면 &lt;b&gt;큐와 유사한 방식&lt;/b&gt;으로 &lt;b&gt;앞뒤를 제거&lt;/b&gt;하면서 비교할 수 있다.&lt;/li&gt;
&lt;li data-end=&quot;2392&quot; data-start=&quot;2357&quot;&gt;&lt;b&gt;직관적&lt;/b&gt;으로 &lt;b&gt;앞과 뒤에서 접근하는 방식이 명확&lt;/b&gt;하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;// 단점&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2502&quot; data-start=&quot;2406&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2445&quot; data-start=&quot;2406&quot;&gt;&lt;b&gt;덱을 생성&lt;/b&gt;하는 과정에서 &lt;b&gt;O(N)의 추가 공간이 필요&lt;/b&gt;하다.&lt;/li&gt;
&lt;li data-end=&quot;2502&quot; data-start=&quot;2446&quot;&gt;&lt;b&gt;`pop_front()`와 `pop_back()`&lt;/b&gt;이 실행될 때마다 &lt;b&gt;오버헤드가 발생&lt;/b&gt;할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;또&amp;nbsp;다른&amp;nbsp;풀이&amp;nbsp;3&amp;nbsp;:&amp;nbsp;투&amp;nbsp;포인터(Two&amp;nbsp;Pointer)&amp;nbsp;이용&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;투 포인터(Two Pointers) 방식은 &lt;b&gt;두 개의 포인터(left, right)를 사용하여 비교&lt;/b&gt;하는 방식이다.&lt;/p&gt;
&lt;pre id=&quot;code_1741739809991&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
using namespace std;

int main() {
    string s;
    cin &amp;gt;&amp;gt; s;

    int left = 0, right = (int)s.size() - 1; // 두 개의 포인터 설정

    while (left &amp;lt; right) { // 두 포인터가 교차하기 전까지 반복
        if (s[left] != s[right]) { // 대칭이 깨지면 팰린드롬이 아님
            cout &amp;lt;&amp;lt; 0;
            return 0;
        }
        left++;  // 왼쪽 포인터 이동
        right--; // 오른쪽 포인터 이동
    }

    cout &amp;lt;&amp;lt; 1; // 팰린드롬이면 1 출력
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;2451&quot; data-start=&quot;2426&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;투 포인터 방식의 장점&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-end=&quot;2463&quot; data-start=&quot;2452&quot; data-ke-size=&quot;size20&quot;&gt;// &lt;b&gt;가독성&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2612&quot; data-start=&quot;2464&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2518&quot; data-start=&quot;2464&quot;&gt;`left`와 `right` 두 개의 포인터를 사용하므로, &lt;b&gt;코드의 흐름이 명확&lt;/b&gt;하다.&lt;/li&gt;
&lt;li data-end=&quot;2612&quot; data-start=&quot;2519&quot;&gt;기존 코드에서는 `s[len - 1 - i]`처럼 인덱스를 직접 계산해야 했지만, 여기서는 &lt;b&gt;두 개의 포인터가 이동하면서 비교&lt;/b&gt;하므로 &lt;b&gt;논리적으로 직관적&lt;/b&gt;이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;2638&quot; data-start=&quot;2614&quot; data-ke-size=&quot;size20&quot;&gt;// &lt;b&gt;다양한 문제 해결에 적용 가능&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2799&quot; data-start=&quot;2639&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2727&quot; data-start=&quot;2639&quot;&gt;투 포인터 방식은 &lt;b&gt;문자열 비교&lt;/b&gt;뿐만 아니라, &lt;b&gt;정렬된 배열에서 특정 값을 찾는&lt;/b&gt; 문제, &lt;b&gt;두 개의 배열을 합치는&lt;/b&gt; 문제 등 &lt;b&gt;다양한 곳에서 활용 가능&lt;/b&gt;하다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2799&quot; data-start=&quot;2728&quot;&gt;ex) 정렬된 배열에서 특정 합을 가지는 두 수를 찾는 문제(Two Sum)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;2818&quot; data-start=&quot;2801&quot; data-ke-size=&quot;size20&quot;&gt;// &lt;b&gt;성능 향상 가능성&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2963&quot; data-start=&quot;2819&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2877&quot; data-start=&quot;2819&quot;&gt;기존 코드와 시간 복잡도는 동일하지만, &lt;b&gt;특정한 경우&lt;/b&gt;에는 &lt;b&gt;캐시 효율이 증가&lt;/b&gt;할 가능성이 있다.&lt;/li&gt;
&lt;li data-end=&quot;2963&quot; data-start=&quot;2878&quot;&gt;캐시 미스를 줄이기 위해 두 포인터를 사용하면 &lt;b&gt;배열을 순차적으로 탐색&lt;/b&gt;하므로 &lt;b&gt;공간 지역성(Spatial Locality)이 더욱 극대화&lt;/b&gt;된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;또&amp;nbsp;다른&amp;nbsp;풀이&amp;nbsp;4&amp;nbsp;:&amp;nbsp;재귀(Recursion)&amp;nbsp;이용&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2729&quot; data-start=&quot;2677&quot;&gt;`isPalindrome()` 함수를 &lt;b&gt;재귀적으로 호출&lt;/b&gt;하면서 앞과 뒤의 문자를 비교한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1741740272147&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
using namespace std;

bool isPalindrome(const string &amp;amp;s, int left, int right) {
    if (left &amp;gt;= right) return true; // 기저 사례: 모든 문자가 일치했을 경우
    if (s[left] != s[right]) return false; // 문자가 다르면 팰린드롬 아님
    return isPalindrome(s, left + 1, right - 1); // 재귀 호출
}

int main() {
    string s;
    cin &amp;gt;&amp;gt; s;
    cout &amp;lt;&amp;lt; (isPalindrome(s, 0, s.size() - 1) ? 1 : 0);
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;3151&quot; data-start=&quot;3140&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;// 장점&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3230&quot; data-start=&quot;3152&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3230&quot; data-start=&quot;3190&quot;&gt;재귀 호출을 활용하여 &lt;b&gt;다른 문제에도 쉽게 응용할 수 있다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;3243&quot; data-start=&quot;3232&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;// 단점&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3346&quot; data-start=&quot;3244&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3298&quot; data-start=&quot;3244&quot;&gt;재귀 호출이 많아지면 &lt;b&gt;스택 오버플로우(Stack Overflow) &lt;/b&gt;위험이 존재한다.&lt;/li&gt;
&lt;li data-end=&quot;3346&quot; data-start=&quot;3299&quot;&gt;&lt;b&gt;반복문보다 성능이 떨어지&lt;/b&gt;며, &lt;b&gt;비효율적인 메모리 사용&lt;/b&gt;이 발생할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;667&quot; data-origin-height=&quot;250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bd5tOp/btsMGAA0zYX/pDBO3z8KQ3NPCf3lrqgZMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bd5tOp/btsMGAA0zYX/pDBO3z8KQ3NPCf3lrqgZMk/img.png&quot; data-alt=&quot;(맨 아래부터) 단순 인덱스 비교 / 캐시 최적화 이용 / reverse() 이용 / deque 이용 / Two pointer 이용 / Recursion 이용&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bd5tOp/btsMGAA0zYX/pDBO3z8KQ3NPCf3lrqgZMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbd5tOp%2FbtsMGAA0zYX%2FpDBO3z8KQ3NPCf3lrqgZMk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;667&quot; height=&quot;250&quot; data-origin-width=&quot;667&quot; data-origin-height=&quot;250&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(맨 아래부터) 단순 인덱스 비교 / 캐시 최적화 이용 / reverse() 이용 / deque 이용 / Two pointer 이용 / Recursion 이용&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 문제였는데 생각보다 다양한 풀이 방법이 있어서 흥미로웠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>C++/BAEKJOON</category>
      <category>C++</category>
      <category>reverse함수</category>
      <category>개발</category>
      <category>덱</category>
      <category>백준</category>
      <category>인덱스비교</category>
      <category>재귀</category>
      <category>캐시최적화</category>
      <category>코딩테스트</category>
      <category>투포인터</category>
      <author>D0YUN</author>
      <guid isPermaLink="true">https://alizwldyl.tistory.com/42</guid>
      <comments>https://alizwldyl.tistory.com/42#entry42comment</comments>
      <pubDate>Wed, 12 Mar 2025 12:15:34 +0900</pubDate>
    </item>
    <item>
      <title>[백준/C++] 15651(N과 M (2)) (중복 순열 / 백 트래킹 / 재귀 / 완전 탐색 / ostringstream)</title>
      <link>https://alizwldyl.tistory.com/41</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;931&quot; data-origin-height=&quot;497&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c7ktEk/btsMHnUAGyD/E6AFKCbuYYbW3KA0JDIvIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c7ktEk/btsMHnUAGyD/E6AFKCbuYYbW3KA0JDIvIk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c7ktEk/btsMHnUAGyD/E6AFKCbuYYbW3KA0JDIvIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc7ktEk%2FbtsMHnUAGyD%2FE6AFKCbuYYbW3KA0JDIvIk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;931&quot; height=&quot;497&quot; data-origin-width=&quot;931&quot; data-origin-height=&quot;497&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;934&quot; data-origin-height=&quot;1248&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/s4J9W/btsMHsuIfb0/BuaUjHf4vItfUDX5MKVhr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/s4J9W/btsMHsuIfb0/BuaUjHf4vItfUDX5MKVhr1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/s4J9W/btsMHsuIfb0/BuaUjHf4vItfUDX5MKVhr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fs4J9W%2FbtsMHsuIfb0%2FBuaUjHf4vItfUDX5MKVhr1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;934&quot; height=&quot;1248&quot; data-origin-width=&quot;934&quot; data-origin-height=&quot;1248&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/15651&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/15651&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;내가 해냄 : Back tracking 이용&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1741653413560&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;bits/stdc++.h&amp;gt;
using namespace std;

int N, M;               // 자연수 N과 M을 저장하는 변수
vector&amp;lt;int&amp;gt; v;          // 1부터 N까지의 숫자를 저장할 벡터
vector&amp;lt;int&amp;gt; result;     // 선택한 숫자를 저장할 벡터

/*
    문제의 핵심:
    - 숫자를 중복해서 선택할 수 있기 때문에 방문 체크를 하지 않는다.
    - 사전 순 증가하는 순서로 출력해야 하므로 1부터 N까지의 숫자를 저장한 후 백트래킹을 수행한다.
*/

// 백트래킹을 활용하여 자기 자신을 포함하여 M개의 원소를 선택한다
void backtrack(int depth)
{
    // M개를 선택했으면 출력한다
    if (depth == M)
    {
        for(int i = 0; i &amp;lt; M; i++)
            cout &amp;lt;&amp;lt; result[i] &amp;lt;&amp;lt; ( i != M - 1 ? &quot; &quot; : &quot;\n&quot;);
        return;
    }

    // 숫자를 선택한다
    for (int i = 0; i &amp;lt; N; i++) {
        result.push_back(v[i]); // 현재 선택한 숫자를 result에 추가한다

        backtrack(depth + 1);   // 다음 숫자를 선택하기 위해 재귀함수를 호출한다

        // Backtracking : 선택한 숫자를 제거하여 이전 상태로 되돌아 간다
        result.pop_back();
    }
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);

    // N과 M을 입력받는다
    cin &amp;gt;&amp;gt; N &amp;gt;&amp;gt; M;

    // 1부터 N까지 수를 벡터 v에 저장한다
    v.resize(N);
    iota(v.begin(), v.end(), 1);

    // 백트래킹을 시작한다 (depth = 0)
    backtrack(0);

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;사용한 핵심 개념&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-end=&quot;872&quot; data-start=&quot;820&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// 중복을 허용하는 순열 (중복 순열, Multiset Permutation)&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1002&quot; data-start=&quot;876&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;944&quot; data-start=&quot;876&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;문제에서 &lt;b&gt;같은 수를 여러 번 선택할 수 있으므로&lt;/b&gt; 일반적인 순열이 아닌 &quot;중복을 허용하는 순열&quot;을 만들어야 한다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1002&quot; data-start=&quot;948&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;따라서, 방문 체크 (`visited[]`)를 하지 않고 모든 숫자를 선택할 수 있도록 한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1017&quot; data-start=&quot;1007&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;사용 예시&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741653517324&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for (int i = 0; i &amp;lt; N; i++) {
    result.push_back(v[i]); // 현재 숫자 선택
    backtrack(depth + 1);   // 다음 숫자 선택
    result.pop_back();      // 백트래킹
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1301&quot; data-start=&quot;1212&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1252&quot; data-start=&quot;1212&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;방문 체크를 하지 않고&lt;/b&gt; 모든 숫자를 다시 선택할 수 있도록 허용했다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1301&quot; data-start=&quot;1256&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`v[i]`를 &lt;b&gt;여러 번 선택&lt;/b&gt;하여 &lt;b&gt;중복된 숫자가 포함된 수열&lt;/b&gt;을 생성할 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;70&quot; data-start=&quot;40&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// 백트래킹 (Backtracking)&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;222&quot; data-start=&quot;74&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;112&quot; data-start=&quot;74&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;백트래킹은 &lt;b&gt;모든 가능한 경우를 탐색&lt;/b&gt;하는 알고리즘 기법이다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;156&quot; data-start=&quot;116&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;불필요한 경로를 미리 차단하여 &lt;b&gt;탐색 속도를 최적화&lt;/b&gt;할 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;222&quot; data-start=&quot;160&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이번 문제에서는 &lt;b&gt;M개의 숫자를 중복 선택할 수 있는 순열&lt;/b&gt;을 생성하는 과정에서 백트래킹을 사용했다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;237&quot; data-start=&quot;227&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;사용 예시&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;pre id=&quot;code_1741653622092&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void backtrack(int depth)
{
    if (depth == M) { // M개의 숫자를 선택한 경우 출력
        for(int i = 0; i &amp;lt; M; i++)
            cout &amp;lt;&amp;lt; result[i] &amp;lt;&amp;lt; (i != M - 1 ? &quot; &quot; : &quot;\n&quot;);
        return;
    }

    for (int i = 0; i &amp;lt; N; i++) {
        result.push_back(v[i]); // 현재 숫자 선택
        backtrack(depth + 1);   // 다음 숫자 선택 (재귀 호출)
        result.pop_back();      // 백트래킹 (이전 상태로 복구)
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;813&quot; data-start=&quot;687&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;722&quot; data-start=&quot;687&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;현재 `depth`가 M이면 완성된 수열이므로 출력한다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;768&quot; data-start=&quot;726&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;1부터 N까지의 숫자를 선택하고, `depth+1` 단계로 넘어간다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;813&quot; data-start=&quot;772&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`result.pop_back();`을 수행하여 &lt;b&gt;이전 상태로&lt;/b&gt; 되돌린다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;AI 피드백 : 완전 탐색을 활용한 구현&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1741654615752&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;  // 표준 입출력 사용 (cin, cout)
#include &amp;lt;vector&amp;gt;    // 벡터 자료구조 사용 (vector&amp;lt;int&amp;gt;)
#include &amp;lt;sstream&amp;gt;   // 문자열 스트림 사용 (ostringstream)

using namespace std;

int N, M;           // 입력으로 주어지는 자연수 N과 M
ostringstream out;  // 출력을 버퍼에 저장하여 성능을 최적화하는 스트림 객체

int main() {
    ios_base::sync_with_stdio(0); // 입출력 속도 최적화 (C 스타일 입출력과 동기화 해제)
    cin.tie(0); cout.tie(0);      // 입력과 출력을 분리하여 속도를 더 향상시킴

    // 사용자 입력 받기: N(1~N까지 숫자 사용), M(길이가 M인 수열 생성)
    cin &amp;gt;&amp;gt; N &amp;gt;&amp;gt; M;

    // M자리 수열을 표현할 벡터 (모든 자리 초기값을 1로 설정)
    vector&amp;lt;int&amp;gt; indices(M, 1);

    while (true) {
        // 현재 선택된 숫자들을 출력 스트림(out)에 저장
        for (int i = 0; i &amp;lt; M; i++)
            out &amp;lt;&amp;lt; indices[i] &amp;lt;&amp;lt; (i != M - 1 ? &quot; &quot; : &quot;\n&quot;); // 마지막 숫자 뒤에는 개행 추가

        // 가장 오른쪽 자리부터 증가시키면서 새로운 조합 생성
        int pos = M - 1;  // 맨 끝자리(index M-1)부터 증가시키기 시작
        while (pos &amp;gt;= 0 &amp;amp;&amp;amp; indices[pos] == N) 
            pos--;  // 현재 자리의 숫자가 N이면, 그 앞자리(pos-1)를 변경

        // pos가 -1이면 모든 조합을 생성했으므로 종료
        if (pos &amp;lt; 0) break;

        indices[pos]++; // 현재 자릿수 값 증가

        // 증가한 자리(pos) 뒤쪽의 모든 숫자를 1로 초기화
        for (int i = pos + 1; i &amp;lt; M; i++) 
            indices[i] = 1;
    }

    // 한 번에 모든 출력을 수행하여 속도 향상
    cout &amp;lt;&amp;lt; out.str();
    
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;사용한 핵심 개념&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-end=&quot;30&quot; data-start=&quot;0&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// 완전 탐색 (Brute Force)&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;241&quot; data-start=&quot;31&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;89&quot; data-start=&quot;31&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;모든 경우의 수를 전부 탐색하는 방식&lt;/b&gt;으로, 가능한 모든 선택지를 하나씩 나열하며 답을 찾는다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;154&quot; data-start=&quot;90&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 문제에서는 `N^M`개의 경우의 수가 존재하며, &lt;b&gt;모든 경우를 직접 생성하여 출력하는 방식&lt;/b&gt;을 사용한다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;241&quot; data-start=&quot;155&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;백트래킹을 사용하면 불필요한 탐색을 줄일 수 있지만, 이 코드에서는 &lt;b&gt;반복문을 활용하여 단순하게 모든 경우의 수를 직접 생성&lt;/b&gt;하는 방식을 선택했다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;264&quot; data-start=&quot;243&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;예제 (N=3, M=2)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;299&quot; data-start=&quot;265&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;입력값이 `N = 3`, `M = 2`라면, 가능한 모든 조합은:&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741696683217&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;379&quot; data-start=&quot;344&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 조합을 &lt;b&gt;순서대로 생성하는 것이 완전 탐색의 핵심&lt;/b&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;379&quot; data-start=&quot;344&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;407&quot; data-start=&quot;381&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;코드에서 완전 탐색을 구현한 부분&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741696713111&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;while (true) {  // 모든 경우를 생성할 때까지 반복
    for (int i = 0; i &amp;lt; M; i++)
        out &amp;lt;&amp;lt; indices[i] &amp;lt;&amp;lt; (i != M - 1 ? &quot; &quot; : &quot;\n&quot;);

    int pos = M - 1;
    while (pos &amp;gt;= 0 &amp;amp;&amp;amp; indices[pos] == N) pos--;  // 더 증가할 수 있는 자리 찾기

    if (pos &amp;lt; 0) break;  // 모든 조합을 다 만들었으면 종료

    indices[pos]++;  // 증가할 수 있는 자리 증가
    for (int i = pos + 1; i &amp;lt; M; i++) indices[i] = 1;  // 이후 자리 초기화
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;864&quot; data-start=&quot;793&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;조건을 만족하는지 확인하는 과정 없이 무조건 모든 경우를 출력&lt;/b&gt;하기 때문에 완전 탐색이 이루어지고 있다고 볼 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;864&quot; data-start=&quot;793&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;864&quot; data-start=&quot;793&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;910&quot; data-start=&quot;871&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// 사전순 탐색 (Lexicographic Order)&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1072&quot; data-start=&quot;911&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;958&quot; data-start=&quot;911&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;가장 작은 숫자부터 시작&lt;/b&gt;해서 &lt;b&gt;사전순으로 증가&lt;/b&gt;하는 순서로 탐색하는 방법이다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1012&quot; data-start=&quot;959&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;문제에서 사전순 증가 형태로 출력해야 하므로, &lt;b&gt;작은 수부터 증가&lt;/b&gt;하면서 새로운 조합을 만든다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1072&quot; data-start=&quot;1013&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`indices` 배열을 1부터 시작하고, &lt;b&gt;오른쪽 자리부터 숫자를 증가&lt;/b&gt;시키는 방식으로 구현한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1095&quot; data-start=&quot;1074&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;예제 (N=3, M=2)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1194&quot; data-start=&quot;1096&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1128&quot; data-start=&quot;1096&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`{1,1}` &amp;rarr; `{1,2}` &amp;rarr; `{1,3}`&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1161&quot; data-start=&quot;1129&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`{2,1}` &amp;rarr; `{2,2}` &amp;rarr; `{2,3}`&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1194&quot; data-start=&quot;1162&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`{3,1}` &amp;rarr; `{3,2}` &amp;rarr; `{3,3}`&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;1229&quot; data-start=&quot;1196&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;모든 조합이 &lt;b&gt;사전순(오름차순)으로 정렬&lt;/b&gt;되어 탐색된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1229&quot; data-start=&quot;1196&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1258&quot; data-start=&quot;1231&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;코드에서 사전순 탐색을 구현한 부분&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741696960024&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for (int i = pos + 1; i &amp;lt; M; i++) indices[i] = 1;  // 증가한 자리 뒤를 1로 초기화&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1467&quot; data-start=&quot;1399&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;출력 순서&lt;/b&gt;가 &lt;b&gt;작은 수&lt;/b&gt;에서 &lt;b&gt;큰 수&lt;/b&gt;로 변한다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1467&quot; data-start=&quot;1399&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;반복문&lt;/b&gt;을 활용하여 &lt;b&gt;증가된 자리 이후의 값&lt;/b&gt;들은&amp;nbsp;&lt;b&gt;가장 작은 값(1)으로 다시 초기화&lt;/b&gt;되어&lt;b&gt; 별도의 정렬 없이 사전순 정렬&lt;/b&gt;을 유지한다&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;1509&quot; data-start=&quot;1474&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// 자리값 조정 (Position Update)&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1619&quot; data-start=&quot;1510&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1563&quot; data-start=&quot;1510&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;숫자를 증가&lt;/b&gt;시키면서 &lt;b&gt;모든 조합&lt;/b&gt;을 만들되, &lt;b&gt;오른쪽 자리부터 증가&lt;/b&gt;시키는 방식을 사용한다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1619&quot; data-start=&quot;1564&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;마지막 숫자가 N에 도달하면, &lt;b&gt;그 앞자리를 증가&lt;/b&gt;시키고 &lt;b&gt;뒷자리는 다시 1로 초기화&lt;/b&gt;한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1648&quot; data-start=&quot;1621&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;자리 증가 과정 (N=3, M=2)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1854&quot; data-start=&quot;1649&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1710&quot; data-start=&quot;1649&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`{1,1}` &amp;rarr; `{1,2}` &amp;rarr; `{1,3}` : &lt;b&gt;오른쪽 자리(두 번째 숫자)만 증가&lt;/b&gt;한다&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1786&quot; data-start=&quot;1711&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`{2,1}` &amp;rarr; `{2,2}` &amp;rarr; `{2,3}` : &lt;b&gt;첫 번째 숫자를 증가&lt;/b&gt;시키고 &lt;b&gt;두 번째 숫자는 1부터 다시 시작&lt;/b&gt;한다&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1854&quot; data-start=&quot;1787&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`{3,1}` &amp;rarr; `{3,2}` &amp;rarr; `{3,3}` : &lt;b&gt;첫 번째 숫자가 N까지 도달&lt;/b&gt;하면 &lt;b&gt;탐색을 종료&lt;/b&gt;한다&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;1883&quot; data-start=&quot;1856&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;코드에서 자리값 조정을 구현한 부분&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741697115576&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int pos = M - 1;
while (pos &amp;gt;= 0 &amp;amp;&amp;amp; indices[pos] == N) pos--;  // 더 증가할 수 있는 자리 찾기

if (pos &amp;lt; 0) break;  // 모든 조합을 다 만들었으면 종료

indices[pos]++;  // 증가할 수 있는 자리 증가
for (int i = pos + 1; i &amp;lt; M; i++) indices[i] = 1;  // 이후 자리 초기화&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2189&quot; data-start=&quot;2121&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;오른쪽 자리부터 확인&lt;/b&gt;하여 &lt;b&gt;&lt;b&gt;N&lt;/b&gt;&lt;/b&gt;이면 &lt;b&gt;&lt;b&gt;앞자리를 증가&lt;/b&gt;&lt;/b&gt;시키고 &lt;b&gt;&lt;b&gt;뒤의 숫자를 초기화&lt;/b&gt;&lt;/b&gt;하여 &lt;b&gt;증가 가능 여부를 판단&lt;/b&gt;한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;2189&quot; data-start=&quot;2121&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2189&quot; data-start=&quot;2121&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;39&quot; data-start=&quot;0&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// ostringstream를 활용한 입출력 최적화&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-end=&quot;74&quot; data-start=&quot;40&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;`cout`을 여러 번 호출하는 것의 문제점&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;195&quot; data-start=&quot;75&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;134&quot; data-start=&quot;75&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`cout`을 사용하면 데이터가 &lt;b&gt;한 번 출력될 때마다 버퍼를 flush(비우는 작업)&lt;/b&gt; 하게 된다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;195&quot; data-start=&quot;135&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;즉, `cout`을 여러 번 호출하면 &lt;b&gt;매번 버퍼를 비우면서 출력을 수행&lt;/b&gt;하므로 &lt;b&gt;실행 속도가 느려&lt;/b&gt;진다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2189&quot; data-start=&quot;2121&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;예제 (비효율적인 출력)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741697366041&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for (int i = 0; i &amp;lt; M; i++) {
    cout &amp;lt;&amp;lt; indices[i];  
    if (i != M - 1) cout &amp;lt;&amp;lt; &quot; &quot;;
    else cout &amp;lt;&amp;lt; &quot;\n&quot;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;415&quot; data-start=&quot;346&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;378&quot; data-start=&quot;346&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;위 코드에서는 `cout`이 &lt;b&gt;최소 M번 호출&lt;/b&gt;된다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;415&quot; data-start=&quot;379&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;버퍼를 자주 flush하기 때문에 &lt;b&gt;출력 성능이 저하&lt;/b&gt;된다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;461&quot; data-start=&quot;422&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;`ostringstream`을 사용한 해결 방법&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;568&quot; data-start=&quot;462&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;538&quot; data-start=&quot;462&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`ostringstream`은 &lt;b&gt;출력을 버퍼(메모리)에 저장&lt;/b&gt;해 두었다가, &lt;b&gt;한 번에 `cout`을 통해 출력&lt;/b&gt;할 수 있도록 도와준다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;568&quot; data-start=&quot;539&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;출력 횟수를 최소화&lt;/b&gt;하여 &lt;b&gt;성능을 향상&lt;/b&gt;시킨다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2189&quot; data-start=&quot;2121&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;예제 (`ostringstream`을 활용한 출력 최적화)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741697496077&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ostringstream out; // 출력 버퍼 선언

for (int i = 0; i &amp;lt; M; i++) {
    out &amp;lt;&amp;lt; indices[i];  
    if (i != M - 1) out &amp;lt;&amp;lt; &quot; &quot;;
    else out &amp;lt;&amp;lt; &quot;\n&quot;; 
}

// 한 번에 출력 (여기서만 cout을 사용)
cout &amp;lt;&amp;lt; out.str();&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;897&quot; data-start=&quot;816&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;버퍼에 모든 출력 내용을 저장&lt;/b&gt;한 후, `cout`을 &lt;b&gt;단 한 번 호출&lt;/b&gt;하여 출력한다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;897&quot; data-start=&quot;816&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;출력 연산이 많을 때&lt;/b&gt; 성능이 크게 향상된다&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-start=&quot;145&quot; data-end=&quot;198&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;백트래킹 (Backtracking) vs. 완전 탐색 (Brute Force)&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;474&quot; data-origin-height=&quot;102&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blBU8p/btsMHg2ksMn/6BI7nAN2ZTH5sjdO62wZ1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blBU8p/btsMHg2ksMn/6BI7nAN2ZTH5sjdO62wZ1k/img.png&quot; data-alt=&quot;(위) 완전 탐색 이용 / (아래) 백 트래킹 이&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blBU8p/btsMHg2ksMn/6BI7nAN2ZTH5sjdO62wZ1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblBU8p%2FbtsMHg2ksMn%2F6BI7nAN2ZTH5sjdO62wZ1k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;474&quot; height=&quot;102&quot; data-origin-width=&quot;474&quot; data-origin-height=&quot;102&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(위) 완전 탐색 이용 / (아래) 백 트래킹 이&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 실행 결과에서 위는 완전 탐색을 이용한 코드의 결과이고, 아래는 백 트래킹으로 푼 코드의 결과이고, 위는 완전 탐색을 이용한 코드의 결과이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;두 가지 접근법(백트래킹 vs. 완전 탐색)의 성능 차이가 크지 않은 이유는 &lt;b&gt;입력 크기가 상대적으로 작기 때문&lt;/b&gt;이다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;그러나 &lt;b&gt;입력 크기가 커질수록&lt;/b&gt;, 두 방식의 차이가 더욱 두드러지게 나타난다고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;643&quot; data-start=&quot;625&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;실행 결과 분석&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-end=&quot;663&quot; data-start=&quot;644&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// 메모리 사용량&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;781&quot; data-start=&quot;664&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;724&quot; data-start=&quot;664&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;백트래킹 (2020 KB)이 &lt;b&gt;완전 탐색 (29844 KB)보다 훨씬 적은 메모리를 사용&lt;/b&gt;함.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;781&quot; data-start=&quot;725&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;완전 탐색은 &lt;b&gt;모든 경우를 직접 메모리에 저장하거나 탐색&lt;/b&gt;해야 하므로, &lt;b&gt;메모리 소비가 더 큼&lt;/b&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;800&quot; data-start=&quot;783&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// 실행 시간&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;930&quot; data-start=&quot;801&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;860&quot; data-start=&quot;801&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;백트래킹 (296 ms)이 완전 탐색 (240 ms)보다 약간 더 느리지만, &lt;b&gt;차이가 크지 않음&lt;/b&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;930&quot; data-start=&quot;861&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;백트래킹이 &lt;b&gt;불필요한 탐색을 줄여 최적화&lt;/b&gt;할 수 있지만, 이번 경우에는 &lt;b&gt;탐색 공간이 작아&lt;/b&gt; 최적화 효과가 크지 않았음.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;965&quot; data-start=&quot;937&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;언제 어떤 방식을 사용해야 할까?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-end=&quot;988&quot; data-start=&quot;966&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;// &lt;b&gt;백트래킹이 유용한 경우&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1466&quot; data-start=&quot;989&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1179&quot; data-start=&quot;989&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;탐색 공간이 큰 경우 (N이 크고 M이 클 때)&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1179&quot; data-start=&quot;1030&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1121&quot; data-start=&quot;1030&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;예제에서는 N, M이 상대적으로 작아서 완전 탐색도 효율적이었지만, N = 10, M = 5 이상이 되면 &lt;b&gt;완전 탐색은 기하급수적으로 시간이 증가&lt;/b&gt;하게 된다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1179&quot; data-start=&quot;1125&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;백트래킹은 &lt;b&gt;탐색 중 불필요한 경우를 가지치기(Pruning)&lt;/b&gt;하면서 탐색 공간을 줄일 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1326&quot; data-start=&quot;1181&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;순열(Permutation)이나 조합(Combination)&lt;/b&gt;을 구할 때&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1326&quot; data-start=&quot;1231&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1279&quot; data-start=&quot;1231&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;특정 조건을 만족하는 경우만 선택해야 하는 경우 (예: 중복 없이 M개 선택)&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1326&quot; data-start=&quot;1283&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;완전 탐색은 모든 경우를 탐색하기 때문에 불필요한 탐색이 많아질 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1466&quot; data-start=&quot;1328&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;DFS(깊이 우선 탐색, Depth-First Search)와 결합&lt;/b&gt;할 때&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1466&quot; data-start=&quot;1379&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1422&quot; data-start=&quot;1379&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;그래프 탐색에서 &lt;b&gt;특정 조건을 만족&lt;/b&gt;하는 경로를 찾을 때 (예: 미로 탐색)&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1466&quot; data-start=&quot;1426&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;백트래킹을 사용하면 불필요한 경로를 미리 배제하여 성능을 개선할 수 있다&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-end=&quot;1496&quot; data-start=&quot;1473&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;// &lt;b&gt;완전 탐색이 유용한 경우&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1929&quot; data-start=&quot;1497&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1639&quot; data-start=&quot;1497&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;탐색 공간이 작고 단순한 경우 (N, M이 작을 때)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1639&quot; data-start=&quot;1539&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1639&quot; data-start=&quot;1589&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;작은 경우의 수를 탐색하는 문제에서는 &lt;b&gt;완전 탐색이 더 직관적이고 빠를 수 있다.&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1639&quot; data-start=&quot;1589&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 문제에서는 N과 M이 작아 완전 탐색도 충분히 빠르게 실행될 수 있었다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: none;&quot; data-end=&quot;1639&quot; data-start=&quot;1589&quot;&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1790&quot; data-start=&quot;1641&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;모든 경우를 반드시 탐색해야 하는 경우&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1790&quot; data-start=&quot;1673&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1723&quot; data-start=&quot;1673&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;가지치기를 하더라도 &lt;b&gt;모든 경우를 탐색해야 정답을 구할 수 있는 &lt;/b&gt;경우&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1790&quot; data-start=&quot;1727&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 문제처럼 M개를 선택하는 모든 가능한 조합을 &lt;b&gt;순서대로 출력해야 하는 문제&lt;/b&gt;라면 완전 탐색이 적합하다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1929&quot; data-start=&quot;1792&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;구현이 쉬운 경우&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1929&quot; data-start=&quot;1812&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1877&quot; data-start=&quot;1812&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;백트래킹을 적용할 수 있지만, &lt;b&gt;완전 탐색으로도 시간 내 해결 가능하다&lt;/b&gt;면 &lt;b&gt;구현이 더 쉬운 완전 탐색이 유리&lt;/b&gt;하다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1929&quot; data-start=&quot;1881&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 문제의 경우 반복문을 통해 해결하는 방식이 복잡하지 않기 때문에 완전 탐색도 실용적이었다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;618&quot; data-start=&quot;199&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center; width: 5.93023%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;방식&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 22.2093%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;개념&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 21.5116%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;장점&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 23.9535%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;단점&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 26.2791%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;언제 유용한가&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;457&quot; data-start=&quot;269&quot;&gt;
&lt;td style=&quot;width: 5.93023%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;백트래킹&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 22.2093%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;가능한 모든 경우를 탐색하되, 불필요한 탐색을 가지치기(Pruning)하여 최적화&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 21.5116%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;* 메모리 사용이 적다&lt;br /&gt;&lt;/b&gt;* 탐색 공간을 줄여 속도가 빠를 가능성이 높다&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 23.9535%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;일부 경우에는 백트래킹을 활용해도 최적화 효과가 크지 않을 수 있다&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.2791%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;탐색 공간이 크고, 가지치기가 가능한 경우&lt;/b&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;(예: 순열, 조합 문제)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;618&quot; data-start=&quot;458&quot;&gt;
&lt;td style=&quot;width: 5.93023%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;완전 탐색&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 22.2093%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;모든 경우의 수를 전부 생성하여 확인&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 21.5116%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;* 구현이 쉽고 직관적이다&lt;/b&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;* 모든 경우를 고려하므로 실수 가능성이 적다&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 23.9535%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;* 탐색 공간이 크면 비효율적이다&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;* 메모리 사용량이 많다&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.2791%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;탐색 공간이 작거나, 모든 경우를 반드시 탐색해야 하는 문제&lt;/b&gt; (예: 조합 생성)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 즉, &lt;b&gt;문제의 입력 크기&lt;/b&gt;와 &lt;b&gt;요구 사항&lt;/b&gt;에 따라 적절한 탐색 방법을 선택하여 풀면 된다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>C++/BAEKJOON</category>
      <category>C++</category>
      <category>ostringstream</category>
      <category>백트래킹</category>
      <category>알고리즘</category>
      <category>완전탐색</category>
      <category>재귀</category>
      <category>중복순열</category>
      <category>코딩테스트</category>
      <category>프로그래밍</category>
      <author>D0YUN</author>
      <guid isPermaLink="true">https://alizwldyl.tistory.com/41</guid>
      <comments>https://alizwldyl.tistory.com/41#entry41comment</comments>
      <pubDate>Tue, 11 Mar 2025 22:05:01 +0900</pubDate>
    </item>
    <item>
      <title>[백준/C++] 15649(N과 M (1)) (int를 string으로 / 순열 / next_permutation / 백트래킹)</title>
      <link>https://alizwldyl.tistory.com/40</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1332&quot; data-origin-height=&quot;1396&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lXjRX/btsMFyBU7Or/8olkLPW2jN45PZv1SE91Ak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lXjRX/btsMFyBU7Or/8olkLPW2jN45PZv1SE91Ak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lXjRX/btsMFyBU7Or/8olkLPW2jN45PZv1SE91Ak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlXjRX%2FbtsMFyBU7Or%2F8olkLPW2jN45PZv1SE91Ak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1332&quot; height=&quot;1396&quot; data-origin-width=&quot;1332&quot; data-origin-height=&quot;1396&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1322&quot; data-origin-height=&quot;837&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ALDc5/btsMFZ6YK1b/KlsrdMj5mQWLLqAh6wRk50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ALDc5/btsMFZ6YK1b/KlsrdMj5mQWLLqAh6wRk50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ALDc5/btsMFZ6YK1b/KlsrdMj5mQWLLqAh6wRk50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FALDc5%2FbtsMFZ6YK1b%2FKlsrdMj5mQWLLqAh6wRk50%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1322&quot; height=&quot;837&quot; data-origin-width=&quot;1322&quot; data-origin-height=&quot;837&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/15649&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/15649&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;내가 해냄 : `next_permutation()` 사용&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1741501706159&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;bits/stdc++.h&amp;gt;
using namespace std;

int main()
{
    // N과 M을 입력받는다.
    int N, M;
    cin &amp;gt;&amp;gt; N &amp;gt;&amp;gt; M;

    // 1부터 N까지의 자연수를 담을 벡터 v를 선언하고 초기화한다.
    vector&amp;lt;int&amp;gt; v;
    for (int i = 0; i &amp;lt; N; i++)
        v.push_back(i + 1);

    // prev: 직전에 출력한 순열 문자열을 저장하는 변수
    // cur: 현재 출력할 순열 문자열을 저장하는 변수
    string prev = &quot;&quot;, cur = &quot;&quot;;

    // next_permutation()을 이용하여 N개의 수로 만들 수 있는 모든 순열을 생성한다.
    // N Permutation N
    do {
        // 현재 순열에서 앞에서 M개를 선택하여 문자열 cur을 만든다.
        for (int i = 0; i &amp;lt; M; i++)
            cur += to_string(v[i]) + ((i != M - 1) ? &quot; &quot; : &quot;&quot;); // 마지막 원소 뒤에는 공백을 붙이지 않음

        // 현재 생성한 문자열(cur)이 이전에 출력한 문자열(prev)과 다르면
        // 중복되지 않는 순열이므로 출력한다
        if (cur != prev)
        {
            cout &amp;lt;&amp;lt; cur &amp;lt;&amp;lt; &quot;\n&quot;; 
            prev = cur; // 이전 문자열(prev)을 현재 문자열(cur)로 갱신
        }

        // 다음 반복을 위해 cur를 초기화한다.
        cur = &quot;&quot;;
    } while (next_permutation(v.begin(), v.end())); // 다음 순열이 존재하는 동안 반복

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;사용한 핵심 개념&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-end=&quot;72&quot; data-start=&quot;28&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;// `next_permutation()`을 이용한 순열 생성&lt;/b&gt;&lt;/h4&gt;
&lt;p data-end=&quot;82&quot; data-start=&quot;73&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;역할&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;189&quot; data-start=&quot;83&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;144&quot; data-start=&quot;83&quot;&gt;주어진 수열을 &lt;b&gt;사전순(lexicographical order)으로 다음 순열로 변환&lt;/b&gt;하는 함수다.&lt;/li&gt;
&lt;li data-end=&quot;189&quot; data-start=&quot;145&quot;&gt;이를 반복적으로 호출하면 &lt;b&gt;모든 순열을 사전순으로 탐색할 수 있다&lt;/b&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;200&quot; data-start=&quot;191&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;317&quot; data-start=&quot;201&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;270&quot; data-start=&quot;201&quot;&gt;vector 또는 배열과 함께 사용되며, &lt;b&gt;사전순으로 정렬된 상태(= 오름차순 정렬이 된 상태)에서 시작&lt;/b&gt;해야 &lt;b&gt;모든 순열을 탐색&lt;/b&gt;할 수 있다.&lt;/li&gt;
&lt;li data-end=&quot;317&quot; data-start=&quot;271&quot;&gt;최후의 순열(내림차순 상태)까지 도달하면 `false`를 반환하며 종료된다.&lt;/li&gt;
&lt;li data-end=&quot;331&quot; data-start=&quot;319&quot;&gt;&lt;b&gt;사용 예시&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741502111527&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;vector&amp;lt;int&amp;gt; v = {1, 2, 3};
do {
    for (int num : v) cout &amp;lt;&amp;lt; num &amp;lt;&amp;lt; &quot; &quot;;
    cout &amp;lt;&amp;lt; &quot;\n&quot;;
} while (next_permutation(v.begin(), v.end()));&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;494&quot; data-start=&quot;483&quot;&gt;&lt;b&gt;결과&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741502121995&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;588&quot; data-start=&quot;545&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;// 벡터 초기화 및 활용 (`vector&amp;lt;int&amp;gt;` 사용)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-end=&quot;598&quot; data-start=&quot;589&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;역할&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;700&quot; data-start=&quot;599&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;648&quot; data-start=&quot;599&quot;&gt;1부터 N까지의 자연수를 저장하는 벡터를 선언하고 초기화하는 역할을 한다.&lt;/li&gt;
&lt;li data-end=&quot;700&quot; data-start=&quot;649&quot;&gt;`push_back()`을 사용하여 &lt;b&gt;1부터 N까지의 값을 순차적으로 삽입한다&lt;/b&gt;. 이를 통해 저절로 오름차순 정렬이 된 효과를 볼 수 있다.&lt;/li&gt;
&lt;li data-end=&quot;700&quot; data-start=&quot;649&quot;&gt;&lt;b&gt;구현 방식&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1741502226888&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;vector&amp;lt;int&amp;gt; v;
for (int i = 0; i &amp;lt; N; i++) 
    v.push_back(i + 1);&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;806&quot; data-start=&quot;794&quot;&gt;&lt;b&gt;작동 원리&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;874&quot; data-start=&quot;807&quot;&gt;`for` 루프를 활용하여 `v[0] = 1, v[1] = 2, ..., v[N-1] = N`과 같이 초기화된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;918&quot; data-start=&quot;881&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;// `prev`와 `cur`을 이용한 중복 제거&lt;/b&gt;&lt;/h4&gt;
&lt;p data-end=&quot;928&quot; data-start=&quot;919&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;역할&lt;/b&gt;:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1086&quot; data-start=&quot;929&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1019&quot; data-start=&quot;929&quot;&gt;`next_permutation()`을 사용하면 &lt;b&gt;N개의 전체 순열을 생성&lt;/b&gt;하지만,&lt;br /&gt;앞 M개의 원소만 선택할 경우 일부 순열이 중복될 수 있다.&lt;/li&gt;
&lt;li data-end=&quot;1086&quot; data-start=&quot;1020&quot;&gt;이를 방지하기 위해 &lt;b&gt;직전 출력된 순열(prev)&lt;/b&gt;과 &lt;b&gt;현재 순열(cur)을 비교&lt;/b&gt;하여 &lt;b&gt;중복을 제거&lt;/b&gt;한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1100&quot; data-start=&quot;1088&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;구현 방식&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1741502355483&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;string prev = &quot;&quot;, cur = &quot;&quot;;
do {
    cur = &quot;&quot;;
    for (int i = 0; i &amp;lt; M; i++)
        cur += to_string(v[i]) + ((i != M - 1) ? &quot; &quot; : &quot;&quot;);
    
    if (cur != prev) { 
        cout &amp;lt;&amp;lt; cur &amp;lt;&amp;lt; &quot;\n&quot;; 
        prev = cur;
    }
} while (next_permutation(v.begin(), v.end()));&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1396&quot; data-start=&quot;1384&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;작동 원리&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1532&quot; data-start=&quot;1397&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1434&quot; data-start=&quot;1397&quot;&gt;`cur` 문자열을 생성하여 현재 M개의 숫자를 저장한다.&lt;/li&gt;
&lt;li data-end=&quot;1482&quot; data-start=&quot;1435&quot;&gt;`prev`와 `cur`을 비교하여 &lt;b&gt;중복되지 않은 경우&lt;/b&gt;에만 &lt;b&gt;출력&lt;/b&gt;한다.&lt;/li&gt;
&lt;li data-end=&quot;1532&quot; data-start=&quot;1483&quot;&gt;`prev`를 `cur`로 갱신하여 &lt;b&gt;다음 순열과 비교할 기준을 설정&lt;/b&gt;한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;50&quot; data-start=&quot;33&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;시간 복잡도 분석&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;156&quot; data-start=&quot;51&quot; data-ke-size=&quot;size16&quot;&gt;해당 코드는 `next_permutation()`을 이용하여 &lt;b&gt;N개의 수로 만들 수 있는 모든 순열을 탐색&lt;/b&gt;하며,&lt;br /&gt;각 순열에서 &lt;b&gt;M개의 원소만 선택하여 출력&lt;/b&gt;하는 구조이다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;659&quot; data-start=&quot;158&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;330&quot; data-start=&quot;158&quot;&gt;&lt;b&gt;`next_permutation()`의 호출 횟수&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;330&quot; data-start=&quot;198&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;279&quot; data-start=&quot;198&quot;&gt;`next_permutation(v.begin(), v.end())`은 &lt;b&gt;N개의 원소로 만들 수 있는 모든 순열&lt;/b&gt;을 순차적으로 생성한다.&lt;/li&gt;
&lt;li data-end=&quot;330&quot; data-start=&quot;283&quot;&gt;따라서 &lt;b&gt;N개의 순열&lt;/b&gt;을 생성하는 데 걸리는 시간 복잡도는 &lt;b&gt;O(N!)&lt;/b&gt;이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;526&quot; data-start=&quot;332&quot;&gt;&lt;b&gt;출력 문자열 생성 및 비교 연산&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;526&quot; data-start=&quot;362&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;423&quot; data-start=&quot;362&quot;&gt;`for` 루프를 통해 &lt;b&gt;M개의 원소를 선택&lt;/b&gt;하여 `&lt;b&gt;cur` 문자열을 구성하는 과정&lt;/b&gt;의 시간 복잡도는 &lt;b&gt;O(M)&lt;/b&gt;이다.&lt;/li&gt;
&lt;li data-end=&quot;484&quot; data-start=&quot;427&quot;&gt;`cur`과 `prev`를 비교하는 연산도 &lt;b&gt;문자열 길이가 O(M)&lt;/b&gt;이므로 &lt;b&gt;O(M)&lt;/b&gt;의 시간 복잡도를 갖는다.&lt;/li&gt;
&lt;li data-end=&quot;526&quot; data-start=&quot;488&quot;&gt;따라서, 한 번의 순열에 대해 수행하는 전체 연산의 시간 복잡도는 &lt;b&gt;O(M)&lt;/b&gt;이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;659&quot; data-start=&quot;528&quot;&gt;&lt;b&gt;총 시간 복잡도&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;659&quot; data-start=&quot;549&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;589&quot; data-start=&quot;549&quot;&gt;`next_permutation()`이 &lt;b&gt;O(N!)&lt;/b&gt;번 실행되며, 매 실행마다 O(M)의 연산을 수행하므로,&lt;/li&gt;
&lt;li data-end=&quot;659&quot; data-start=&quot;626&quot;&gt;전체 시간 복잡도는 &lt;b&gt;O(N! * M)&lt;/b&gt;이 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;804&quot; data-start=&quot;661&quot;&gt;즉, &lt;b&gt;N!이 급격하게 증가&lt;/b&gt;하므로 &lt;b&gt;N이 커질수록 실행 시간이 매우 빠르게 증가&lt;/b&gt;하는 알고리즘이다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;804&quot; data-start=&quot;661&quot;&gt;`prev`와 `cur`을 이용한 중복 제거를 통해 불필요한 출력을 방지하지만, 최악의 경우 여전히 O(N! * M)이 된다.&lt;/li&gt;
&lt;li data-end=&quot;804&quot; data-start=&quot;661&quot;&gt;상당히 비효율적이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AI 피드백 : 백트래킹(Backtracking) 활용&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1741503814458&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;     // 표준 입출력
#include &amp;lt;vector&amp;gt;       // vector 컨테이너
#include &amp;lt;algorithm&amp;gt;    // sort(), next_permutation()
#include &amp;lt;numeric&amp;gt;      // iota() 사용을 위한 헤더

using namespace std;

int N, M;
vector&amp;lt;int&amp;gt; v;          // 1부터 N까지의 수 저장
vector&amp;lt;bool&amp;gt; used;      // 방문 여부 체크
vector&amp;lt;int&amp;gt; result;     // 현재 선택된 수열

// 백트래킹을 이용하여 중복 없이 M개의 원소를 선택한다.
void backtrack(int depth) {
    // M개 선택 완료 시 출력한다.
    if (depth == M) {
        for (int i = 0; i &amp;lt; M; i++)
            cout &amp;lt;&amp;lt; result[i] &amp;lt;&amp;lt; (i != M - 1 ? &quot; &quot; : &quot;\n&quot;);
        return;
    }

    // 사용되지 않은 숫자를 하나씩 선택한다.
    for (int i = 0; i &amp;lt; N; i++) {
        if (!used[i]) {
            used[i] = true;          // 선택한 숫자를 방문 처리한다.
            result.push_back(v[i]);  // 현재 선택된 수열에 추가한다.

            backtrack(depth + 1);    // 다음 숫자를 선택한다.

            // 백트래킹: 이전 상태로 되돌린다.
            used[i] = false;
            result.pop_back();
        }
    }
}

int main() {
    // N과 M을 입력받는다.
    cin &amp;gt;&amp;gt; N &amp;gt;&amp;gt; M;

    // 1부터 N까지의 수를 벡터에 저장한다.
    v.resize(N);
    iota(v.begin(), v.end(), 1);

    // 방문 여부를 체크할 배열을 초기화한다.
    used.resize(N, false);

    // 백트래킹을 시작한다.
    backtrack(0);

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 data-end=&quot;841&quot; data-start=&quot;821&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;주요 개선 포인트&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-end=&quot;841&quot; data-start=&quot;821&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;// `next_permutation()`을 제거하고, 백트래킹을 이용하여 직접 순열을 생성했다&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1016&quot; data-start=&quot;904&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;953&quot; data-start=&quot;904&quot;&gt;기존 코드에서는 &lt;b&gt;모든 순열을 탐색한 후, 중복을 제거하는 방식&lt;/b&gt;을 사용했다.&lt;/li&gt;
&lt;li data-end=&quot;1016&quot; data-start=&quot;957&quot;&gt;개선된 코드에서는 &lt;b&gt;아예 중복이 없는 순열을 처음부터 생성&lt;/b&gt;하므로 불필요한 비교 연산이 사라짐.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;// 문자열 비교(prev vs cur) 방식 대신, `vector&amp;lt;bool&amp;gt; used`를 활용함&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1224&quot; data-start=&quot;1086&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1157&quot; data-start=&quot;1086&quot;&gt;기존 코드에서는 &lt;b&gt;이전 문자열(`prev`)과 현재 문자열(`cur`)을 비교하는 방식&lt;/b&gt;을 사용하여 중복을 제거했다.&lt;/li&gt;
&lt;li data-end=&quot;1224&quot; data-start=&quot;1161&quot;&gt;개선된 코드에서는 &lt;b&gt;이미 방문한 숫자&lt;/b&gt;를 `&lt;b&gt;used[i]`로 체크&lt;/b&gt;하여 &lt;b&gt;중복이 발생하지 않도록 차단&lt;/b&gt;했다&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;// 출력 최적화 (`cout` 활용)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1348&quot; data-start=&quot;1257&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1294&quot; data-start=&quot;1257&quot;&gt;기존 코드에서는 `cur` 문자열을 매번 생성하여 출력했다.&lt;/li&gt;
&lt;li data-end=&quot;1348&quot; data-start=&quot;1298&quot;&gt;개선된 코드에서는 `&lt;b&gt;cout`을 직접 활용&lt;/b&gt;하여 &lt;b&gt;불필요한 문자열 연산을 줄였다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;// 시간 복잡도 개선&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1477&quot; data-start=&quot;1372&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1425&quot; data-start=&quot;1372&quot;&gt;기존 코드: &lt;b&gt;O(N! * M)&lt;/b&gt; &amp;rarr; &lt;b&gt;모든 순열을 탐색&lt;/b&gt;한 후 &lt;b&gt;필요한 경우&lt;/b&gt;만 출력&lt;/li&gt;
&lt;li data-end=&quot;1477&quot; data-start=&quot;1429&quot;&gt;개선 코드: &lt;b&gt;O(N! / (N-M)!)&lt;/b&gt; &amp;rarr; &lt;b&gt;필요한 조합&lt;/b&gt;만 직접 탐색&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;추가로 사용한 개념&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-end=&quot;1539&quot; data-start=&quot;1509&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;// 백트래킹 (Backtracking)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-end=&quot;1549&quot; data-start=&quot;1540&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;역할&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1674&quot; data-start=&quot;1550&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1614&quot; data-start=&quot;1550&quot;&gt;가능한 모든 경우의 수를 탐색하면서 &lt;b&gt;불필요한 탐색을 가지치기(Pruning)&lt;/b&gt;하여 &lt;b&gt;최적화&lt;/b&gt;하는 기법이다.&lt;/li&gt;
&lt;li data-end=&quot;1674&quot; data-start=&quot;1615&quot;&gt;방문 여부(`used` 배열)를 이용하여 &lt;b&gt;이미 선택된 원소를 다시 선택하지 않도록 제한&lt;/b&gt;한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1686&quot; data-start=&quot;1676&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사용 예시&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1741504468149&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void backtrack(int depth) {
    if (depth == M) {  // M개 선택 완료 &amp;rarr; 출력
        for (int i = 0; i &amp;lt; M; i++)
            cout &amp;lt;&amp;lt; result[i] &amp;lt;&amp;lt; (i != M - 1 ? &quot; &quot; : &quot;\n&quot;);
        return;
    }

    for (int i = 0; i &amp;lt; N; i++) {
        if (!used[i]) {  
            used[i] = true;          // 숫자 사용 처리
            result.push_back(v[i]);  // 현재 선택된 수열에 추가

            backtrack(depth + 1);    // 다음 숫자 선택

            used[i] = false;         // 백트래킹 (되돌리기)
            result.pop_back();
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;2356&quot; data-start=&quot;2320&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;// vector&amp;lt;bool&amp;gt;을 이용한 방문 체크&lt;/b&gt;&lt;/h4&gt;
&lt;p data-end=&quot;2366&quot; data-start=&quot;2357&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;역할&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2409&quot; data-start=&quot;2367&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2409&quot; data-start=&quot;2367&quot;&gt;이미 선택한 원소인지 여부를 저장하여 &lt;b&gt;중복된 선택을 방지&lt;/b&gt;한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2421&quot; data-start=&quot;2411&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사용 예시&lt;/b&gt;:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741504528082&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;vector&amp;lt;bool&amp;gt; used(N, false); // 모든 원소를 처음에는 미사용 상태로 설정

if (!used[i]) {  // 사용되지 않은 원소만 선택
    used[i] = true;   // 사용 처리
    result.push_back(v[i]);

    backtrack(depth + 1);

    used[i] = false;  // 백트래킹: 원래대로 복구
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2706&quot; data-start=&quot;2652&quot; data-ke-size=&quot;size16&quot;&gt;기존 코드의 `prev`와 `cur`을 이용한 중복 비교보다 &lt;b&gt;더 효율적인 방식&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-end=&quot;2706&quot; data-start=&quot;2652&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1171&quot; data-start=&quot;1072&quot;&gt;기존 코드에서는 `cur`과 `prev`를 비교(&lt;b&gt;O(M)&lt;/b&gt;)해야 했지만, 백트래킹은 `used[]` 배열을 사용하여 &lt;b&gt;선택한 원소인지 O(1) 연산&lt;/b&gt;으로 확인이 가능하다.&lt;/li&gt;
&lt;li data-end=&quot;1223&quot; data-start=&quot;1172&quot;&gt;즉, &lt;b&gt;문자열 비교를 하지 않고 방문 여부를 빠르게 확인&lt;/b&gt;할 수 있어 &lt;b&gt;성능이 향상&lt;/b&gt;된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2706&quot; data-start=&quot;2652&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;2744&quot; data-start=&quot;2713&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;// iota()를 이용한 벡터 초기화&lt;/b&gt;&lt;/h4&gt;
&lt;p data-end=&quot;2754&quot; data-start=&quot;2745&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;역할&lt;/b&gt;:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2853&quot; data-start=&quot;2755&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2804&quot; data-start=&quot;2755&quot;&gt;`iota()`를 사용하면 &lt;b&gt;1부터 N까지의 숫자를 한 줄로 &lt;/b&gt;채울 수 있다.&lt;/li&gt;
&lt;li data-end=&quot;2853&quot; data-start=&quot;2805&quot;&gt;기존 for 루프를 사용하는 것보다 &lt;b&gt;더 간결한 코드 작성이 가능&lt;/b&gt;하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2865&quot; data-start=&quot;2855&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사용 예시&lt;/b&gt;:&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;pre id=&quot;code_1741504610939&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;v.resize(N);
iota(v.begin(), v.end(), 1);  // v = {1, 2, 3, ..., N}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`for` 루프 없이 `iota()` 한 줄로 벡터를 초기화할 수 있어 코드가 더 깔끔해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;3035&quot; data-start=&quot;3006&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;// `cout`을 이용한 출력 최적화&lt;/b&gt;&lt;/h4&gt;
&lt;p data-end=&quot;3045&quot; data-start=&quot;3036&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;역할&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3158&quot; data-start=&quot;3046&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3101&quot; data-start=&quot;3046&quot;&gt;`cout`을 활용하여 &lt;b&gt;문자열 연산을 줄이고, 더 빠르게 출력&lt;/b&gt;할 수 있도록 개선한다.&lt;/li&gt;
&lt;li data-end=&quot;3158&quot; data-start=&quot;3102&quot;&gt;&lt;b&gt;삼항 연산자&lt;/b&gt;를 활용하여 &lt;b&gt;출력 형식을 조정&lt;/b&gt;하고 &lt;b&gt;마지막 숫자 뒤에는 공백을 붙이지 않는다&lt;/b&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;3198&quot; data-start=&quot;3160&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;기존 방식 (`prev`와 `cur`을 이용한 문자열 비교)&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741504765700&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cur += to_string(v[i]) + ((i != M - 1) ? &quot; &quot; : &quot;&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3285&quot; data-start=&quot;3262&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;개선된 방식 (`cout` 활용)&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741504778283&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cout &amp;lt;&amp;lt; result[i] &amp;lt;&amp;lt; (i != M - 1 ? &quot; &quot; : &quot;\n&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3387&quot; data-start=&quot;3345&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;출력 최적화&lt;/b&gt;로 &lt;b&gt;불필요한 문자열 연산을 줄이&lt;/b&gt;고 &lt;b&gt;실행 속도를 높인&lt;/b&gt;다.&lt;/p&gt;
&lt;p data-end=&quot;3387&quot; data-start=&quot;3345&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3387&quot; data-start=&quot;3345&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-end=&quot;3387&quot; data-start=&quot;3345&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3387&quot; data-start=&quot;3345&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;936&quot; data-origin-height=&quot;140&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcSBzg/btsMES2i8V2/cCZRxdvEsulRbpaVGGZJL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcSBzg/btsMES2i8V2/cCZRxdvEsulRbpaVGGZJL0/img.png&quot; data-alt=&quot;(위) AI 피드백 코드 / (아래) 내가 작성한 코드&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcSBzg/btsMES2i8V2/cCZRxdvEsulRbpaVGGZJL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcSBzg%2FbtsMES2i8V2%2FcCZRxdvEsulRbpaVGGZJL0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;936&quot; height=&quot;140&quot; data-origin-width=&quot;936&quot; data-origin-height=&quot;140&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(위) AI 피드백 코드 / (아래) 내가 작성한 코드&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;271&quot; data-start=&quot;141&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;271&quot; data-start=&quot;141&quot; data-ke-size=&quot;size16&quot;&gt;이론적으로 보면 백트래킹을 활용한 코드(AI 피드백 코드)가 &lt;b&gt;O(N! / (N-M)!)이므로 더 효율적&lt;/b&gt;이어야 한다.&lt;br /&gt;반면, `next_permutation()`을 활용한 코드는 &lt;b&gt;O(N! * M)&lt;/b&gt;이므로 더 느릴 것이라고 예상할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;271&quot; data-start=&quot;141&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;355&quot; data-start=&quot;273&quot; data-ke-size=&quot;size16&quot;&gt;하지만, 실제 실행 결과는 `&lt;b&gt;next_permutation()`을 활용한 코드가 더 빠르게 실행되었다.&lt;/b&gt;&lt;br /&gt;이는 다음과 같은 이유일 것이라 예상된다.&lt;/p&gt;
&lt;p data-end=&quot;355&quot; data-start=&quot;273&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;429&quot; data-start=&quot;388&quot; data-ke-size=&quot;size23&quot;&gt;`&lt;b&gt;next_permutation()`의 내부 최적화&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;498&quot; data-start=&quot;430&quot; data-ke-size=&quot;size16&quot;&gt;C++ 표준 라이브러리에서 제공하는 `next_permutation()`은 &lt;b&gt;매우 효율적으로 구현된 알고리즘&lt;/b&gt;이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;685&quot; data-start=&quot;499&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;567&quot; data-start=&quot;499&quot;&gt;`next_permutation()`은 &lt;b&gt;사전순으로 정렬된 배열&lt;/b&gt;에서 &lt;b&gt;다음 순열을 구하는 최적화된 연산&lt;/b&gt;을 수행한다.&lt;/li&gt;
&lt;li data-end=&quot;606&quot; data-start=&quot;568&quot;&gt;&lt;b&gt;일반적인 백트래킹 방식보다 빠르게 순열을 생성&lt;/b&gt;할 수 있다.&lt;/li&gt;
&lt;li data-end=&quot;685&quot; data-start=&quot;607&quot;&gt;내부적으로 `&lt;b&gt;swap` 연산&lt;/b&gt;과 &lt;b&gt;빠른 비교 연산&lt;/b&gt;을 사용하여 최적화가 되어 있기 때문에, 백트래킹보다 실행 속도가 빠를 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;767&quot; data-start=&quot;687&quot; data-ke-size=&quot;size16&quot;&gt;즉, &lt;b&gt;C++ STL의 최적화된 next_permutation()이 백트래킹의 순열 생성보다 실제 실행에서 더 빠르게 동작할 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;h3 data-end=&quot;801&quot; data-start=&quot;774&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;801&quot; data-start=&quot;774&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;재귀 함수 호출의 오버헤드&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;910&quot; data-start=&quot;802&quot; data-ke-size=&quot;size16&quot;&gt;백트래킹 방식은 &lt;b&gt;재귀 함수 호출을 반복적으로 수행&lt;/b&gt;해야 한다.&lt;br /&gt;재귀 호출 과정에서 &lt;b&gt;함수 호출 스택이 쌓이고 해제되는 과정이 반복&lt;/b&gt;되기 때문에 실행 속도에 영향을 미칠 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1045&quot; data-start=&quot;911&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;990&quot; data-start=&quot;911&quot;&gt;`backtrack(depth + 1)`을 호출할 때마다 &lt;b&gt;스택 프레임이 새로 생성&lt;/b&gt;되며, &lt;b&gt;함수가 종료될 때마다 스택 프레임이 해제&lt;/b&gt;된다.&lt;/li&gt;
&lt;li data-end=&quot;1045&quot; data-start=&quot;991&quot;&gt;즉, &lt;b&gt;재귀 호출이 많아질수록 함수 호출 오버헤드가 커지고 실행 속도가 느려질 가능성&lt;/b&gt;이 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1123&quot; data-start=&quot;1047&quot; data-ke-size=&quot;size16&quot;&gt;반면, `next_permutation()`은 &lt;b&gt;재귀 호출 없이 순열을 반복적으로 생성&lt;/b&gt;하는 방식이므로, &lt;b&gt;함수 호출 오버헤드가 적다.&lt;/b&gt;&lt;/p&gt;
&lt;h3 data-end=&quot;1158&quot; data-start=&quot;1130&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;1158&quot; data-start=&quot;1130&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문자열 연산 vs 벡터 연산&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;1216&quot; data-start=&quot;1159&quot; data-ke-size=&quot;size16&quot;&gt;AI 피드백 코드에서는 cout을 사용할 때 벡터에서 값을 가져와 &lt;b&gt;직접 출력&lt;/b&gt;하는 방식이다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741507109342&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for (int i = 0; i &amp;lt; M; i++)
    cout &amp;lt;&amp;lt; result[i] &amp;lt;&amp;lt; (i != M - 1 ? &quot; &quot; : &quot;\n&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1358&quot; data-start=&quot;1308&quot; data-ke-size=&quot;size16&quot;&gt;이 과정은 벡터에서 값을 가져와 바로 출력하기 때문에 &lt;b&gt;메모리 복사 오버헤드가 적다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1428&quot; data-start=&quot;1360&quot; data-ke-size=&quot;size16&quot;&gt;반면, `next_permutation()`을 사용하는 기존 코드에서는 &lt;b&gt;문자열을 생성하고 비교하는 과정이 추가&lt;/b&gt;된다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741507128496&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cur += to_string(v[i]) + ((i != M - 1) ? &quot; &quot; : &quot;&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1596&quot; data-start=&quot;1492&quot; data-ke-size=&quot;size16&quot;&gt;하지만, STL에서는 &lt;b&gt;문자열 연산도 내부적으로 최적화되어 있으며&lt;/b&gt;,&lt;br /&gt;단순히 cur != prev 비교하는 것이 백트래킹에서 &lt;b&gt;벡터 연산을 수행하는 것보다 빠를 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1653&quot; data-start=&quot;1598&quot; data-ke-size=&quot;size16&quot;&gt;➡ STL의 문자열 비교 연산(O(M))이 재귀 호출을 통한 벡터 조작보다 더 빠를 수도 있음.&lt;/p&gt;
&lt;h3 data-end=&quot;1683&quot; data-start=&quot;1660&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;1683&quot; data-start=&quot;1660&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;입출력 최적화 영향&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1896&quot; data-start=&quot;1684&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1756&quot; data-start=&quot;1684&quot;&gt;`cout`은 기본적으로 버퍼링을 사용하지만,&lt;br /&gt;&lt;b&gt;재귀 호출이 많아지면 입출력 연산이 더 느려질 가능성&lt;/b&gt;이 있다&lt;/li&gt;
&lt;li data-end=&quot;1830&quot; data-start=&quot;1757&quot;&gt;`next_permutation()`을 활용한 코드는 &lt;b&gt;반복문 기반&lt;/b&gt;이므로 &lt;b&gt;입출력 버퍼를 더 효율적으로 활용&lt;/b&gt;할 수 있다.&lt;/li&gt;
&lt;li data-end=&quot;1896&quot; data-start=&quot;1831&quot;&gt;백트래킹 코드에서도 &lt;b&gt;출력을 모아두었다가 한 번에 출력하는 방식&lt;/b&gt;을 사용하면 속도가 더 빨라질 가능성이 있다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1896&quot; data-start=&quot;1831&quot;&gt;이 가능성을 염두하여 AI 피드백 코드의 `main()` 함수에 `&lt;span style=&quot;letter-spacing: 0px;&quot;&gt; ios_base::sync_with_stdio(false);`를 추가하고 실행해보았는데 똑같이 24초가 걸렸다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>C++/BAEKJOON</category>
      <category>BackTracking</category>
      <category>C++</category>
      <category>c++형변환</category>
      <category>next_permutation</category>
      <category>permutation</category>
      <category>백트래킹</category>
      <category>순열</category>
      <category>코딩테스트</category>
      <author>D0YUN</author>
      <guid isPermaLink="true">https://alizwldyl.tistory.com/40</guid>
      <comments>https://alizwldyl.tistory.com/40#entry40comment</comments>
      <pubDate>Mon, 10 Mar 2025 08:03:11 +0900</pubDate>
    </item>
    <item>
      <title>[C++] iota()를 이용하여 연속된 값을 빠르게 채우기 (ft. transform(), generate())</title>
      <link>https://alizwldyl.tistory.com/39</link>
      <description>&lt;h2 data-end=&quot;69&quot; data-start=&quot;44&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;iota() 함수란?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-end=&quot;224&quot; data-start=&quot;70&quot; data-ke-size=&quot;size16&quot;&gt;C++에서 `iota()` 함수는 특정 범위에 연속된 값을 채우는 함수로, &lt;b&gt;시작 값을 설정&lt;/b&gt;하면 &lt;b&gt;이후 요소들을 1씩 증가&lt;/b&gt;하며 채워 넣습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-end=&quot;248&quot; data-start=&quot;226&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;iota() 함수 정의&lt;/b&gt;&lt;/h2&gt;
&lt;div&gt;
&lt;div&gt;`iota()` 함수의 정의는 다음과 같습니다.&lt;/div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741505560931&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void iota(ForwardIterator first, ForwardIterator last, T value);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;427&quot; data-start=&quot;325&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;364&quot; data-start=&quot;325&quot;&gt;&lt;b&gt;first&lt;/b&gt;: 값을 채울 범위의 시작 (begin())&lt;/li&gt;
&lt;li data-end=&quot;400&quot; data-start=&quot;365&quot;&gt;&lt;b&gt;last&lt;/b&gt;: 값을 채울 범위의 끝 (end())&lt;/li&gt;
&lt;li data-end=&quot;427&quot; data-start=&quot;401&quot;&gt;&lt;b&gt;value&lt;/b&gt;: 채우기 시작할 값&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-end=&quot;463&quot; data-start=&quot;434&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;기본적인 iota() 사용법&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-end=&quot;494&quot; data-start=&quot;464&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;벡터를 1부터 N까지 자동으로 채우기&lt;/b&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741505612575&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;numeric&amp;gt;  // iota()를 사용하기 위한 헤더

using namespace std;

int main() {
    vector&amp;lt;int&amp;gt; v(5); // 크기가 5인 벡터 생성

    // 1부터 시작하는 연속된 값을 벡터에 채운다.
    iota(v.begin(), v.end(), 1);

    // 결과 출력
    for (int num : v) cout &amp;lt;&amp;lt; num &amp;lt;&amp;lt; &quot; &quot;;

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;808&quot; data-start=&quot;799&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;808&quot; data-start=&quot;799&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실행 결과&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741505628083&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1 2 3 4 5&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;837&quot; data-start=&quot;828&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;837&quot; data-start=&quot;828&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;동작 과정&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;937&quot; data-start=&quot;838&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;865&quot; data-start=&quot;838&quot;&gt;v[0] = 1 (초기 값 1 설정)&lt;/li&gt;
&lt;li data-end=&quot;895&quot; data-start=&quot;866&quot;&gt;v[1] = 2 (이전 값에 +1 증가)&lt;/li&gt;
&lt;li data-end=&quot;909&quot; data-start=&quot;896&quot;&gt;v[2] = 3&lt;/li&gt;
&lt;li data-end=&quot;923&quot; data-start=&quot;910&quot;&gt;v[3] = 4&lt;/li&gt;
&lt;li data-end=&quot;937&quot; data-start=&quot;924&quot;&gt;v[4] = 5&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;972&quot; data-start=&quot;939&quot; data-ke-size=&quot;size16&quot;&gt;실행 결과를 통해 확인할 수 있듯이 각 원소는 앞의 원소보다 1씩 증가하는 값으로 채워집니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-end=&quot;1011&quot; data-start=&quot;979&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;iota()를 활용한 다양한 예제&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-end=&quot;1041&quot; data-start=&quot;1012&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;ex1) 0부터 시작하는 값 채우기&lt;/b&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741505709095&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;vector&amp;lt;int&amp;gt; v(10);
iota(v.begin(), v.end(), 0);  // 0부터 9까지 자동 채움
// 결과: 0 1 2 3 4 5 6 7 8 9&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;1178&quot; data-start=&quot;1147&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;ex2) 100부터 시작하는 값 채우기&lt;/b&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741505720579&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;vector&amp;lt;int&amp;gt; v(5);
iota(v.begin(), v.end(), 100);  // 100부터 104까지 자동 채움
// 결과: 100 101 102 103 104&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;1317&quot; data-start=&quot;1289&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;ex3) 배열을 초기화할 때 사용하기&lt;/b&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741505731903&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int arr[6];
iota(arr, arr + 6, 10);  // 10부터 15까지 자동 채움
// 결과: 10 11 12 13 14 15&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;1466&quot; data-start=&quot;1416&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;`iota()`를 변형하여 특정 간격(2, 5 등)으로 값 증가시키기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-end=&quot;1579&quot; data-start=&quot;1467&quot; data-ke-size=&quot;size16&quot;&gt;`iota()`는 기본적으로 &lt;b&gt;1씩 증가하는 값&lt;/b&gt;을 채우지만,&lt;br /&gt;`transform()` 또는 `generate()`를 활용하면 &lt;b&gt;1 이외의 숫자만큼 증가하는 값&lt;/b&gt;을 저장할 수도 있습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;1622&quot; data-start=&quot;1581&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;방법 1: `iota()` + `transform()` 활용&lt;/b&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741505851123&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;numeric&amp;gt;  // iota()
#include &amp;lt;algorithm&amp;gt; // transform()

using namespace std;

int main() {
    vector&amp;lt;int&amp;gt; v(10); // 크기가 10인 벡터 생성

    // 0부터 9까지 연속된 값 채우기
    iota(v.begin(), v.end(), 0);

    // 각 요소를 2씩 증가하도록 변환 (0, 2, 4, 6, 8, ...)
    transform(v.begin(), v.end(), v.begin(), [](int x) { return x * 2; });

    // 결과 출력
    for (int num : v) cout &amp;lt;&amp;lt; num &amp;lt;&amp;lt; &quot; &quot;;

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2078&quot; data-start=&quot;2069&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot; data-start=&quot;771&quot; data-end=&quot;780&quot;&gt;&lt;b&gt;`iota()`와 `transform()`을 활용한 방식의 원리는 다음과 같습니다.&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot; data-start=&quot;781&quot; data-end=&quot;995&quot;&gt;
&lt;li data-start=&quot;781&quot; data-end=&quot;830&quot;&gt;`iota(v.begin(), v.end(), 0);`&amp;nbsp; v를 0부터 9까지 채웁니다.&lt;/li&gt;
&lt;li data-start=&quot;831&quot; data-end=&quot;951&quot;&gt;`transform()`을 사용하여&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;각 요소를 2배로 변경&lt;/b&gt;합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot; data-start=&quot;879&quot; data-end=&quot;951&quot;&gt;
&lt;li data-start=&quot;879&quot; data-end=&quot;951&quot;&gt;`[](int x) { return x * 2; }`는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;람다 함수&lt;/b&gt;로, 기존 값 x를 2배로 변환하는 역할을 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-start=&quot;952&quot; data-end=&quot;995&quot;&gt;결과적으로 0, 2, 4, 6, 8, ... 같은 수열이 생성됩니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2078&quot; data-start=&quot;2069&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실행 결과&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741505879889&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;0 2 4 6 8 10 12 14 16 18&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;2170&quot; data-start=&quot;2118&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;방법 2: `generate()` 활용 (`iota()` 없이 특정 간격 설정)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`generate()`를 사용하면 `iota()` 없이 특정 간격으로 값을 채울 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741505920335&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;algorithm&amp;gt; // generate()

using namespace std;

int main() {
    vector&amp;lt;int&amp;gt; v(10);
    int start = 2;
    int step = 5;

    // 람다 함수로 각 요소를 채운다.
    generate(v.begin(), v.end(), [&amp;amp;]() { 
        int val = start; 
        start += step; 
        return val;
    });

    // 결과 출력
    for (int num : v) cout &amp;lt;&amp;lt; num &amp;lt;&amp;lt; &quot; &quot;;

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;`generate()`를 사용하는 방식의 원리는 다음과 같습니다.&lt;/b&gt;&lt;/h4&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1511&quot; data-start=&quot;1502&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1599&quot; data-start=&quot;1512&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1548&quot; data-start=&quot;1512&quot;&gt;`start` 변수에 초기값을 설정하고, `step`만큼 증가시키면서&lt;/li&gt;
&lt;li data-end=&quot;1548&quot; data-start=&quot;1512&quot;&gt;각 요소를 직접 채웁니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;2580&quot; data-start=&quot;2571&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2580&quot; data-start=&quot;2571&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실행 결과&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741505935165&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;2 7 12 17 22 27 32 37 42 47&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2670&quot; data-start=&quot;2618&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2670&quot; data-start=&quot;2618&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;1709&quot; data-start=&quot;1669&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;방법 3: for 루프 직접 사용 (기본적인 방법)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 기본적인 방법으로, `iota()`보다 코드가 길어지는 단점이 있습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741506286059&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;

using namespace std;

int main() {
    vector&amp;lt;int&amp;gt; v(10);

    // 2부터 시작해서 5씩 증가하는 수열 생성
    for (int i = 0; i &amp;lt; v.size(); i++) {
        v[i] = 2 + i * 5;
    }

    // 결과 출력
    for (int num : v) cout &amp;lt;&amp;lt; num &amp;lt;&amp;lt; &quot; &quot;;

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2008&quot; data-start=&quot;1996&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실행 결과&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741506298635&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;2 7 12 17 22 27 32 37 42 47&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2099&quot; data-start=&quot;2046&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2099&quot; data-start=&quot;2046&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2099&quot; data-start=&quot;2046&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>C++</category>
      <category>C++</category>
      <category>for문</category>
      <category>generate</category>
      <category>iota</category>
      <category>Transform</category>
      <author>D0YUN</author>
      <guid isPermaLink="true">https://alizwldyl.tistory.com/39</guid>
      <comments>https://alizwldyl.tistory.com/39#entry39comment</comments>
      <pubDate>Sun, 9 Mar 2025 16:46:49 +0900</pubDate>
    </item>
    <item>
      <title>[백준/C++] 7785(회사에 있는 사람) (문자열 비교 / Hash / unordered_map, unordered_set)</title>
      <link>https://alizwldyl.tistory.com/38</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1463&quot; data-origin-height=&quot;1240&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LdwdV/btsME5tpCVB/7JHDIKHG42QPOMEFdebggk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LdwdV/btsME5tpCVB/7JHDIKHG42QPOMEFdebggk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LdwdV/btsME5tpCVB/7JHDIKHG42QPOMEFdebggk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLdwdV%2FbtsME5tpCVB%2F7JHDIKHG42QPOMEFdebggk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1463&quot; height=&quot;1240&quot; data-origin-width=&quot;1463&quot; data-origin-height=&quot;1240&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/7785&quot;&gt;https://www.acmicpc.net/problem/7785&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;내가 해냄&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1741481006164&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;bits/stdc++.h&amp;gt;
// #include &amp;lt;unordered_map&amp;gt;    // 원래는 &amp;lt;bits/stdc++.h&amp;gt; 만 include해도 동작하는데 VS에서 동작하지 않아서 추가로 include
using namespace std;

long long n;    // 출입 기록 수
unordered_map &amp;lt;string, string&amp;gt; syslog; // 출입 기록 로그 (이름 - 출입 상태 저장)
vector&amp;lt;string&amp;gt; cur;   // 현재 회사에 있는 사람들 (정렬을 위해 사용)

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    // 출입 기록 수를 입력받는다
    cin &amp;gt;&amp;gt; n;

    // 출입 기록을 입력받는다
    for (int i = 0; i &amp;lt; n; i++)
    {
        string tmp1, tmp2;
        cin &amp;gt;&amp;gt; tmp1 &amp;gt;&amp;gt; tmp2;

        syslog[tmp1] = tmp2;  // 마지막 출입 상태만 저장됨 (enter / leave)
    }

    // 현재 회사에 있는 사람들을 기록한다
    // unordered_map을 순회하여 &quot;enter&quot; 상태인 사람만 벡터에 추가
    // *** string은 == 연산자 오버로딩이 되어 있어서 두 문자열이 같은지 비교 가능 ***
    for (auto i : syslog)
        if (i.second == &quot;enter&quot;)
            cur.push_back(i.first);

    // 현재 회사에 있는 사람들을 역순으로 정렬한다
    // *** greater&amp;lt;string&amp;gt;()을 비교자로 전달하여 사전 역순(내림차순)으로 정렬한다 ***
    sort(cur.begin(), cur.end(), greater&amp;lt;string&amp;gt;());

    // 회사에 있는 사람들을 출력한다
    for (string i : cur)
        cout &amp;lt;&amp;lt; i &amp;lt;&amp;lt; '\n';

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;사용한 핵심 개념&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-end=&quot;115&quot; data-start=&quot;66&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// `unordered_map&amp;lt;string, string&amp;gt;` (해시 맵)&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;208&quot; data-start=&quot;115&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;역할 &lt;/b&gt;: 사람의 이름(string)을 키(key)로 하고, 출입 상태(&quot;enter&quot; 또는 &quot;leave&quot;)를 값(value)으로 저장하는 자료구조다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;330&quot; data-start=&quot;209&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;330&quot; data-start=&quot;221&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;266&quot; data-start=&quot;221&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;평균 O(1)의 시간 복잡도로 &lt;b&gt;빠른 검색, 삽입, 삭제&lt;/b&gt;가 가능하다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;330&quot; data-start=&quot;269&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;마지막으로 기록된 출입 상태만 저장된다. (즉, &lt;b&gt;동일한 이름의 키가 등장&lt;/b&gt;하면 새로운 값으로 &lt;b&gt;덮어씌워&lt;/b&gt;진다.)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;사용 예시&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1741481181489&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;unordered_map&amp;lt;string, string&amp;gt; syslog;
syslog[&quot;Alice&quot;] = &quot;enter&quot;;  // Alice가 회사에 들어옴
syslog[&quot;Alice&quot;] = &quot;leave&quot;;  // Alice가 퇴근 &amp;rarr; 이전 값 &quot;enter&quot;가 덮어씌워짐&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;1955&quot; data-start=&quot;1924&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// `vector&amp;lt;string&amp;gt;`의 활용&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2145&quot; data-start=&quot;1956&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2007&quot; data-start=&quot;1956&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;역할 &lt;/b&gt;: 현재 회사에 남아 있는 사람들을 저장하고, 정렬 후 출력하는 역할을 한다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;2057&quot; data-start=&quot;2008&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;사용 예시&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1741481231973&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;vector&amp;lt;string&amp;gt; cur;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;121&quot; data-start=&quot;84&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// `std::string`의 `==` 연산자 활용&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;685&quot; data-start=&quot;122&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;183&quot; data-start=&quot;122&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;역할&lt;/b&gt;: &quot;enter&quot;인지 &quot;leave&quot;인지 비교하여 현재 회사에 남아 있는 사람을 판별한다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;268&quot; data-start=&quot;184&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;사용 코드&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1741481664956&quot; class=&quot;reasonml&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;if (i.second == &quot;enter&quot;)
    cur.push_back(i.first);&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;685&quot; data-start=&quot;122&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;426&quot; data-start=&quot;269&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;작동 원리&lt;/b&gt;:&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;426&quot; data-start=&quot;284&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;357&quot; data-start=&quot;284&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;C++의 `std::string` 클래스는 `&lt;b&gt;==` 연산자가 오버로딩&lt;/b&gt;되어 있어 두 문자열이 같은지 쉽게 비교할 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;426&quot; data-start=&quot;360&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;C 스타일 문자열(char*)과 다르게 직접 비교가 가능&lt;/b&gt;하며, `strcmp()`를 사용할 필요가 없다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;593&quot; data-start=&quot;427&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;예제&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1741481696791&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;string a = &quot;hello&quot;;
string b = &quot;hello&quot;;
string c = &quot;world&quot;;

if (a == b) cout &amp;lt;&amp;lt; &quot;a와 b는 같다.\n&quot;;
if (a != c) cout &amp;lt;&amp;lt; &quot;a와 c는 다르다.\n&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;685&quot; data-start=&quot;122&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;643&quot; data-start=&quot;594&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;출력 결과&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1741481713169&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a와 b는 같다.
a와 c는 다르다.&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;685&quot; data-start=&quot;122&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;685&quot; data-start=&quot;644&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;시간 복잡도&lt;/b&gt;: O(N) (두 문자열의 길이가 N일 경우)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;736&quot; data-start=&quot;692&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;cf) `std::string::compare()` 함수&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1167&quot; data-start=&quot;737&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;796&quot; data-start=&quot;737&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;역할&lt;/b&gt;: `std::string::compare()`는 문자열 비교 결과를 &lt;b&gt;정수 값으로 반환&lt;/b&gt;한다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1014&quot; data-start=&quot;797&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;사용 예시&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1741481772537&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;string a = &quot;apple&quot;;
string b = &quot;banana&quot;;

if (a.compare(b) == 0) cout &amp;lt;&amp;lt; &quot;같다.\n&quot;;
else if (a.compare(b) &amp;lt; 0) cout &amp;lt;&amp;lt; &quot;a가 b보다 사전순으로 앞에 있다.\n&quot;;
else cout &amp;lt;&amp;lt; &quot;a가 b보다 사전순으로 뒤에 있다.\n&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1167&quot; data-start=&quot;737&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1061&quot; data-start=&quot;1015&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;출력 결과&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1741481790325&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a가 b보다 사전순으로 앞에 있다.&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1167&quot; data-start=&quot;737&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1167&quot; data-start=&quot;1062&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;비교 결과 값&lt;/b&gt;:&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1167&quot; data-start=&quot;1079&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1097&quot; data-start=&quot;1079&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;0 &amp;rarr; 두 문자열이 같다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1132&quot; data-start=&quot;1100&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;lt; 0 &amp;rarr; 첫 번째 문자열이 사전순으로 앞에 있다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1167&quot; data-start=&quot;1135&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;gt; 0 &amp;rarr; 첫 번째 문자열이 사전순으로 뒤에 있다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1230&quot; data-start=&quot;1169&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1230&quot; data-start=&quot;1169&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;u&gt;&lt;b&gt;하지만 단순히 문자열이 같은지 비교할 때는 `==` 연산자를 사용하는 것이 더 직관적이고 간결하다.&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;618&quot; data-start=&quot;566&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// `sort()` + 비교 함수 `greater&amp;lt;string&amp;gt;()` (사전 역순 정렬)&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1050&quot; data-start=&quot;619&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;676&quot; data-start=&quot;619&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;역할&lt;/b&gt;: 회사에 남아 있는 사람들의 이름을 &lt;b&gt;사전 역순(내림차순) 정렬&lt;/b&gt;하는 역할을 한다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;755&quot; data-start=&quot;677&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;구현 방식&lt;/b&gt;:&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1741481356821&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sort(cur.begin(), cur.end(), greater&amp;lt;string&amp;gt;());&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1050&quot; data-start=&quot;619&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;869&quot; data-start=&quot;756&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;작동 원리&lt;/b&gt;:&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;869&quot; data-start=&quot;771&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;807&quot; data-start=&quot;771&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;기본적으로 sort()는 &lt;b&gt;오름차순 정렬&lt;/b&gt;을 수행한다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;869&quot; data-start=&quot;810&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`greater&amp;lt;string&amp;gt;()`을 비교 함수로 전달하면 &lt;b&gt;내림차순 정렬&lt;/b&gt;을 수행하여 사전 역순으로 정렬된다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;사용 예시&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1741481439223&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;vector&amp;lt;string&amp;gt; names = {&quot;Alice&quot;, &quot;Charlie&quot;, &quot;Bob&quot;};
sort(names.begin(), names.end(), greater&amp;lt;string&amp;gt;());
// 정렬 후: {&quot;Charlie&quot;, &quot;Bob&quot;, &quot;Alice&quot;} (사전 역순)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;AI 피드백&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1741482694065&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;unordered_set&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;algorithm&amp;gt;
using namespace std;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    int n;  // 출입 기록 수
    cin &amp;gt;&amp;gt; n;

    unordered_set&amp;lt;string&amp;gt; syslog; // 현재 회사에 있는 사람들 저장

    for (int i = 0; i &amp;lt; n; i++) {
        string name, action;
        cin &amp;gt;&amp;gt; name &amp;gt;&amp;gt; action;

        if(action == &quot;enter&quot;) syslog.insert(name);  // 입장 기록
        else syslog.erase(name);    // 퇴장 기록
    }
    
    // 출입 기록을 모두 처리한 후, 회사에 남아 있는 사람들을 벡터에 저장
    vector&amp;lt;string&amp;gt; cur(syslog.begin(), syslog.end());

    // 사전 역순(내림차순) 정렬
    sort(cur.begin(), cur.end(), greater&amp;lt;string&amp;gt;());

    // 결과 출력
    for (const string&amp;amp; name : cur)
        cout &amp;lt;&amp;lt; name &amp;lt;&amp;lt; '\n';

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt; 초기 코드 핵심 로직 분석&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-end=&quot;394&quot; data-start=&quot;240&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;초기 코드에서는 `unordered_map&amp;lt;string, string&amp;gt;`을 사용하여 &lt;b&gt;이름을 키(key), 출입 상태를 값(value)&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;&amp;nbsp;으로 저장&lt;/span&gt;하는 방식으로 구현하였다. 마지막으로 기록된 출입 상태만 저장되므로, 동일한 이름이 여러 번 등장해도 최종 상태만 유지가 된다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;출입 기록을 받은 후 &quot;enter&quot; 상태인 사람들만 벡터에 추가한 후, &lt;b&gt;사전 역순(내림차순)으로 정렬하여 출력&lt;/b&gt;하였다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1741483225862&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;unordered_map&amp;lt;string, string&amp;gt; syslog; // (이름, 출입 상태)

for (int i = 0; i &amp;lt; n; i++) {
    string name, action;
    cin &amp;gt;&amp;gt; name &amp;gt;&amp;gt; action;
    syslog[name] = action;  // 마지막 출입 상태만 저장됨
}

// 현재 회사에 있는 사람들을 벡터에 추가
for (auto i : syslog)
    if (i.second == &quot;enter&quot;)
        cur.push_back(i.first);

// 내림차순 정렬 후 출력
sort(cur.begin(), cur.end(), greater&amp;lt;string&amp;gt;());
for (string i : cur)
    cout &amp;lt;&amp;lt; i &amp;lt;&amp;lt; '\n';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;394&quot; data-start=&quot;240&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;주요 개선점 : &lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;&amp;nbsp;`&lt;/span&gt;&lt;b&gt;unordered_set&amp;lt;string&amp;gt;`의 사용&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;345&quot; data-start=&quot;135&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;258&quot; data-start=&quot;135&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;초기 코드는 unordered_map&amp;lt;string, string&amp;gt;을 사용하여 {&quot;이름&quot;, &quot;enter&quot;} 혹은 {&quot;이름&quot;, &quot;leave&quot;} 형태로 저장하고 있지만, 사실 &lt;b&gt;&quot;leave&quot;를 저장할 필요는 없다.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;345&quot; data-start=&quot;262&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;대신 `&lt;b&gt;unordered_set&amp;lt;string&amp;gt;`을 사용&lt;/b&gt;하면 &lt;b&gt;더 간결하고 직관적&lt;/b&gt;이며, &lt;b&gt;O(1)&lt;/b&gt;의 탐색 속도로 더 빠르게 동작할 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;345&quot; data-start=&quot;262&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;해당 자료형을 사용함으로써 개선된 내용은 다음과 같다&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 67px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;기존 코드&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;개선된 코드&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&quot;leave&quot; 상태를 따로 저장하여 비교&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&quot;leave&quot; 상태를 저장하지 않고, `erase()`로 삭제&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 16px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 16px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&quot;enter&quot; 상태를 벡터에 따로 저장&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 16px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`unordered_set`에서 `vector`로 변환 후 정렬&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;벡터를 따로 관리하며 &quot;enter&quot; 상태만 저장&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`unordered_set` 자체가 &quot;enter&quot; 상태인 사람만 저장&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1741483246914&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;unordered_set&amp;lt;string&amp;gt; syslog; // 현재 회사에 있는 사람들 저장

for (int i = 0; i &amp;lt; n; i++) {
    string name, action;
    cin &amp;gt;&amp;gt; name &amp;gt;&amp;gt; action;

    if (action == &quot;enter&quot;) syslog.insert(name);  // 입장 기록
    else syslog.erase(name);  // 퇴장 기록
}

// 출입 기록을 모두 처리한 후, 벡터로 변환
vector&amp;lt;string&amp;gt; cur(syslog.begin(), syslog.end());

// 내림차순 정렬 후 출력
sort(cur.begin(), cur.end(), greater&amp;lt;string&amp;gt;());
for (const string&amp;amp; name : cur)
    cout &amp;lt;&amp;lt; name &amp;lt;&amp;lt; '\n';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;1951&quot; data-start=&quot;1930&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;추가로 사용한 개념&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-end=&quot;1998&quot; data-start=&quot;1952&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// unordered_map &amp;rarr; unordered_set로 변경&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2259&quot; data-start=&quot;1999&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2106&quot; data-start=&quot;1999&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;기존 코드 문제점&lt;/b&gt;:&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2106&quot; data-start=&quot;2020&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2106&quot; data-start=&quot;2020&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`unordered_map`을 사용하여 &quot;enter&quot;와 &quot;leave&quot; 값을 저장했으나, 사실 &quot;leave&quot; 상태는 따로 저장할 필요가 없다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2106&quot; data-start=&quot;2020&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;회사를 떠난 사람은 최종 결과에서 출력하지 않기 때문이다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;2259&quot; data-start=&quot;2107&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;개선 코드 장점&lt;/b&gt;:&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2259&quot; data-start=&quot;2127&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2203&quot; data-start=&quot;2127&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&quot;enter&quot;일 때는 insert(), &quot;leave&quot;일 때는 `erase()`를 사용하여 &lt;b&gt;바로 추가 및 삭제&lt;/b&gt;가 가능하다&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;2259&quot; data-start=&quot;2206&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;불필요한 &quot;leave&quot; 값 비교 연산을 제거하여 &lt;b&gt;연산 속도&lt;/b&gt;가 &lt;b&gt;평균 O(1)&lt;/b&gt;으로 개선된다&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741483370400&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;unordered_set&amp;lt;string&amp;gt; syslog;

if (action == &quot;enter&quot;) syslog.insert(name);
else syslog.erase(name);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;2453&quot; data-start=&quot;2378&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// 벡터 변환 후 정렬 (vector&amp;lt;string&amp;gt; cur(syslog.begin(), syslog.end());)&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2660&quot; data-start=&quot;2454&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2514&quot; data-start=&quot;2454&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;기존 코드 문제점&lt;/b&gt;:&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2514&quot; data-start=&quot;2475&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2514&quot; data-start=&quot;2475&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&quot;enter&quot; 상태인 사람을 벡터에 따로 추가하는 과정이 필요했다&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;2660&quot; data-start=&quot;2515&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;개선 코드 장점&lt;/b&gt;:&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2660&quot; data-start=&quot;2535&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2580&quot; data-start=&quot;2535&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`unordered_set`을 &lt;b&gt;벡터의 생성자로 변환&lt;/b&gt;하여 &lt;b&gt;한 번에 저장&lt;/b&gt;할 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;2660&quot; data-start=&quot;2583&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`vector&amp;lt;string&amp;gt; cur(syslog.begin(), syslog.end());`를 사용하여 &lt;b&gt;O(N)&lt;/b&gt; 시간 내 변환할 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이분 탐색이나 투 포인터 방식을 이용하여 구현할 수도 있다고 한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>C++/BAEKJOON</category>
      <category>C++</category>
      <category>Hash</category>
      <category>unordered_map</category>
      <category>unordered_set</category>
      <category>개발</category>
      <category>문자열비교</category>
      <category>백준</category>
      <category>코딩테스트</category>
      <category>프로그래밍</category>
      <category>해시</category>
      <author>D0YUN</author>
      <guid isPermaLink="true">https://alizwldyl.tistory.com/38</guid>
      <comments>https://alizwldyl.tistory.com/38#entry38comment</comments>
      <pubDate>Sun, 9 Mar 2025 10:26:33 +0900</pubDate>
    </item>
    <item>
      <title>[백준/C++] 10808(알파벳 개수) (아스키 코드 / 범위 기반 for문 / constexpr / 삼항연산자)</title>
      <link>https://alizwldyl.tistory.com/37</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1076&quot; data-origin-height=&quot;907&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FljfK/btsMFvrrFPk/wdsHFDQXRfGZBw0U0dc2x1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FljfK/btsMFvrrFPk/wdsHFDQXRfGZBw0U0dc2x1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FljfK/btsMFvrrFPk/wdsHFDQXRfGZBw0U0dc2x1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFljfK%2FbtsMFvrrFPk%2FwdsHFDQXRfGZBw0U0dc2x1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1076&quot; height=&quot;907&quot; data-origin-width=&quot;1076&quot; data-origin-height=&quot;907&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/10808&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/10808&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;내가 해냄&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1741411149104&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;bits/stdc++.h&amp;gt;
using namespace std;

string s;   // 입력받을 문자열 선언

// 알파벳 개수가 기억이 안나서 아스키코드 값을 이용하여 배열 크기 지정
// 소문자 개수만큼 배열을 선언하여 각 알파벳의 개수를 저장
int cnt['z' - 'a' + 1] = {0};   

int main()
{
    /*
      배열의 크기 확인 방법:sizeof(배열) / sizeof(배열의 첫 번째 요소)
      - 배열 전체 크기를 각 요소의 크기로 나누어 개수를 구할 수 있음.
    */
    // cout &amp;lt;&amp;lt; sizeof(cnt) / sizeof(cnt[0]) &amp;lt;&amp;lt; &quot;\n&quot;;  // 배열 크기 확인용 코드 (디버깅용)
    
    // 문자열 s를 입력받는다
    cin &amp;gt;&amp;gt; s;

    /*
      입력받은 문자열을 순회하면서 각 알파벳의 등장 횟수를 카운트
      - s[i]는 문자(char)이며, 이를 'a'와의 차이를 이용해 배열의 인덱스로 변환
      - 'a'는 ASCII 값 97이므로, 'a'~'z'를 0~25 범위의 인덱스로 변환 가능
      - 예: 'b' - 'a' &amp;rarr; 1, 'z' - 'a' &amp;rarr; 25
   */
    for (int i = 0; i &amp;lt; s.size(); i++)
        cnt[s[i] - 'a']++;      

    /*
      배열에 저장된 각 알파벳의 등장 횟수를 출력
      - 범위 기반 for문을 사용하여 cnt 배열의 모든 값을 출력
      - 값들 사이에는 공백을 출력하여 가독성을 높임
    */
    for(int i : cnt) cout &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &quot; &quot;;

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;사용한 핵심 개념&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-end=&quot;959&quot; data-start=&quot;918&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// 배열을 이용한 카운팅 (Counting Array)&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1123&quot; data-start=&quot;960&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1009&quot; data-start=&quot;960&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`cnt` 배열을 활용하여 &lt;b&gt;각 알파벳의 등장 횟수를 저장하는 방식이다.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1057&quot; data-start=&quot;1010&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;공간 복잡도가 O(1)로 &lt;b&gt;빠른 조회 및 업데이트가 가능하다.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1123&quot; data-start=&quot;1058&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;해시 테이블(`unordered_map`) 대신 고정된 크기의 배열을 활용하여 더 빠르게 동작한다.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1123&quot; data-start=&quot;1058&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;코드에서 활용&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1741411893113&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int cnt[26] = {0};   // 26개의 공간을 갖는 배열 선언
for (int i = 0; i &amp;lt; s.size(); i++)
    cnt[s[i] - 'a']++;  // 해당 알파벳 인덱스 증가&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;43&quot; data-start=&quot;0&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// ASCII 코드 값 이용 (s[i] - 'a')&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;218&quot; data-start=&quot;45&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;111&quot; data-start=&quot;45&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;문자 'a'부터 'z'까지의 &lt;b&gt;ASCII 코드 값을 활용하여 배열의 인덱스로 변환하는 기법이다.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;218&quot; data-start=&quot;112&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;'a'의 ASCII 값은 97, 'b'는 98, ..., 'z'는 122이므로 'a'를 기준으로 빼면 &lt;b&gt;0~25 범위의 정수 인덱스를 얻을 수 있다.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1741411542447&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;char c = 'c';
cout &amp;lt;&amp;lt; c - 'a';  // 결과: 2 ('c' - 'a' = 99 - 97)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;코드에서 활용&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1741411769906&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cnt[s[i] - 'a']++;  // 알파벳을 0~25 범위의 인덱스로 변환하여 개수 증가&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;449&quot; data-start=&quot;400&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// 범위 기반 for문 이용 (for(int i : cnt))&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;572&quot; data-start=&quot;451&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;514&quot; data-start=&quot;451&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;C++11 이상&lt;/b&gt;에서 추가된 문법으로, `std::vector` 또는 배열을 순회할 때 유용하다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;572&quot; data-start=&quot;515&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;기존의 for 루프에서 인덱스를 활용하는 방식보다 &lt;b&gt;가독성이 좋고 코드가 간결하다.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1741411604552&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 기존의 인덱스 기반 for문
for (int i = 0; i &amp;lt; 26; i++) {
    cout &amp;lt;&amp;lt; cnt[i] &amp;lt;&amp;lt; &quot; &quot;;
}

// 범위 기반 for문 (더 간결하다)
for (int i : cnt) {
    cout &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &quot; &quot;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;코드에서 활용&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1741411859611&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for (int i : cnt) cout &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &quot; &quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;AI 피드백&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1741411206022&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;string&amp;gt;
using namespace std;

constexpr int ALPHA = 26;   // 알파벳 갯수
/*
constexpr : 컴파일 타임 상수를 정의하는 키워드
- constexpr을 사용하면 반드시 컴파일 시점에 값이 결정됨
- const는 런타임에도 값이 결정될 수 있지만, constexpr은 무조건 컴파일 타임에 결정되어야 한다
*/

int cnt[ALPHA] = {0};   // 각 알파벳 개수를 저장할 배열 (초기값 0)

int main()
{
    string s;

    // 문자열을 입력한다
    cin &amp;gt;&amp;gt; s;
    
    // 문자열의 각 문자를 순회하며 알파벳 개수를 센다
    // - string은 char로 구성되어 있다.
    // - 이를 범위 기반 for문에 활용하여 각 알파벳 소문자의 갯수를 센다
    // - 아스키코드 값을 이용해 cnt 배열의 해당 알파벳 위치에 접근하여 개수를 증가시킨다
    for(char c : s) cnt[c - 'a']++;     

    // 각 알파벳의 개수를 출력한다
    // - 삼항 연산자를 활용하여 마지막 값 뒤에는 개행, 나머지는 공백을 출력한다
    for(int i = 0; i &amp;lt; ALPHA; i++)
        cout &amp;lt;&amp;lt; cnt[i] &amp;lt;&amp;lt; (i == ALPHA - 1 ? &quot;\n&quot; : &quot; &quot;);

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;사용한 핵심 개념&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-end=&quot;124&quot; data-start=&quot;80&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// `constexpr`을 활용한 컴파일 타임 상수 정의&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;307&quot; data-start=&quot;125&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;184&quot; data-start=&quot;125&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`constexpr` 키워드를 사용하여 &lt;b&gt;컴파일 타임에 결정되는 상수를 정의하는 방식이다.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;261&quot; data-start=&quot;185&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`const`는 런타임에도 값이 결정될 수 있지만, `constexpr`은 &lt;b&gt;반드시 컴파일 시점에 값이 확정&lt;/b&gt;되어야 한다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;307&quot; data-start=&quot;262&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;매직 넘버(하드코딩된 숫자)를 없애고 의미를 명확하게 표현할 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;307&quot; data-start=&quot;262&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;코드에서 활용&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1741411976496&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;constexpr int ALPHA = 26;   // 알파벳 개수 (a~z는 총 26개다)&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;기존 코드와의 차이점&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1741411996334&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 기존 코드에서는 'z' - 'a' + 1로 배열 크기를 정의했지만, 
// ALPHA라는 상수를 사용하면 더 직관적이고 유지보수가 편리하다.
int cnt[ALPHA] = {0};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;594&quot; data-start=&quot;541&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// range-based for loop (범위 기반 for문) 활용&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;719&quot; data-start=&quot;595&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;662&quot; data-start=&quot;595&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`for (char c : s)`와 같은 구문을 사용하여, &lt;b&gt;문자열의 각 문자를 직접 순회하는 방식이다.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;719&quot; data-start=&quot;663&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;기존의 인덱스 기반 for 루프보다 &lt;b&gt;더 직관적이고 간결하며, 가독성이 뛰어나다.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;719&quot; data-start=&quot;663&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;코드에서 활용&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1741412053823&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for (char c : s) cnt[c - 'a']++;  // 문자를 직접 순회하며 카운트한다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;기존 코드와의 차이점&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1741412080146&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 기존 코드
for (int i = 0; i &amp;lt; s.size(); i++)
    cnt[s[i] - 'a']++;  

// 개선된 코드 (더 간결해졌다.)
for (char c : s) cnt[c - 'a']++;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;1010&quot; data-start=&quot;977&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// 삼항 연산자 활용하여 출력 최적화&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1124&quot; data-start=&quot;1011&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1073&quot; data-start=&quot;1011&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;마지막 원소 출력 시 불필요한 공백을 방지하기 위해 &lt;b&gt;삼항 연산자(?:)를 사용한 방식이다.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1124&quot; data-start=&quot;1074&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;if-else 문을 사용하는 것보다 &lt;b&gt;더 간결하고 깔끔한 코드가 된다.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1124&quot; data-start=&quot;1074&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;코드에서 활용&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1741412133166&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for (int i = 0; i &amp;lt; ALPHA; i++)
    cout &amp;lt;&amp;lt; cnt[i] &amp;lt;&amp;lt; (i == ALPHA - 1 ? &quot;\n&quot; : &quot; &quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;기존 코드와의 차이점&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1741412156710&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 기존 코드에서는 모든 출력값 뒤에 공백이 들어갔다.
for (int i : cnt) cout &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &quot; &quot;;

// 개선된 코드에서는 마지막 값 뒤에 개행(\n)을 넣고, 나머지는 공백을 출력한다.
for (int i = 0; i &amp;lt; ALPHA; i++)
    cout &amp;lt;&amp;lt; cnt[i] &amp;lt;&amp;lt; (i == ALPHA - 1 ? &quot;\n&quot; : &quot; &quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>C++/BAEKJOON</category>
      <category>C++</category>
      <category>constexpr</category>
      <category>개발</category>
      <category>백준</category>
      <category>백준10808</category>
      <category>범위기반for문</category>
      <category>아스키코드</category>
      <category>코딩테스트</category>
      <category>코테</category>
      <category>프로그래밍</category>
      <author>D0YUN</author>
      <guid isPermaLink="true">https://alizwldyl.tistory.com/37</guid>
      <comments>https://alizwldyl.tistory.com/37#entry37comment</comments>
      <pubDate>Sat, 8 Mar 2025 15:55:50 +0900</pubDate>
    </item>
    <item>
      <title>[YYBASIC0307/얌얌코딩] 연산자 오버로딩(Operator Overloading)</title>
      <link>https://alizwldyl.tistory.com/35</link>
      <description>&lt;h1&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;연산자 오버로딩&lt;/b&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;C++에서 연산자는 기본적으로 정수, 실수와 같은 기본 타입에 대해서만 정의되어 있습니다. 하지만 &lt;b&gt;사용자가 정의한 클래스에도 연산자를 적용&lt;/b&gt;할 수 있도록 &lt;b&gt;연산자 오버로딩(Operator&amp;nbsp;Overloading)&lt;/b&gt;을 지원합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;연산자 오버로딩을 사용하면, 객체끼리 `+`, `-`, `==`, `&amp;lt;&amp;lt;`, `[]` 등의 연산을 수행할 수 있습니다. 예를 들어, 두 개의 Vector 객체를 `+` 연산자로 더할 수 있다면 코드가 훨씬 직관적이고 가독성이 좋아집니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h1&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;연산자 오버로딩 문법&lt;/b&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;연산자 오버로딩은 `operator` 키워드를 사용하여 구현할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;class ClassName {
public:
    반환형 operator연산자(매개변수) {
        // 연산 수행
    }
};&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h1&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;멤버 함수 vs. 비멤버 함수&lt;/b&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;연산자 오버로딩을 할 때, &lt;b&gt;멤버 함수&lt;/b&gt;로 오버로딩할지 &lt;b&gt;비멤버 함수(전역 함수)로 오버로딩할지&lt;/b&gt; 선택해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;멤버 함수로 연산자 오버로딩&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;멤버 함수로 연산자 오버로딩을 하면 &lt;b&gt;왼쪽 피연산자(객체)&lt;/b&gt; 가 `this` 포인터를 통해 &lt;b&gt;자동으로 접근&lt;/b&gt;됩니다. 즉, &lt;b&gt;연산자 왼쪽에 있는 객체&lt;/b&gt;가 &lt;b&gt;멤버 함수의 주체&lt;/b&gt;가 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// 멤버 함수의 호출 방식&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;maxima&quot;&gt;&lt;code&gt;lhs.operator+(rhs);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;위 코드는 우리가 흔히 사용하는 `&lt;b&gt;lhs + rhs`&lt;/b&gt; 를 내부적으로 해석한 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// 멤버 함수 오버로딩의 특징&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;왼쪽&lt;/b&gt; 피연산자(`lhs`)가 `this` 포인터를 통해&lt;b&gt; 자동으로 접근&lt;/b&gt;됨&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;첫 번째 피연산자(`lhs`)가 &lt;b&gt;클래스의 멤버여야&lt;/b&gt; 함&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;오른쪽&lt;/b&gt; 피연산자(`rhs`)는 &lt;b&gt;함수의 매개변수&lt;/b&gt;로 전달됨&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// ex) `+` 연산자 오버로딩 (멤버 함수)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
class Vector {
public:
    int x, y;

    Vector(int x = 0, int y = 0) : x(x), y(y) {}

    // 멤버 함수로 + 연산자 오버로딩
    Vector operator+(const Vector&amp;amp; other) const {
        return Vector(x + other.x, y + other.y);
    }
};

int main() {
    Vector v1(3, 4);
    Vector v2(1, 2);
    Vector result = v1 + v2;  // v1.operator+(v2)로 해석됨

    std::cout &amp;lt;&amp;lt; result.x &amp;lt;&amp;lt; &quot;, &quot; &amp;lt;&amp;lt; result.y &amp;lt;&amp;lt; std::endl;  // 출력: 4, 6
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;비멤버 함수(전역 함수)로 연산자 오버로딩&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;비멤버 함수로 연산자 오버로딩을 하면 &lt;b&gt;연산자 왼쪽과 오른쪽을 대등한 관계&lt;/b&gt;로 다룰 수 있습니다. 즉, `lhs`와 `rhs`가 &lt;b&gt;동일한 방식&lt;/b&gt;으로 처리됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;// 비멤버 함수의 호출 방식&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;lisp&quot;&gt;&lt;code&gt;operator+(lhs, rhs);

&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 방식은 &lt;b&gt;연산자의 좌항과 우항을 대등한 관계로 처리&lt;/b&gt;해야 할 때 유용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// 비멤버 함수 오버로딩의 특징&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;두 피연산자가 동등한 관계로 처리됨 (`lhs`와 `rhs` &lt;b&gt;모두 매개변수&lt;/b&gt;로 전달됨)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;클래스 내부에 없는 연산자도 구현 가능&lt;/b&gt; (`ostream &amp;lt;&amp;lt;` 같은 연산자)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`friend` 키워드를 사용하면 &lt;b&gt;private 멤버에도 접근&lt;/b&gt; &lt;b&gt;가능&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;ex) `+` 연산자 오버로딩 (비멤버 함수)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
class Vector {
public:
    int x, y;
    Vector(int x = 0, int y = 0) : x(x), y(y) {}

    // friend 함수로 + 연산자 오버로딩
    friend Vector operator+(const Vector&amp;amp; lhs, const Vector&amp;amp; rhs);
};

// 전역 함수로 + 연산자 오버로딩
Vector operator+(const Vector&amp;amp; lhs, const Vector&amp;amp; rhs) {
    return Vector(lhs.x + rhs.x, lhs.y + rhs.y);
}

int main() {
    Vector v1(3, 4);
    Vector v2(1, 2);
    Vector result = v1 + v2;  // operator+(v1, v2)로 해석됨

    std::cout &amp;lt;&amp;lt; result.x &amp;lt;&amp;lt; &quot;, &quot; &amp;lt;&amp;lt; result.y &amp;lt;&amp;lt; std::endl;  // 출력: 4, 6
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;멤버 함수 사용 vs 비멤버 함수 사용&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;구분&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;멤버 함수 오버로딩&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;비멤버 함수(전역 함수) 오버로딩&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;호출 방식&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`lhs.operator+(rhs)`&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`operator+(lhs, rhs)`&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;첫 번째 피연산자&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;항상 &lt;b&gt;클래스의 객체(`this`)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;두 개의 피연산자가 &lt;b&gt;동등&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;일반적인 사용 예시&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`+=`, `-=`, `*=`, `/=` 등&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`+`,`-`, `==`, `!=`, `&amp;lt;&amp;lt;`, `&amp;gt;&amp;gt;` 등&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;클래스 외부 연산 가능 여부&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;불가&lt;/b&gt; (클래스 내부에서만 동작)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;가능&lt;/b&gt; (클래스 외부에서도 가능)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;출력 연산자(&amp;lt;&amp;lt;) 오버로딩 가능?&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;불가&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;가능&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;특별한 경우: `&amp;lt;&amp;lt;` 연산자 오버로딩&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;출력 연산자(`&amp;lt;&amp;lt;`)는 `std::cout`과 &lt;b&gt;객체를 함께 사용&lt;/b&gt;하기 때문에 &lt;b&gt;비멤버 함수(전역 함수)&lt;/b&gt;로 오버로딩해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// 비멤버 함수로 구현해야 하는 이유&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`std::cout`은 `ostream` 클래스의 객체이므로, 이를 `Vector`의 멤버 함수로 만들 수 없습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;ex) `&amp;lt;&amp;lt; `연산자 오버로딩 (비멤버 함수)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
class Vector {
public:
    int x, y;
    Vector(int x = 0, int y = 0) : x(x), y(y) {}

    // friend 함수로 &amp;lt;&amp;lt; 연산자 오버로딩
    friend std::ostream&amp;amp; operator&amp;lt;&amp;lt;(std::ostream&amp;amp; os, const Vector&amp;amp; v);
};

// 전역 함수로 &amp;lt;&amp;lt; 연산자 오버로딩
std::ostream&amp;amp; operator&amp;lt;&amp;lt;(std::ostream&amp;amp; os, const Vector&amp;amp; v) {
    os &amp;lt;&amp;lt; &quot;(&quot; &amp;lt;&amp;lt; v.x &amp;lt;&amp;lt; &quot;, &quot; &amp;lt;&amp;lt; v.y &amp;lt;&amp;lt; &quot;)&quot;;
    return os;
}

int main() {
    Vector v(3, 4);
    std::cout &amp;lt;&amp;lt; v &amp;lt;&amp;lt; std::endl;  // (3, 4)
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h1&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;연산자 오버로딩에서 주의할 점&lt;/b&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// 반환형을 고려할 것&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`operator+`와 같은 연산은 &lt;b&gt;새로운 객체를 반환&lt;/b&gt;하는 것이 일반적입니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`operator+=`와 같은 연산은 &lt;b&gt;자기 자신을 변경&lt;/b&gt;하고 `this`&lt;b&gt;를 반환&lt;/b&gt;하는 것이 좋습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// 객체의 원본을 변경하지 않도록 const 사용&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;`operator+`는 매개변수에 `const`를 붙여 원본이 변경되지 않도록 설계합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// 연산자의 의미를 유지할 것&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;연산자가 &lt;b&gt;직관적인 의미&lt;/b&gt;를 가지도록 구현합니다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;예를 들어 `==`는 값 비교, `&amp;lt;&amp;lt;`는 출력 용도로 활용합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// 비효율적인 연산 방지&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;불필요한 복사 연산을 줄이기 위해 참조(&amp;amp;)와 이동 연산자(std::move)를 고려합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h1&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;연산자 오버로딩을 통한 커스텀 Vector2 자료형의 사칙 연산 구현&lt;/b&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;아래 예제에서는 `Vector2`라는 구조체를 정의하고, 기본적인 사칙 연산(`+`, `-`, `*`, `/`) 및 비교 연산(`&amp;lt;`)을 오버로딩하여 사용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이때 &lt;b&gt;매개변수를 값으로 전달&lt;/b&gt;하면 &lt;b&gt;불필요한 복사 연산이 발생&lt;/b&gt;하여 성능이 저하될 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이를 방지하기 위해 `&lt;b&gt;const &amp;amp;`(`const` 참조) 키워드를 사용&lt;/b&gt;하여 &lt;b&gt;최적화된 코드&lt;/b&gt;를 구현했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;gml&quot;&gt;&lt;code&gt;// YYBASIC03_07
#include &amp;lt;iostream&amp;gt;  // 입출력을 위한 헤더 파일
using namespace std;

// 2차원 벡터(Vector2) 구조체 정의
struct Vector2
{
    int x;  // x 좌표
    int y;  // y 좌표

    // + 연산자 오버로딩: 두 Vector2 객체를 더하는 기능
    Vector2 operator+(const Vector2&amp;amp; other)
    {
        Vector2 rslt;
        rslt.x = x + other.x;
        rslt.y = y + other.y;

        return rslt;
    }

    // - 연산자 오버로딩: 두 Vector2 객체를 빼는 기능
    Vector2 operator-(const Vector2&amp;amp; other)
    {
        Vector2 rslt;
        rslt.x = x - other.x;
        rslt.y = y - other.y;

        return rslt;
    }

    // * 연산자 오버로딩: 두 Vector2 객체를 곱하는 기능
    Vector2 operator*(const Vector2&amp;amp; other)
    {
        Vector2 rslt;
        rslt.x = x * other.x;
        rslt.y = y * other.y;

        return rslt;
    }

    // / 연산자 오버로딩: 두 Vector2 객체를 나누는 기능 (단, 0으로 나누는 예외 처리가 필요함)
    Vector2 operator/(const Vector2&amp;amp; other)
    {
        Vector2 rslt;
        rslt.x = x / other.x;
        rslt.y = y / other.y;

        return rslt;
    }

    // &amp;lt; 연산자 오버로딩: 두 Vector2 객체를 비교하는 기능
    bool operator&amp;lt;(const Vector2&amp;amp; other)
    {
        return (x &amp;lt; other.x &amp;amp;&amp;amp; y &amp;lt; other.y); // 두 좌표가 모두 작을 때 true 반환
    }
};

int main(void)
{
    Vector2 p1;  // 첫 번째 벡터 객체 선언
    p1.x = 1;
    p1.y = 1;

    Vector2 p2;  // 두 번째 벡터 객체 선언
    p2.x = 3;
    p2.y = 2;

    Vector2 p3;  // 결과를 저장할 세 번째 벡터 객체 선언

    // 연산자 오버로딩을 사용하지 않고 p1 + p2 연산 수행
    p3.x = p1.x + p2.x;
    p3.y = p1.y + p2.y;
    cout &amp;lt;&amp;lt; &quot;p3 : (&quot; &amp;lt;&amp;lt; p3.x &amp;lt;&amp;lt; &quot; , &quot; &amp;lt;&amp;lt; p3.y &amp;lt;&amp;lt; &quot;)\\n&quot;;

    cout &amp;lt;&amp;lt; &quot;----- Initialize p3 -----\\n&quot;;

    // p3 좌표를 초기화
    p3.x = 0;
    p3.y = 0;
    cout &amp;lt;&amp;lt; &quot;p3 : (&quot; &amp;lt;&amp;lt; p3.x &amp;lt;&amp;lt; &quot; , &quot; &amp;lt;&amp;lt; p3.y &amp;lt;&amp;lt; &quot;)\\n&quot;;

    cout &amp;lt;&amp;lt; &quot;----- Use Operator Overloading -----\\n&quot;;

    // + 연산자 오버로딩 사용: p1 + p2 계산 (p1.operator+(p2)와 동일)
    p3 = p1 + p2;
    cout &amp;lt;&amp;lt; &quot;p3 : (&quot; &amp;lt;&amp;lt; p3.x &amp;lt;&amp;lt; &quot; , &quot; &amp;lt;&amp;lt; p3.y &amp;lt;&amp;lt; &quot;)\\n&quot;;

    cout &amp;lt;&amp;lt; &quot;----- Compare p1 &amp;amp; p2 with Operator Overloading -----\\n&quot;;

    // &amp;lt; 연산자 오버로딩 사용: p1이 p2보다 작은지 비교
    if (p1 &amp;lt; p2)
        cout &amp;lt;&amp;lt; &quot;p1 is smaller than p2\\n&quot;;

    // 문자열도 연산자 오버로딩이 구현되어 있어서 += 연산이 가능함
    string test = &quot;test&quot;;
    test += &quot; success&quot;;  // 문자열 덧붙이기 연산자 += 가 적용됨

    return 0;
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;// 실행 결과&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;653&quot; data-origin-height=&quot;175&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mvUEe/btsMEyhnty4/R3YJuJOj1yY5qIJhQUXuAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mvUEe/btsMEyhnty4/R3YJuJOj1yY5qIJhQUXuAK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mvUEe/btsMEyhnty4/R3YJuJOj1yY5qIJhQUXuAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmvUEe%2FbtsMEyhnty4%2FR3YJuJOj1yY5qIJhQUXuAK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;653&quot; height=&quot;175&quot; data-origin-width=&quot;653&quot; data-origin-height=&quot;175&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;const &amp;amp;를 사용한 최적화의 장점&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;불필요한 복사 연산 방지&lt;/b&gt; : `const Vector2&amp;amp;`를 사용하면&lt;b&gt; 원본 객체를 직접 참조&lt;/b&gt;하므로 &lt;b&gt;복사 비용을 줄일&lt;/b&gt; 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;객체의 불변성 유지&lt;/b&gt; : `const`를 추가하여 &lt;b&gt;연산 중 객체가 변경되지 않도록&lt;/b&gt; 보호합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;성능 향상&lt;/b&gt; : &lt;b&gt;값 복사 없이 연산을 수행&lt;/b&gt;하여&lt;b&gt; 빠른 실행 속도&lt;/b&gt;를 유지합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;C++ 표준 라이브러리에서의 연산자 오버로딩 활용&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;C++ 표준 라이브러리에서도 연산자 오버로딩이 적극적으로 활용됩니다. 대표적인 예로 `std::string`이 있으며, 문자열을 쉽게 이어 붙일 수 있도록 `+=` 연산자가 오버로딩되어 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1741322073189&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;string&amp;gt;

int main() {
    std::string test = &quot;test&quot;;
    test += &quot; success&quot;;  // += 연산자 오버로딩이 적용됨
    std::cout &amp;lt;&amp;lt; test &amp;lt;&amp;lt; std::endl;  // 출력: test success
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;528&quot; data-origin-height=&quot;182&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SMlUt/btsMDRBXj8T/Dm4nhHobAhMwkecwjqMSKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SMlUt/btsMDRBXj8T/Dm4nhHobAhMwkecwjqMSKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SMlUt/btsMDRBXj8T/Dm4nhHobAhMwkecwjqMSKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSMlUt%2FbtsMDRBXj8T%2FDm4nhHobAhMwkecwjqMSKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;528&quot; height=&quot;182&quot; data-origin-width=&quot;528&quot; data-origin-height=&quot;182&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;위 코드에서&lt;span style=&quot;color: #333333;&quot;&gt; `test += &quot; success&quot;;` 구문이 동작하는 이유는 `std::string` 클래스에 `operator+=`가 &lt;b&gt;오버로딩&lt;/b&gt;되어 있기 때문입니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;812&quot; data-origin-height=&quot;327&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdTrqA/btsMCuBaYRp/B2Y7NTakQgxvs12SOpom4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdTrqA/btsMCuBaYRp/B2Y7NTakQgxvs12SOpom4K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdTrqA/btsMCuBaYRp/B2Y7NTakQgxvs12SOpom4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdTrqA%2FbtsMCuBaYRp%2FB2Y7NTakQgxvs12SOpom4K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;812&quot; height=&quot;327&quot; data-origin-width=&quot;812&quot; data-origin-height=&quot;327&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 디버깅을 통해 확인해 보면 `operator+=`가 `const char*`을 &lt;b&gt;매개변수&lt;/b&gt;로 받아 &lt;b&gt;문자열을 결합&lt;/b&gt;하는 역할을 수행한다는 것을 알 수 있습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?embeds_referring_euri=https%3A%2F%2Fwww.inflearn.com%2F&amp;amp;source_ve_path=Mjg2NjQsMTY0NTAz&amp;amp;v=WfnuW1C3RoE&amp;amp;feature=youtu.be&quot;&gt;Lv11 연산자 오버로딩(Operator Overloading)&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=WfnuW1C3RoE&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/dSGMOt/hyYqVq8cqP/1jz6tftVpmRnKewslNYLC1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/b63ZxI/hyYm5WpdSU/cozW1QKYtQvc6GV2NSWYtK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;Lv11 연산자 오버로딩(Operator Overloading)&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/WfnuW1C3RoE&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>C++/YYBASIC</category>
      <category>C++</category>
      <category>개발</category>
      <category>게임프로그래밍</category>
      <category>얌얌코딩</category>
      <category>연산자오버로딩</category>
      <category>오버로딩</category>
      <category>프로그래머</category>
      <author>D0YUN</author>
      <guid isPermaLink="true">https://alizwldyl.tistory.com/35</guid>
      <comments>https://alizwldyl.tistory.com/35#entry35comment</comments>
      <pubDate>Sat, 8 Mar 2025 14:37:47 +0900</pubDate>
    </item>
  </channel>
</rss>