<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>프론트 엔드 개발자 박형석입니다. ( _ _ )</title>
    <link>https://kimbob-world.tistory.com/</link>
    <description>TIL을 한번 작성해볼까 합니다..</description>
    <language>ko</language>
    <pubDate>Mon, 29 Jun 2026 20:38:20 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>박형석_</managingEditor>
    <image>
      <title>프론트 엔드 개발자 박형석입니다. ( _ _ )</title>
      <url>https://tistory1.daumcdn.net/tistory/5108210/attach/aa9992e99d3742a2b92ea8cd6a6105d9</url>
      <link>https://kimbob-world.tistory.com</link>
    </image>
    <item>
      <title>AI의 답변 질을 높이는 기술 (feat.컨텍스트 엔지니어링)</title>
      <link>https://kimbob-world.tistory.com/entry/AI%EC%9D%98-%EB%8B%B5%EB%B3%80-%EC%A7%88%EC%9D%84-%EB%86%92%EC%9D%B4%EB%8A%94-%EA%B8%B0%EC%88%A0-feat%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4%EB%A7%81</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;어떻게 해야 Ai가 더 좋은 정보를 나에게 줄 수 있을까?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원하는 답은 있지만 항상 우린 말한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&quot;해 줘&quot;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;머릿속에 설계도는 3D로 그려놓고 정작 AI에게는 &quot;집 지어줘&quot;라고 말하는 것과 같다. &lt;br /&gt;생각해 보면 웃기지 않나.. &lt;br /&gt;난 아무것도 모르는데 그냥 해달래&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;아니? 나는 더 디테일하게 설명하는데? 그래서 잘해주는데?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&quot;A부분이 사진처럼 변경됐는데 여기는 B형태로 변경해 주고.. ~는 ~이런 식으로 변경해 줘&quot;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;이게 대부분 AI를 사용하는 방식이라고 생각했고 나 또한 그렇게 AI를 쓰면서 잘 쓰고 있다고 생각했다&lt;br /&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;br /&gt;라고 약 6개월 전의 나에게 내가 묻는다면 최소한 뭐인지는 &lt;b&gt;알아봐&lt;/b&gt;&amp;nbsp;&lt;b&gt;친구야&lt;/b&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;br /&gt;이 전에 구조를 사용해서 AI를 이용해서 개발을 하려 하면서 자연스럽게 알게 된 기술인데 정리하자면&lt;br /&gt;&lt;b&gt;일단 AI는 이전 대화를 기억하지 못한다.&lt;br /&gt;&lt;/b&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;AI에게 같은 질문을 다른 탭을 열어두고 해 보면 서로 다른 답을 준다.&lt;br /&gt;사람은 어떤가? 다른 사람이 똑같은 질문을 하면 결은 달라도 대부분 비슷한 답변을 준다.&lt;br /&gt;그리고 해당 대화를 통해 상대방을 파악하고 그 사람에 맞게 다시 한번 설명을 해준다고 했을 때 여기서 &lt;b&gt;컨텍스트 엔지니어링&lt;/b&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;b&gt;&quot;그 사람에 맞게 다시 한번 설명&quot;&lt;/b&gt;이다.&lt;br /&gt;이 사람이 이전에 나와 어떤 대화를 나누었고 어떤 것에 흥미를 느끼며 A라는 부류를 좋아한다라는 정보를 기억을 했다가&lt;br /&gt;그 정보를 토대로 제공을 해주는 것이다.&lt;br /&gt;우리가 누군가에게 배움을 받을 때 좋은 단어를 사용한 언어로는 이해가 가지 않을 때가 있지만 친한 친구와 이야기하며 &lt;b&gt;조금 수준 낮은 단어&lt;/b&gt;나 아니면 &quot;&lt;b&gt;저번에 그거 있잖아. A 가서 ~~ 했던 거&lt;/b&gt;&quot;하면 바로 이해했을 때가 있을 것이다.&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;b&gt;&quot;지식의 저주&quot;&lt;/b&gt;를 깨는 맥락(Context)의 힘이다.&lt;br /&gt;단어가 아무리 좋으면 뭐 하나.. &lt;br /&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;이처럼 컨텍스트 엔지니어링이란 AI의 답변이 기존 사용자의 정보를 토대로 &lt;b&gt;사용자가 이해하기 더 쉽게&lt;/b&gt; 또는 &lt;b&gt;정보를 사용자에게 맞게&lt;/b&gt; 전달을 하는 방식을 뜻한다.&lt;br /&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;style3&quot; /&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;b&gt;RAG(검색 증강 생성)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;어디에서 검색을 해올지 미리 알려주는 작업이다.&lt;br /&gt;예를 들어 AI한테 &lt;b&gt;&quot;나에 대해설명해줘&quot;&lt;/b&gt; 라고하면 당연히 정상 범주를 벗어난 답변을 해줄 것이다.&lt;br /&gt;하지만 &lt;b&gt;&quot;너는 지금부터 이 (내 설명이 적힌) 메모장을 기준으로 '나'란 사람에 대해서 물어보면 누군가에게 설명해 줘' &quot;라고&lt;/b&gt; 한다면?&lt;br /&gt;AI는 메모장을 기준으로 &quot;나&quot;라는 사람을 내가 써놓은 &lt;b&gt;최신정보에 맞춰서 더 디테일하게 설명해 줄 것이다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;이처럼 &lt;b&gt;AI의 머릿속 지식이 아닌&lt;/b&gt;, &lt;b&gt;내가 건네준&lt;/b&gt; &lt;b&gt;참고서를 먼저 펼쳐보게 하는 것,&lt;/b&gt; 그게 &lt;b&gt;컨텍스트 엔지니어링&lt;/b&gt;이다.&lt;br /&gt;그리고 &lt;b&gt;RAG(검색 증강)가&lt;/b&gt; 컨텍스트 엔지니어링을 실현하기에 좋은 방법론 중 하나이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;COT(Chain of Thought , 생각의 사슬)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Ai가 어떻게 답을 줄지 미리 단계를 정의하는 작업이다.&lt;/li&gt;
&lt;li&gt;Ai는 알고리즘을 굉장히 잘풀지만 가끔씩 내가 원하지 않는 답변을 줄 때가 있고 사용자 입장에서는 &lt;br /&gt;&lt;b&gt;&quot;그게 아니야 B에 대한 정보를 줘야지&quot;&lt;/b&gt;할 때가 있을 것이다.그 부분에서 사용되는 것이 &lt;b&gt;&quot;생각의 사슬(CoT)&quot;&lt;/b&gt;이다.&lt;/li&gt;
&lt;li&gt;우리도 어려운 알고리즘 문제를 풀 때, 머릿속 생각대로 코드를 쭉 써 내려가다가 틀리면 어떻게 하는가? &lt;b&gt;다시 처음부터&lt;/b&gt; 코드를 한 줄씩 읽으며 &quot;이 변수에는 뭐가 담기지?&quot;, &quot;여기서 조건문은 어떻게 작동하지?&quot;라며 &lt;b&gt;실행 과정을 복기&lt;/b&gt;한다.&lt;/li&gt;
&lt;li data-path-to-node=&quot;5,2&quot;&gt;&lt;b&gt;CoT&lt;/b&gt;는 AI에게 바로 이 &lt;b&gt;&quot;복기하는 과정&quot;&lt;/b&gt;을 미리 시키는 작업이다.&lt;br /&gt;답만 툭 내뱉으라고 재촉하는 게 아닌, &lt;b&gt;&quot;먼저 문제를 분석하고, 그다음 로직을 설계하고, 마지막으로 코드를 짜줘&quot;&lt;/b&gt;라고 &lt;br /&gt;생각의 단계(Chain)를 정의해 주는 것이다. 이렇게 길을 깔아주면 &lt;b&gt;AI는 훨씬 더 정교하고 정확한 답변을 내놓게 된다.&lt;/b&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;style7&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;여기까지가 내가 생각하는 &lt;b&gt;컨텍스트 엔지니어링 기법&lt;/b&gt;에 대한 설명이다.&lt;br /&gt;전에 들어본 것들이 얼핏 있기도 하고 내가 직접 프로젝트에 넣어보기 전에 공부하면서 글을 써보는 게 굉장히 도움이 되는 것 같다.&lt;br /&gt;컨텍스트 엔지니어링을 마친 이후에는 하네스 엔지니어링에 대해 알아볼 것이다.(그건 진짜 아무것도 모지만 써봤을 지도)&lt;/p&gt;</description>
      <category>프로젝트/개발로그</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/46</guid>
      <comments>https://kimbob-world.tistory.com/entry/AI%EC%9D%98-%EB%8B%B5%EB%B3%80-%EC%A7%88%EC%9D%84-%EB%86%92%EC%9D%B4%EB%8A%94-%EA%B8%B0%EC%88%A0-feat%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4%EB%A7%81#entry46comment</comments>
      <pubDate>Thu, 26 Mar 2026 23:04:37 +0900</pubDate>
    </item>
    <item>
      <title>바이브 코딩으로 3000줄 지옥을 경험하고 배운 것 &amp;mdash; AI 시대의 아키텍처 설계</title>
      <link>https://kimbob-world.tistory.com/entry/vibecode3000toai-architecture</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 AI(코덱스, 클로드, 재미나이)를&amp;nbsp;활용한 CLI를 통한 개발을 하며 느낀 기분은&lt;br /&gt;&quot;내가 왜 필요하지&quot; , &quot;채팅 치는데 얘가 만들어주고 나는 그 결과물만 구경하는 느낌&quot;을 많이 느꼈다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;s&gt;&lt;b&gt;(그렇다고 Ai를 쓰지 않는다면 &quot;속도&quot;가 너무 느려지니 끊기 힘든 마약 같은 느낌이랄까...)&lt;/b&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;그럼 어떻게 해야 AI도 잘 활용하면서 개발을 하는 걸까?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분이 많은 고민을 하고 있다가 멘토링을 통해 피드백을 받은 내용이 있다&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;(두구두구..)&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&amp;nbsp;아키텍처를 먼저 설계해 전체적인 구조를 잡아놓고 그 위에 반복적인 일을 AI에게 시킨다면 그게 좋은 도구 활용이다.&lt;/blockquote&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;그럼 네가 생각하는 아키텍처란?&lt;/b&gt;&lt;/h2&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;br /&gt;이 전에 CLI를 사용하기 전에는 폴더구조를 만들어놓고 그 폴더구조에 기초 공사는 내가 작업한 이후 &lt;br /&gt;AI를 어시스턴스 느낌으로 사용했다면&lt;br /&gt;Chat GPT가 맥에서 Visual Studio를 읽어서 직접 변경할 때부터 손으로 코드를 안치더니&lt;br /&gt;이후 Gemini CLI를 사용하고부터는 폴더구조까지도 맡기는 바보 같은 행동을 했다는 걸 새삼 다시 느끼고 있다.&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;지옥 같았던 3000줄의 스파게티 코드: kkeua 프로젝트&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;이 전에 &lt;b&gt;kkeua라는 프로젝트&lt;/b&gt;를 진행한 적이 있는데 &lt;b&gt;맥에서 Visual Studio가 연결되니 그때부터 바이브 코딩을 한 거 같다.&lt;/b&gt;&lt;br /&gt;폴더 구조는 간단하게 나눈 뒤 파일을 모듈별로 나누지 않고 한 페이지 내에 모든 기능들을 다 박아놓았던 기억이.. 난다&lt;br /&gt;그때 나는 API URL링크, 자주 쓰는 헤더, 풋바만 나눠놓고 페이지하나를 통째로 코드를 작업했었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그때 같이 작업하던 지인이 백엔드 개발자이자 리드개발자 역할을 했었는데 &lt;b&gt;코드가 3000줄이 넘어가고&lt;br /&gt;&lt;/b&gt;커밋당 +-합치면 300줄이 넘다보니 들었던 말이 있다&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot;내가 AI코드 N줄을 다 어떻게 읽어보냐, 커밋 좀 나눠서 해라.. , &quot;&lt;/b&gt;&amp;nbsp;이것저것 굉장히 많이 들었던 거 같다&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 생각해 보면 정말 어이가 없는 행동이었다.&lt;br /&gt;그 프로젝트를 진행할 때 소켓 관련 에러가 났었는데 A대기실에서 B페이지로 이동할 때&lt;br /&gt;A대기실에 소켓정보가 남아있고 B페이지에서 소켓 데이터가 제대로 연결되지 않는 버그가 있었다.&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;&quot;&lt;b&gt;이제 그 부분에서 서로 프론트엔드 / 백엔드 부분을 나눠서 작업하다 보니 어디서 에러가 낫는가?&quot;를&lt;/b&gt; 찾는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 AI로 코드 3000줄을 만들고 디버깅하려고 하니 &lt;br /&gt;&quot;소켓의 연결 흐름&quot; , &quot;A페이지에서 B페이지로 넘어가는 과정에 props데이터&quot;, &quot; 소켓 연결 / 종료 시점&quot; 내가 &lt;b&gt;아는 게 없었다.&lt;/b&gt;&lt;br /&gt;현재 코드에 문제가 있고 그게 프론트/백엔드인지 모르는 상황에서 AI 코드 &lt;b&gt;3000줄은 정말 지옥이었다.&lt;/b&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;br /&gt;사실상 해당 부분이 우리 &lt;b&gt;웹의 킥이 되는 부분&lt;/b&gt;이어서 서로 다른 일을 할 수도 없는 상황에 어디에 있는지도 모를 버그를 찾는데&lt;br /&gt;&lt;b&gt;&quot;나는 코드 실행흐름 자체를 모르고 AI에게 맡기고 있고&quot; , &quot;시간은 점점 흘러가는데 Ai는 백엔드 코드를 수정하려고 하고&quot;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&quot;나는 또 거기에 있어 이거 백엔드 로직이 문제일 수 있으니 이쪽 사항 바꿔달라고 요청하고&quot;&lt;/b&gt; 정말 쓸데없는 시간이 굉장히 많이 들었다.&lt;br /&gt;그렇게 이 프로젝트는 내게 있어서는 &quot;아직 해결하지 못한 짐&quot;으로써 가지고 있는 프로젝트이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&quot;실제 트래픽도 경험해보지 못하고 끝난 아쉬운 프로젝트...&quot;&lt;/b&gt;&amp;nbsp;&lt;/h4&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;사실 그게 맞다 내가 잘못을 했고 그렇게 프로젝트가 중단이 됐다..&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; 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;style1&quot; /&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&quot;그럼 그 실패에서 배운 게 있었을까?&quot;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;div data-test-render-count=&quot;1&quot;&gt;
&lt;div&gt;
&lt;div data-is-streaming=&quot;false&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;있다.&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3000줄의 스파게티 다음 프로젝트를 맡은 건 학교에서 기말프로젝트로 진행된 &lt;br /&gt;&lt;b&gt;Ai-serbot을 통한 화재 구조현장 제어로봇이었다.&lt;/b&gt;&lt;br /&gt;WIFI를 통해 아이피로 연결하여 소켓으로 통신하는 구조였다.(오답노트를 토대로 새로운 프로젝트랄까..)&lt;br /&gt;PM 겸 팀장을 맡게 됐는데 총 5명이서 진행한 프로젝트에서 인원은 로봇 1명, DB 1명 , 서버(본인) , 프론트 2명 구조로 진행됐다.&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;b&gt;내가 틀렸던 것을 바로잡을 기회&lt;/b&gt;였던 것 같다.&lt;br /&gt;&lt;b&gt;나는 바로 안전한 소켓 연결 및 통신 부분부터 개발을 진행했다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 디자인을 신경 쓰다가 제일 중요한 &lt;b&gt;&quot;소켓 연결&quot;&lt;/b&gt;이라는 &lt;b&gt;중요한 부분을 신경 쓰지 않고 바이브 코딩을 한 행동&lt;/b&gt;&lt;br /&gt;- 무질서한 구조로 &lt;b&gt;코드가 스파게티가 되어 어디서 연결되고 어디서 끊기는지 흐름 자체를 놓쳤던 것&lt;/b&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;br /&gt;5명이 로봇 2명/서버 1명/GUI 2명으로 프로젝트를 진행을 했었는데 오히려 프로젝트 난이도는 쉬웠던 거 같다.&lt;br /&gt;AI는 쓰지만 기능별로 소켓연결을 구조화시키니 메인이 어떤 흐름으로 데이터를 송/수신하는지 내가 구조를 알고 있기 때문에&lt;br /&gt;로봇-서버-GUI 구조로 &lt;b&gt;여러 개의 소켓을 쓰는 상황에서도 &lt;/b&gt;센서/GUI 쪽 문제가 있으면&lt;b&gt;&lt;br /&gt;그 부분에 대해 문제점을 빠르게 찾아 수정할 수 있게 되었다.(디버깅이 이렇게 편할 수 있엇다니..)&lt;/b&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;br /&gt;&lt;b&gt;팀원&lt;/b&gt;&lt;b&gt;분들이&lt;/b&gt; 뭔가 잘못되면&lt;b&gt; &quot;서버가 이상해요&quot;&lt;/b&gt;라고 했지만 &quot;&lt;b&gt;해당 문제면 여기서 문제가 있어야하는데 없네요?&quot;로 받아쳤다 ㅎ&lt;br /&gt;&lt;/b&gt;구조를 나눠놓음으로써 &lt;b&gt;어디에서 문제가 생겼는지 빠르게 확인할 수 있다는 것&lt;/b&gt;이 엄청난 장점이였다.&lt;br /&gt;&lt;span style=&quot;color: #666666;&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;중요한 소켓 연결을 안정적으로 만들었더니 그 이후 다른 기능을 붙이는 건 너무 쉬웠다.&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바보같이 중요한 것을 안하고 프론트 디자인만 수정하면서 &quot;&lt;b&gt;유저가 이런 것을 만들면 좋아하지 않을까?&quot;&lt;/b&gt;라는 생각만 했었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;그렇게 구조에 대한 글을 쓰기시작했고&lt;/b&gt;,&lt;b&gt;해당 글은 왜 내가 서버를 중심에 두는 구조를 선택했는가?&lt;/b&gt;에 대한 글이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a title=&quot;[Ai-serbot] 재난 로봇 시스템에서 서버를 중심에 두기로 한 이유&quot; href=&quot;https://kimbob-world.tistory.com/entry/Ai-serbot%EC%99%9C-%EC%9A%B0%EB%A6%AC%EB%8A%94-%EC%9E%AC%EB%82%9C-%EB%A1%9C%EB%B4%87-%EC%8B%9C%EC%8A%A4%ED%85%9C%EC%9D%84-%E2%80%98%EC%84%9C%EB%B2%84-%EC%A4%91%EC%8B%AC-%EA%B5%AC%EC%A1%B0%EB%A1%9C-%EC%84%A4%EA%B3%84%ED%96%88%EB%8A%94%EA%B0%80&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kimbob-world.tistory.com/entry/Ai-serbot왜-우리는-재난-로봇-시스템을-&amp;lsquo;서버-중심-구조로-설계했는가&lt;/a&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;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;그 경험 이후에도 나는 또 AI한테 구조까지 맡기고 있었다. 최근 3달이 딱 그랬다. &lt;br /&gt;클로드랑 코덱스 중에 누가 더 잘하나 테스트하면서 코드 자체를 통째로 맡겨두고, 비용이나 수치 같은 것만 신경 쓰고 있는 나를&lt;br /&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;b&gt;결국 AI 탓이 아니다.&lt;/b&gt; &lt;br /&gt;개발자인 내가 구조를 잡지 않으면, AI는 그저 &lt;b&gt;'잘 돌아가는 것처럼 보이는 3000줄짜리 스파게티 코드'&lt;/b&gt;를 또 만들어줄 뿐이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그래서 지금 진행 중인 Django 프로젝트를 Next.js로 전환하는 작업은 정신을 차리고&lt;br /&gt;이번엔 확실하게 구조부터 먼저 잡으며 진행하고 있다.&lt;br /&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&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;
&lt;/div&gt;</description>
      <category>프로젝트/개발로그</category>
      <category>AI개발</category>
      <category>Claude</category>
      <category>codex</category>
      <category>바이브코딩</category>
      <category>바이브코딩의 위험성</category>
      <category>설계</category>
      <category>소켓통신</category>
      <category>아키텍쳐</category>
      <category>프로젝트 회고</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/45</guid>
      <comments>https://kimbob-world.tistory.com/entry/vibecode3000toai-architecture#entry45comment</comments>
      <pubDate>Wed, 25 Mar 2026 14:10:12 +0900</pubDate>
    </item>
    <item>
      <title>AI가 사고를 내면 대체 누구 책임일까? (feat. 휴먼 인 더 루프)</title>
      <link>https://kimbob-world.tistory.com/entry/AI%EA%B0%80-%EC%82%AC%EA%B3%A0%EB%A5%BC-%EB%82%B4%EB%A9%B4-%EB%8C%80%EC%B2%B4-%EB%88%84%EA%B5%AC-%EC%B1%85%EC%9E%84%EC%9D%BC%EA%B9%8C-feat-%ED%9C%B4%EB%A8%BC-%EC%9D%B8-%EB%8D%94-%EB%A3%A8%ED%94%84</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;휴먼 인 더 루프란?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;인공지능(Ai)이 인간이 하는 일에 &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;color: #666666;&quot;&gt;과연 Ai가 우리의 모든 걸 자동으로 해준다고 하면 편할까?&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #666666;&quot;&gt;테슬라에서 핸들과 페달이 없는 &lt;b&gt;로보택시&lt;/b&gt;가 공개됐다는 걸 최근에 봤다(좀 늦긴 함..)&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;문제가 생겼을 때 제어할 수 없는 장치가 있다면 어떤 기분일까?&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;편안함보다는 불안함이 처음에 클 거 같다.&lt;br /&gt;FSD까지는 모르겠고 반자율주행을 처음 써볼 때도 너무 무서웠지만 핸들을 약하게 잡고 앞에 똑바로 봤던 기억이 있다 &lt;br /&gt;그런데 만약, 내 차에 아예 핸들과 페달마저 사라진다면 어떨까?&lt;br /&gt;처음에는 통제권이 없다는 생각에 너무 무서울 것 같다..&lt;/p&gt;
&lt;p 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;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;책임 소재는 누가 가질까?&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;과연 도로 위에서 사고가 아예 안 나는 완벽한 시스템이 존재할 수 있을까?&lt;br /&gt;현실에서는 내가 아무리 완벽하게 주행해도 누군가 갑자기 와서 부딪힐 수도 있고,&lt;br /&gt;시스템이 한 번도 학습하지 못한 예상치 못한 돌발 변수는 언제든 일어날 수밖에 없다고 생각한다.&lt;br /&gt;그렇게 위험천만한 순간이 닥쳤을 때,&lt;br /&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;의료 쪽으로 본다면 진단은 AI가 하되 최종 판단은 사람이 하는 거라고 생각한다&lt;br /&gt;만약 AI가 잘못 진단해서 암을 놓치고 지나갔다면 그 잘못이 AI를 믿은 환자의 잘못일까? 병원 잘못일까?&lt;br /&gt;아니면 Ai를 만든 곳일까&lt;br /&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;b&gt;휴먼 인 더 루프(HITL)&lt;/b&gt;라는 개념이 왜 중요한지 깨닫는 부분이라고 생각한다.&lt;br /&gt;AI가 주도하는 시스템의 의사결정이나 운영과정에서 &lt;b&gt;언제 어떻게 사람이 개입할 것 인가?&lt;/b&gt;를 설계하는 방법론이다.&lt;br /&gt;100% 완벽한 자동화는 불가능에 가깝고 돌발 변수는 존재하기에 Ai 시스템 안에는 위급한 순간 언제든 개입해&amp;nbsp;&lt;br /&gt;방향성이라는 핸들과 판단이라는 제동장치가 꼭 필요하다고 생각한다.&lt;br /&gt;&lt;br /&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;br /&gt;현재의 내 생각은 인공지능의 완전자동화는 인간에게 이익만 갖다 줄 것 같지는 않다.&lt;/p&gt;</description>
      <category>프로젝트/개발로그</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/44</guid>
      <comments>https://kimbob-world.tistory.com/entry/AI%EA%B0%80-%EC%82%AC%EA%B3%A0%EB%A5%BC-%EB%82%B4%EB%A9%B4-%EB%8C%80%EC%B2%B4-%EB%88%84%EA%B5%AC-%EC%B1%85%EC%9E%84%EC%9D%BC%EA%B9%8C-feat-%ED%9C%B4%EB%A8%BC-%EC%9D%B8-%EB%8D%94-%EB%A3%A8%ED%94%84#entry44comment</comments>
      <pubDate>Sun, 22 Mar 2026 03:22:18 +0900</pubDate>
    </item>
    <item>
      <title>코딩은 Ai가 다 한다면 개발자는 뭐 먹고살아야하나..?</title>
      <link>https://kimbob-world.tistory.com/entry/%EC%BD%94%EB%94%A9%EC%9D%80-Ai%EA%B0%80-%EB%8B%A4-%ED%95%9C%EB%8B%A4%EB%A9%B4-%EA%B0%9C%EB%B0%9C%EC%9E%90%EB%8A%94-%EB%AD%90-%EB%A8%B9%EA%B3%A0%EC%82%B4%EC%95%84%EC%95%BC%ED%95%98%EB%82%98</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=rQo_RnK9KUs&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.youtube.com/watch?v=rQo_RnK9KUs&lt;/a&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=rQo_RnK9KUs&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/LnEGB/dJMb8T9YvQp/rWHKGk3N1B2VfuH2QU4XjK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/byspoE/dJMb85WSloW/QZL4MiQ6fAFEH36a3WTZXK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/kcHGV/dJMb86nWAw3/L6ubh3HOyQIIlxypRCqWY0/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;커여운AI&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/rQo_RnK9KUs&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;최근에 만든 생성형 AI로 만든영상이다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지는 Gemini / 영상은 hailuo / 노래는 Suno를 통해 제작했다.&lt;br /&gt;가사를 계속 수정하면서 요즘 코딩을 하는방식을 넣어봤는데 들어보면 내 최근 개발이 들어있다.&lt;br /&gt;(CLI가 들어오면서 너무 편해짐.. 근데 아직 취준생인데 이런 말 해두 될진 잘 모름)&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;확실히 AI가 개발에 들어오다보니 속도가 빨라진건 체감이 너무 잘되고 이 전으로 돌아가기는 힘들 것 같다.&lt;br /&gt;그러면 난 어떻게 성장해야할까? 사실 코드를 만드는건 나보다는 AI가 더 잘하는건 팩트다&lt;br /&gt;(그래서 요즘 신입 취업이 좀 어려워진 것도 맞긴한거같다.)&lt;br /&gt;&lt;br /&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;b&gt;일단 자료구조랑 알고리즘 공부부터 해볼까?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 전에 프로그래머스를 통해 PCCP를 봤던 경험이 있는데, 그때도 스터디하며 자료구조를 열심히 공부해서 문제를 풀었던 경험이 있엇다.&lt;br /&gt;그럼 뭐하나 그때는 문제의 구조를 모르겠다고 AI를 통해서 검색해보는게 너무 많았고,&lt;br /&gt;&quot;이 코드가 왜 안되지&quot; , &quot;프로그래머스 이 문제를 풀고있는데 내 코드가 뭐가 문제임?&quot; , &quot;어떤 구조로 풀어야해?&quot;&lt;br /&gt;AI는 좋지만 사용방법이 너무 잘못됐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;그렇게 해서 문제를 푸는 구조는 알았는데 실제 시험이 들어갔을때 구조는 알겠는데&lt;br /&gt;어떻게 구현해야할지만 2시간동안 고민하다가 나왔을때 자괴감이 많이 들어&lt;br /&gt;그 이후로 알고리즘을 1달정도는 안봤던 기억이 있다 :(&lt;/p&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; &amp;zwj; &amp;nbsp; 다시 해야지..&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;교내에서 자료구조 / 알고리즘 동아리를 하나 만들어서 서로가 자료구조에 대해 설명해주고&lt;br /&gt;1 주에 프로그래머스/백준 문제를 2개를 풀어서 제출하기로 했다. &lt;br /&gt;대신 제일 중요한거&lt;b&gt;&quot;절 대 Ai를 쓰지마&quot;라는 규칙을 추가했다.&lt;br /&gt;&lt;/b&gt;내가 제일 힘들었던 부분이 AI를 통해서 문제를 풀다보니 문제를 보고 &lt;b&gt;&quot;우선순위 큐로 풀어야겠네&quot;&lt;/b&gt;는 알겠는데 실제 문제에서 어떻게 접근해야할지 그 부분이 너무 어려웠다.(&lt;b&gt;&quot;Ai가 단축시켜준 시간만큼 너는 질이 부족한 정보를 가져간다.&quot;&lt;/b&gt;라는 생각이 생긴걸지도)&lt;b&gt;&lt;/b&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;❓그러면 문제가 어렵고 구조도 모르겠으면 어떡하지&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;우리에게는 인공지능(AI)이전에 구글신과 스택오버플로우가&lt;/b&gt; 있엇다.&lt;br /&gt;&quot;근데 그러면 Ai검색하는거랑 똑같은거 아녀?&quot;라는 의문이 들 수 있다. 하지만 최근 글을 써본결과 조금 다른 부분이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 질문하기 나름이겠지만 AI에게 질문하면 내가 물어본 단편적인 질문에 대한 정보만 돌아온다&lt;br /&gt;&lt;b&gt;ex)내 코드에서 어떤 부분이 잘못됐어? -&amp;gt; a가 b로 바뀌어야해요&lt;/b&gt;&lt;br /&gt;하지만 구글 서치를 한다면 예를들어 잘못된 부분을 찾기위해서 해당 자료구조부터 찾아보게 될것이다.&lt;br /&gt;&quot;파이썬은 스택에서 어떤 자료구조를 갖고있나?&quot; ,&quot;우선순위 큐는 어떤식으로 구현하지?&quot;를 구글에 검색한다면 사람들이 써놓은 &quot;스택 , 큐&quot;..등등 &lt;b&gt;원리부터 실제 사용까지&lt;/b&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;br /&gt;단편적으로 코드에서 내가 어떤 부분이 잘못됐다는 것을 볼게아닌 내가 쓰는자료구조가 어떤 식으로 이루어져있는지 원리를 알기를 원하고 추가로 문법적으로 틀렸다면 그 문법적으로 틀린 것을 가지고 1시간이상 써본다면 다음에 그 문법가지고 틀릴 일은 없다.&lt;br /&gt;나도 물론 자료구조/알고리즘을 전체적으로 한번 훑어봤지만 아직 모르는 입장이다.&lt;br /&gt;그래서 이 후 내 학교 동기들은 나와같은 고통을 알지 않았으면 좋겠다.&lt;br /&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;b&gt;✅ 다시하면 된다.&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 스터디 약 2달 정도를 잡고 문제를 풀고 있는데, 끝나면 다시 PCCP 볼 것이다. &lt;br /&gt;2달 뒤의 내가 PCCP에 관한 글을 포스트하지 않았다면 아마 이 글이 지워질지도 모른다... &lt;br /&gt;AI는 그때까지 문법이든 뭐든 절대 쓰지 않고 풀어서 올려야지. 실패하면 뭐 다시 하면 된다.&lt;br /&gt;&lt;b&gt;편하자고 포기하지만 말자.&lt;/b&gt;&lt;/p&gt;</description>
      <category>프로젝트/개발로그</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/43</guid>
      <comments>https://kimbob-world.tistory.com/entry/%EC%BD%94%EB%94%A9%EC%9D%80-Ai%EA%B0%80-%EB%8B%A4-%ED%95%9C%EB%8B%A4%EB%A9%B4-%EA%B0%9C%EB%B0%9C%EC%9E%90%EB%8A%94-%EB%AD%90-%EB%A8%B9%EA%B3%A0%EC%82%B4%EC%95%84%EC%95%BC%ED%95%98%EB%82%98#entry43comment</comments>
      <pubDate>Thu, 19 Mar 2026 11:46:36 +0900</pubDate>
    </item>
    <item>
      <title>개인화 서비스에 대해</title>
      <link>https://kimbob-world.tistory.com/entry/%EA%B0%9C%EC%9D%B8%ED%99%94-%EC%84%9C%EB%B9%84%EC%8A%A4%EC%97%90-%EB%8C%80%ED%95%B4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;요즘 서비스를 기획하고 개발하면서 &lt;b&gt;개인화(Personalization)&lt;/b&gt;에 대해 깊이 고민하고 있다. 인공지능(AI) 기술이 비약적으로 발전하면서, 이제 서비스는 단순히 데이터를 수집하는 수준을 넘어 사용자의 상황을 '추론'하고 최적의 경험을 '실행'하는 단계에 접어들었기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전에는 추천의 기준이 &lt;b&gt;'Tag'&lt;/b&gt;라는 틀이었다면, 현재는 &lt;b&gt;'경험 기반 AI의 추론'&lt;/b&gt;을 통한 추천 시스템이다. 아래는 그 예시이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  사용자가 최근에 공포영화를 봤을 때&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;기존 Tag 방식&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사람이 미리 정의한 키워드에 의존해야 한다.&lt;/li&gt;
&lt;li&gt;사용자가 봤던 영화의 태그를 확인하고(예: #스릴러, #공포영화) 비슷한 태그의 영화를 추천한다.&lt;/li&gt;
&lt;li&gt;사용자가 A를 봤으니 B를 좋아할 것이라는 고정된 규칙에 가깝다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;현재: 데이터 사이의 맥락(Context) 기반 추천&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&quot;사용자가 비 오는 금요일 밤에 공포영화를 끝까지 봄&quot;, &quot;중간에 무서운 장면에서 일시 정지함&quot; 등 다양한 행동 데이터를 분석한다.&lt;/li&gt;
&lt;li&gt;현재 상황(날씨, 시간)에 맞는 영화를 추천해 주며, 사용자 데이터를 통해 진정한 맞춤형 서비스가 가능해진다.&lt;/li&gt;
&lt;li&gt;AI가 상황과 행동을 통해 더 좋은 서비스를 줄 수 있다는 것, 그게 진짜 사용자 경험의 끝이 아닐까 싶다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⚖️ 개인화의 역설: 나를 너무 잘 알아서 생기는 문제들&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단점이라기보다는 조심해야 할 점들이 보인다. &lt;b&gt;'필터 버블(Filter Bubble)'&lt;/b&gt;이라고 하는데, AI가 너무 정확하게 취향을 저격하다 보면 사용자가 새로운 장르를 접할 기회가 많이 사라진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 유튜브를 보면, 애니메이션을 봤을 때 관련 알고리즘이 적용되어 피드에 애니메이션이 가득 차게 된다. 그러다 가끔 이전에 봤던 노래 영상이나 예능 영상들이 하나씩 보이고, 그걸 클릭하면 점점 많아진다. 그렇다 보니 요즘 유튜브로 새로운 것을 본 적이 많이 없는 것 같다. (그래서 새로운 쇼츠라는 도파민에 빠진 건가...?)&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;우리는 어쩌면 알고리즘으로 인한 뻔한 구성을 넘어, 쇼츠를 통한 예측할 수 없는 의외성을 찾고 있는지도 모르겠다.&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;&lt;/blockquote&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;'의외의 발견(Serendipity)'&lt;/b&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;&lt;b&gt;&quot;아, 이 사람이 이런 쪽으로도 확장할 수 있구나?&quot;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라는 것 또한 학습하고 또 다른 사용자에게 전달되어 더 다양한 분야를 추천할 수 있는 시스템이 되겠지.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&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;결국 서비스를 만들어야 하는 개발자 입장에서 &lt;b&gt;&quot;정확한 추천&quot;&lt;/b&gt;만 추구한다면 지루한 서비스가 될 수 있고, &lt;b&gt;&quot;새로운 경험&quot;&lt;/b&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;b&gt;초개인화 서비스&lt;/b&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;단순히 &quot;너랑 딱 맞는 회사야&quot;라는 정확도만 강조하기보다, &lt;b&gt;&quot;네 이력서라면 이런 의외의 분야에서도 충분히 매력적일 수 있어&quot;&lt;/b&gt;라는 새로운 선택지를 던져주는 것. 어쩌면 이게 내가 만드는 서비스가 지루한 정보 전달을 넘어, 사용자의 커리어 스펙트럼을 넓혀주는 &lt;b&gt;'진짜 개인화'&lt;/b&gt;로 가는 길이 아닐까 싶다.&lt;/p&gt;</description>
      <category>프로젝트/개발로그</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/42</guid>
      <comments>https://kimbob-world.tistory.com/entry/%EA%B0%9C%EC%9D%B8%ED%99%94-%EC%84%9C%EB%B9%84%EC%8A%A4%EC%97%90-%EB%8C%80%ED%95%B4#entry42comment</comments>
      <pubDate>Thu, 19 Mar 2026 01:15:49 +0900</pubDate>
    </item>
    <item>
      <title>Django venv에서 Docker로 변경하면 어떤 이득을 가질 수 있을까?</title>
      <link>https://kimbob-world.tistory.com/entry/Django-venv%EC%97%90%EC%84%9C-Docker%EB%A1%9C-%EB%B3%80%EA%B2%BD%ED%95%98%EB%A9%B4-%EC%96%B4%EB%96%A4-%EC%9D%B4%EB%93%9D%EC%9D%84-%EA%B0%80%EC%A7%88-%EC%88%98-%EC%9E%88%EC%9D%84%EA%B9%8C</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Venv의 한계를 마주하다&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 Django로 랩실 프로젝트를 진행하며 venv를 통해 가상환경을 구축하고, 그 안에서 버전 관리를 진행했다. &lt;br /&gt;또한 MySQL을 이용해 DB를 구성했다.하지만 팀원들의 초기 설정을 도와주느라 예상보다 많은 시간을 소모했다.&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;특히 README에 venv 설정, requirements 설치, 마이그레이션 등의 과정이 정리되어 있지 않아&lt;br /&gt;에러를 해결하는 데 불필요한 시간을 많이 사용했다.&lt;br /&gt;또한 집에서 MySQL과 Python을 별도로 설치해야 하는 과정이 번거로워 개발 자체를 꺼리게 되는 경우도 있었다.&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;그리고 Mac, Windows, Linux 간의 환경 차이로 인해 로컬에서는 정상 동작하던 코드가&lt;br /&gt;병합 후에는 오류가 발생하는 문제가 점점 빈번해졌다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&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;그렇다면 Docker는 어떤 역할을 하길래 이를 도입하게 되었을까?&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 첫 번째 이유는 개발 환경의 통합이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Docker가 설치된 상태에서 &lt;span&gt;docker-compose up --build&lt;/span&gt;를 실행하면, 컨테이너 내부에 Django, MySQL 등 필요한 실행 환경이 이미지 기반으로 구성되어 별도의 로컬 설치 없이도 동일한 환경에서 프로젝트를 실행할 수 있다.&lt;br /&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;b&gt;- 두 번째 이유는&amp;nbsp; 초기 설정 비용 및 온보딩 개선이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에는 프로젝트를 실행하기 위해 Python, MySQL 등 다양한 의존성을 직접 설치해야 했고, 이 과정에서 많은 오류가 발생했다.&lt;br /&gt;하지만 Docker를 도입한 이후에는 단순히 &lt;span&gt;docker-compose up&lt;/span&gt; 명령어만으로 전체 환경을 구성하고 실행할 수 있게 되어,&lt;br /&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;b&gt;세 번째: 배포 과정의 단순화 및 일관성 확보&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에는 로컬에서 실행하던 환경과 서버 환경을 별도로 구성해야 했기 때문에, 배포 과정에서 추가적인 설정과 오류가 발생하는 경우가 많았다.Docker를 도입하면서 로컬 환경을 이미지로 정의하고 동일한 환경을 재현할 수 있도록 구성했으며, 이를 통해 향후 배포 시에도 환경 차이 없이 서비스를 운영할 수 있는 기반을 마련했다.현재는 기존 Render 환경을 사용하고 있어 Docker 기반 배포까지는 진행하지 않았지만, 배포 환경에서도 동일한 구조를 적용할 수 있도록 준비하였다.&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;Docker Image만 있으면 어떤 클라우드(AWS, GCP, Azure)에서도 즉시 배포 가능하기때문에 이를 이용해 쿠버네티스나 EC2까지 여러개의 배포 파이프라인을 경험해보고 TDD를 제작해볼 생각이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로젝트/개발로그</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/41</guid>
      <comments>https://kimbob-world.tistory.com/entry/Django-venv%EC%97%90%EC%84%9C-Docker%EB%A1%9C-%EB%B3%80%EA%B2%BD%ED%95%98%EB%A9%B4-%EC%96%B4%EB%96%A4-%EC%9D%B4%EB%93%9D%EC%9D%84-%EA%B0%80%EC%A7%88-%EC%88%98-%EC%9E%88%EC%9D%84%EA%B9%8C#entry41comment</comments>
      <pubDate>Tue, 17 Mar 2026 23:54:57 +0900</pubDate>
    </item>
    <item>
      <title>Django가 Netlify를 이용해서 배포하는게 왜 비효율적일까?</title>
      <link>https://kimbob-world.tistory.com/entry/Django%EA%B0%80-Netlify%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%B4%EC%84%9C-%EB%B0%B0%ED%8F%AC%ED%95%98%EB%8A%94%EA%B2%8C-%EC%99%9C-%EB%B9%84%ED%9A%A8%EC%9C%A8%EC%A0%81%EC%9D%BC%EA%B9%8C</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;최근 프로젝트에서는 &lt;span&gt;&lt;span&gt;Next.js&lt;/span&gt;&lt;/span&gt; 기반으로 개발을 진행하는 경우가 많았기 때문에 &lt;span&gt;&lt;span&gt;Netlify&lt;/span&gt;&lt;/span&gt;를 이용한 배포를 주로 했다.&lt;br /&gt;Netlify는 &lt;b&gt;정적 파일을 기반&lt;/b&gt;으로 하는 프론트엔드 프로젝트를 손쉽게 배포할 수 있도록 지원하는 플랫폼이기 때문에 React나 Next.js와 같은 프레임워크와 잘 맞는다...(아무튼 그렇다)&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;이번 프로젝트에 사용한 Django는 WSGI(Web Server Gateway Interface)기반의 서버형 웹 프레임워크로,&lt;br /&gt;정적페이지를 단순히 제공하는 것이 아닌 서버에서 브라우저 요청을 실시간으로 처리한 뒤&lt;br /&gt;템플릿을 렌더링하여 사용자에게 응답하는 MVT(Model-View-Templet) 구조를 가진다.&lt;br /&gt;한마디로, 사용자 요청이 발생할 때마다 서버가 가동되어&lt;br /&gt;&lt;b data-index-in-node=&quot;31&quot; data-path-to-node=&quot;4&quot;&gt;데이터와 정적 자원(JS, CSS, HTML)을 결합해 동적으로 페이지를 생성&lt;/b&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;- 그럼 Nelify를 이용해서 배포하면 왜 비효율적일까?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Netlify같은 경우에 정적 사이트 호스팅 플랫폼이기 때문에 &lt;br /&gt;git push -&amp;gt; 빌드 -&amp;gt; 정적파일(html,css,js) 생성 -&amp;gt; CDN에 배포 구조를 가지고 있기 때문에 서버가 계속 실행되지않는다.&lt;br /&gt;하지만 Django의 요구환경은 Python서버가 항상 실행되고 요청마다 코드가 실행되는 구조이다.&lt;br /&gt;그래서 실제 개발용 서버 python manage.py runserver를 통해 개발을 진행하고 운영에는 Nginx + Gunicorn구조를 사용한다.&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;- 그럼 Netlify로 배포는 할 수 없나요?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;불가능한건 아니지만 정적 사이트 생성기처럼 사용하거나 &lt;b&gt;Serverless Function&lt;/b&gt;을 활용해야하지만 Django 본연의 MVT를 제대로 활용하지 못하기 때문에 &lt;b&gt;Render&lt;/b&gt;나 &lt;b&gt;Railway&lt;/b&gt;같은 서비를 주로 사용합니다.&lt;br /&gt;(쉽게 생각하면 Netlify의 서버버전이라고 생각하면 편합니다 PaaS - 서비스형 플랫폼)&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;- 그럼 Nginx + Gunicorn은 뭐고 Render,Railway는 뭔데요?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Django는 파이썬 파일일 뿐이라 혼자 돌아갈 수 없습니다. &lt;br /&gt;그래서 Gunicorn이 해당 파일을 실행해 &quot;프로세스&quot;상태로 유지하고 실제 유저가 들어왔을때 웹에 서빙을 하는역할을 합니다.&lt;br /&gt;Nginx는 여기서 정적파일을 서빙하는 역할을 합니다.&lt;br /&gt;.jgp,css,html파일같은 정적파일은 Django를 거칠 필요없어 하드에서 바로 꺼내보여줄 수 있게 하는것이 Nginx입니다.&lt;br /&gt;그로 인해 사용자에게 정적파일을 좀 더 빨리 보여줄 수 있다는 장점과 외부 공격으로부터 Django가 돌아가는 포트를 숨기고 보호할 수 있다는 장점이 있습니다.&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;Render나 Railway는 Nginx나 Gunicorn같은 소프트웨어 개념이 아닌 그것들을 포함시킨 &quot;대행 서비스&quot;입니다.&lt;br /&gt;GitHub에 소스 코드를 올리고 연결만 하면, Render나 Railway 측에서 자기들의 서버에 &lt;b data-index-in-node=&quot;60&quot; data-path-to-node=&quot;9,1,0&quot;&gt;이미 세팅된 Nginx와 유사한 환경&lt;/b&gt;에 내 코드를 올려버립니다.Netlify가 정적파일만 지원한다면 이 두개는 &quot;실행중인 파이썬 서버&quot;까지 지원해준다는 장점이 있습니다.&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;저는 Nginx와 Gunicorn을 통해 다시한번 배포해 CI/CD 배포파이프라인을 경험 해보고싶기 때문에 이후 후기를 남기러 다시 오겠습니다.이전에 해봤던 경험은있지만 이렇게 실제 글을 쓰려고 공부를 하고 다시 작업을 하면 따라 치기에만 바빳던 그때와 다른 결과가 있을꺼라 생각하기때문에 재밌을꺼같습니당&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로젝트/개발로그</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/40</guid>
      <comments>https://kimbob-world.tistory.com/entry/Django%EA%B0%80-Netlify%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%B4%EC%84%9C-%EB%B0%B0%ED%8F%AC%ED%95%98%EB%8A%94%EA%B2%8C-%EC%99%9C-%EB%B9%84%ED%9A%A8%EC%9C%A8%EC%A0%81%EC%9D%BC%EA%B9%8C#entry40comment</comments>
      <pubDate>Tue, 17 Mar 2026 00:10:36 +0900</pubDate>
    </item>
    <item>
      <title>[Core-CBT]GPT API 비용 40% 절감하기: Supabase를 활용한 CBT 서비스 캐싱 전략</title>
      <link>https://kimbob-world.tistory.com/entry/Core-CBTGPT-API-%EB%B9%84%EC%9A%A9-40-%EC%A0%88%EA%B0%90%ED%95%98%EA%B8%B0-Supabase%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-CBT-%EC%84%9C%EB%B9%84%EC%8A%A4-%EC%BA%90%EC%8B%B1-%EC%A0%84%EB%9E%B5</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;정보처리산업기사 자격증을 준비하며 여러 CBT 서비스를 사용했지만, &lt;/span&gt;&lt;span&gt;시험 환경에 비해 학습 경험은 아쉬웠습니다.&lt;/span&gt;&lt;br /&gt;&lt;span&gt;해설을 바로 확인하기 어렵고, &lt;/span&gt;&lt;span&gt;오답을 기준으로 다시 학습하기도 불편했기 때문입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;문제를 풀다 막혔을 때, 즉시 해설을 보고 GPT에게 추가 질문을 통해 &lt;b&gt;학습&lt;/b&gt; &lt;b&gt;흐름을 이어갈 수 있는 환경&lt;/b&gt;을 만들고 싶었습니다. 그렇게 &lt;b&gt;Core-CBT 프로젝트&lt;/b&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;b&gt;&quot;왜 틀렸는지&quot;&lt;/b&gt;가 중요한 포인트라고 생각하여&lt;br /&gt;Open AI API를 도입했습니다. 하지만 곧 두 가지의 현실적인 문제가 있었습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&amp;gt;&lt;b&gt; 느린 응답 속도 :&lt;/b&gt;&amp;nbsp; 질문 후 5초 이상 소요되는 로딩 시간으로 인한 학습의 흐름을 끊는 대기시간&lt;/li&gt;
&lt;li&gt;&amp;gt;&lt;b&gt; 비용 문제 :&lt;/b&gt; 사용자가 증가함에 따라 기하급수적으로 늘어나는 API 요금&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 사용자들이 응답속도면에서 &lt;b&gt;불편함을 느낀 피드백&lt;/b&gt;이 들어왔고 ,해당&amp;nbsp;문제를 해결하기 위해&lt;br /&gt;&lt;b&gt;Supabase를 활용한 캐싱 전략&lt;/b&gt;을 도입했고, 결과적으로 &lt;b&gt;리퀘스트 효율을 40% 이상 개선&lt;/b&gt;했습니다.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;b&gt;나중에&amp;nbsp;같은&amp;nbsp;고민을&amp;nbsp;할&amp;nbsp;&quot;나&quot;&amp;nbsp;또는&amp;nbsp;누군가를&amp;nbsp;위해&amp;nbsp;그&amp;nbsp;과정을&amp;nbsp;기록으로&amp;nbsp;남깁니다.&lt;/b&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;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. 3단계 캐싱 레이어 구축&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;단순한 DB에 저장/불러오는것이 아닌 요청이 발생하는 지점부터 서버까지 &lt;b&gt;3단계의 거름망&lt;/b&gt;을 만들었습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;gt;&lt;b&gt; L1(Browser)&lt;/b&gt; : 로컬 스토리지에 사용자가 이전에 질문했던 정보가 남아있다면,&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 서버 요청 없이 즉시 반환하여 응답 시간을 제로(0ms)에 가깝게 구현했습니다.&lt;/li&gt;
&lt;li&gt;&amp;gt;&lt;b&gt; L2(Database)&lt;/b&gt; : 내가 처음 보는 문제라도 , 다른 사용자가 이미 질문했던 내용이라면 &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Supabase에 저장된 데이터를 가져와서 보여줍니다.&lt;/li&gt;
&lt;li&gt;&amp;gt;&lt;b&gt; Origin(LLM)&lt;/b&gt; : 앞선 두 레이어 데이터가 없을 때만 Open AI API를 호출하여 새로운 답변을 생성하고&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 그 결과를 DB에 기록하여 다음 사용자를 위한 자산으로 만듭니다.&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;size18&quot;&gt;&lt;b&gt; 2. 핵심 로직: 캐시 키(Cache Key) 설계&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;중복 요청을 판별하기 위한 가장 중요한 것은&amp;nbsp;&lt;b&gt;&quot;무엇이 같은 질문일까?&quot;&lt;/b&gt;를 정의하는 것이었습니다.&lt;br /&gt;단순히 문제 번호만을 기준으로 캐시를 만들면 ,동일한 문제라도 &lt;b&gt;&quot;사용자가 어떤 보기를 선택했는가?&quot;&lt;/b&gt;에 따라&lt;br /&gt;전혀 다른 해설이 필요하기때문에 &lt;b&gt;실서비스에서 사용하기에는 부족&lt;/b&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;b&gt;&quot;내가 고른 이 답이 왜 틀렸는가?&quot;&lt;/b&gt;에 대한 정교한 피드백입니다.&lt;br /&gt;따라서 문제와 정답의 단순 매칭 보다는,사용자가 &quot;&lt;b&gt;어디에서 착오를 겪엇는지&quot;&lt;/b&gt;까지 캐시로 포함하기로했습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;캐시 키 구조 = problem_id(문제번호) + answer_index(사용자 선택 답안)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 특정 선택지를 고른 이유와 그에대한 피드백을 일관되게 재사용 할 수 있고,&lt;br /&gt;캐시의 단위가 문제가 아닌&amp;nbsp; &lt;b&gt;&quot;문제 + 사용자 선택&quot;&lt;/b&gt;이 되며 데이터의 &lt;b&gt;정확도와 활용성을 모두 높일 수 있엇습니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. 성과 : 데이터로 증명한 리퀘스트 최적화&lt;/b&gt;&lt;br /&gt;&lt;span&gt;캐싱 전략 도입 전후로 &lt;b&gt;OpenAI API 호출 횟수&lt;/b&gt;를 기준으로 변화를 추적했습니다.&lt;/span&gt;&lt;br /&gt;&lt;span&gt;아래 그래프는 &lt;b&gt;하루 단위 요청 수 변화&lt;/b&gt;를 나타낸 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;431&quot; data-origin-height=&quot;175&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/r7w5U/dJMcabi0HJU/SaxuWdrS5k5k5sw4Bl7Ekk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/r7w5U/dJMcabi0HJU/SaxuWdrS5k5k5sw4Bl7Ekk/img.png&quot; data-alt=&quot;캐싱 도입 이후 동일 문제 반복 요청이 캐시에서 처리되며 API 호출 수가 급격히 감소한 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/r7w5U/dJMcabi0HJU/SaxuWdrS5k5k5sw4Bl7Ekk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fr7w5U%2FdJMcabi0HJU%2FSaxuWdrS5k5k5sw4Bl7Ekk%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;431&quot; height=&quot;175&quot; data-origin-width=&quot;431&quot; data-origin-height=&quot;175&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;캐싱 도입 이후 동일 문제 반복 요청이 캐시에서 처리되며 API 호출 수가 급격히 감소한 모습&lt;/figcaption&gt;
&lt;/figure&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;b&gt;기존 :&lt;/b&gt; 모든 사용자의 요청이 API 호출로 이어짐(137회)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;이후 :&lt;/b&gt; 동일 문제에 대해 반복 요청을 캐시가 처리(최저 33회)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CBT 서비스 특성상 새로운 기출문제가 추가될 때는 일시적으로 리퀘스트가 증가하지만, &lt;br /&gt;해설 데이터가 축적될수록 다시 수치가 안정화되는 것을 확인할 수 있었습니다. &lt;br /&gt;결과적으로 &lt;b data-index-in-node=&quot;97&quot; data-path-to-node=&quot;7&quot;&gt;전체 평균 40% 이상의 리퀘스트 절감 효과&lt;/b&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;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;마치며...&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 단순히 &lt;b&gt;'해설 잘 나오는 서비스'이며 간단한 CBT였다면&lt;/b&gt; 실제 서비스를 운영하며 &lt;b&gt;사용자의 피드백&lt;/b&gt;을 마주하고 &lt;b&gt;운영 비용을 고민하며&lt;/b&gt; 개발자에게 화려한 기술보다는 &lt;b&gt;&quot;지속 가능한 구조&quot;&lt;/b&gt;를 설계하는 능력이 더 중요하다는걸 깨달았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재는 비용 절감을 통해 확보한 비용으로 &lt;b data-index-in-node=&quot;23&quot; data-path-to-node=&quot;6&quot;&gt;모델의 버전을 업그레이드할 때, 기존 캐시 데이터를 어떻게 효율적으로 갱신할지&lt;/b&gt; 고민하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조만간 이 고민의 결과물과 함께 다음 글 쓰러 오겠습니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로젝트/개발로그</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/37</guid>
      <comments>https://kimbob-world.tistory.com/entry/Core-CBTGPT-API-%EB%B9%84%EC%9A%A9-40-%EC%A0%88%EA%B0%90%ED%95%98%EA%B8%B0-Supabase%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-CBT-%EC%84%9C%EB%B9%84%EC%8A%A4-%EC%BA%90%EC%8B%B1-%EC%A0%84%EB%9E%B5#entry37comment</comments>
      <pubDate>Fri, 27 Feb 2026 02:41:46 +0900</pubDate>
    </item>
    <item>
      <title>[Ai-serbot] 재난 로봇 시스템에서 서버를 중심에 두기로 한 이유</title>
      <link>https://kimbob-world.tistory.com/entry/Ai-serbot%EC%99%9C-%EC%9A%B0%EB%A6%AC%EB%8A%94-%EC%9E%AC%EB%82%9C-%EB%A1%9C%EB%B4%87-%EC%8B%9C%EC%8A%A4%ED%85%9C%EC%9D%84-%E2%80%98%EC%84%9C%EB%B2%84-%EC%A4%91%EC%8B%AC-%EA%B5%AC%EC%A1%B0%EB%A1%9C-%EC%84%A4%EA%B3%84%ED%96%88%EB%8A%94%EA%B0%80</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;프로젝트 진행 목적&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;재난 현장에서 로봇이 먼저 진입할 수 있다면&amp;nbsp; 이후 &quot;구조요원&quot;분들이 좀 더 안전하게 진입 할 수 있지않을까?&lt;br /&gt;그럼 먼저 로봇이 들어가서 데이터 수집하여 관제 센터에 전달한다면&amp;nbsp; 위험요인 및 구조인원을 미리 확인할 수 있겠다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 처음부터 재난 로봇 시스템을 &lt;b&gt;서버 중심 구조&lt;/b&gt;로 설계했습니다.&lt;br /&gt;로봇과 관제는 서로 직접 통신하지 않고, 모든 데이터와 명령은 서버를 통해 흐르도록 하는 것이 전제였습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1207&quot; data-origin-height=&quot;678&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cG6GwS/dJMcacn9Xb1/RXqsXiqBTnUkYxQ2A2keK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cG6GwS/dJMcacn9Xb1/RXqsXiqBTnUkYxQ2A2keK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cG6GwS/dJMcacn9Xb1/RXqsXiqBTnUkYxQ2A2keK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcG6GwS%2FdJMcacn9Xb1%2FRXqsXiqBTnUkYxQ2A2keK1%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;636&quot; height=&quot;357&quot; data-origin-width=&quot;1207&quot; data-origin-height=&quot;678&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Robot&amp;ndash;Server&amp;ndash;Control Center 구조에서, 서버는 모든 데이터와 제어 흐름의 기준점이다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 구조를 선택한 이유는 서버가 센서 데이터를 파싱하고 AI 모델을 연동함으로써 로봇과 관제는 각자의 역할에만 집중할 수 있도록 분리하고 싶었기 때문입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Robot : GUI(관제센터)에서 온 &lt;b&gt;명령을 처리&lt;/b&gt; (이동 , TTS, STT) / 센서 및 영상 프레임을 수집해 서버로 전달&lt;/li&gt;
&lt;li&gt;Server : &lt;b&gt;TCP/IP기반 Socket&lt;/b&gt;으로 유입되는 데이터를 파싱(Json)하고&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 필요한 &lt;b&gt;Ai모델(SLM 기반 상황 요약, YOLO 기반 사람 인식)&lt;/b&gt;을 서버에서 수행하며&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 모든 이벤트와&lt;b&gt; 결과를 DB에 기록&lt;/b&gt; 이후 &lt;b&gt;관제 판단과 사후분석&lt;/b&gt;의 기준점으로 사용&lt;/li&gt;
&lt;li&gt;GUI :&amp;nbsp; 서버로 부터 전달받은 &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-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;개발을 진행하면서 이 전제는 오히려 더 중요해졌다.&lt;br /&gt;&lt;/span&gt;센서 데이터, 상태 이벤트, 영상 프레임 등 서로 다른 크기와 주기의 데이터가 동시에 유입되면서,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot; 어디서 문제가 있어서 데이터가 안오는거지 ? &quot;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot; 데이터가 왜 지연이 될까? &quot;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 문제들이 하나씩 생기기 시작했엇는데&amp;nbsp;&lt;br /&gt;초기에는 Robot - Server - GUI 모두 6000번 단일 소켓을 통해 공유했다. 겉으로 봤을때는 서버를 경유하지만 , 실제로는 모든 송수신이 하나의 채널에 섞여 들어와 &lt;b&gt;&quot;이건 그냥 말이 서버지 중간에 파싱만하고 무슨 차이가 있는거지&quot;&lt;/b&gt; 라는 생각이 들었다.&lt;br /&gt;많은 데이터가 단일포트로 소통되니 데이터 유실 및 지연이 발생했고 어디서 데이터가 문제가 생겼는지 추적하기가 너무 어려웠다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 로봇에서 유입되는 데이터는 센서 값뿐 아니라&lt;b&gt; LiDAR(대용량 2D 배열)&lt;/b&gt;와&lt;b&gt; 영상 프레임(바이너리)&lt;/b&gt;까지 포함하고 있기 때문에&lt;br /&gt;해당 대용량 데이터들이 단일 포트를 점유하고 있으니 뒤에오는 &lt;b&gt;센서데이터는 지연&lt;/b&gt;될 수 밖에 없었고&lt;br /&gt;구조현장에서 제일 중요하다고 생각하는 &lt;b&gt;실시간성&lt;/b&gt;이 무너졌습니다&lt;br /&gt;그리고 로봇 , GUI에서 오는 데이터를 파싱해서 보내주는데 있어서 서로&lt;b&gt; 다른 포맷(JSON/바이너리)&lt;/b&gt;이 같은 채널에 섞여 &lt;b&gt;파싱 경계까지 깨지는 상황&lt;/b&gt;이 발생해 로봇과 GUI(관제)를 포트단위로 나눴습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;6000 : Server &amp;harr; Robot&lt;/b&gt;&lt;br /&gt;&lt;b&gt;6001 : Server &amp;harr; GUI&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 분리를 통해 로봇과 GUI의 혼선은 줄었지만&amp;nbsp;&lt;br /&gt;로봇에서 서버로 유입되는 데이터 자체가 6000번 포트에 집중되면서&lt;b&gt; 데이터 유실문제 및 지연&lt;/b&gt;이 해결되지않았습니다.&lt;br /&gt;로봇에서 전송되는 데이터는 센서 값, LiDAR 2D 맵,영상 데이터 등 서로 &lt;b&gt;크기와 처리 특성이 달랐습니다.&lt;/b&gt;&lt;br /&gt;특히 영상 프레임과 이미지 기반 사람 인식 데이터는&lt;b&gt; 대용량 바이너리 스트림&lt;/b&gt;으로 같은 채널을 사용하는 다른 &lt;b&gt;데이터의 실시간성&lt;/b&gt;을 방해했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 이후 &lt;b&gt;데이터의 성격&lt;/b&gt;에 따라 통신 채널을 추가로 &lt;b&gt;분리&lt;/b&gt;했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;6000 : 센서 및 LiDAR 데이터&lt;/b&gt;&lt;br /&gt;&lt;b&gt;6002 : 영상 프레임 스트림&lt;/b&gt;&lt;br /&gt;&lt;b&gt;6003 : 이미지 기반 사람 인식 바이너리 데이터&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포트를 데이터 타입으로 분리하여 관리하니 &lt;b&gt;역할이 명확&lt;/b&gt;해지고 데이터 파싱 기준과 로그 흐름도 분리할 수 있엇습니다.&lt;br /&gt;그 결과 지연 문제가 줄며 &lt;b&gt;데이터 유실 &lt;/b&gt;및&lt;b&gt; 실시간 정보전달&lt;/b&gt;이 확실해지고&lt;br /&gt;또한 기능을 추가 / 장애 발생 시 , 문제 발생 지점을 채널 단위로 즉시 추적할 수 있어&lt;b&gt; 운영 및 유지보수&lt;/b&gt;가 훨씬 수월해졌습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로젝트/개발로그</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/36</guid>
      <comments>https://kimbob-world.tistory.com/entry/Ai-serbot%EC%99%9C-%EC%9A%B0%EB%A6%AC%EB%8A%94-%EC%9E%AC%EB%82%9C-%EB%A1%9C%EB%B4%87-%EC%8B%9C%EC%8A%A4%ED%85%9C%EC%9D%84-%E2%80%98%EC%84%9C%EB%B2%84-%EC%A4%91%EC%8B%AC-%EA%B5%AC%EC%A1%B0%EB%A1%9C-%EC%84%A4%EA%B3%84%ED%96%88%EB%8A%94%EA%B0%80#entry36comment</comments>
      <pubDate>Sun, 21 Dec 2025 04:35:14 +0900</pubDate>
    </item>
    <item>
      <title>[Next.js] Navigate 방법 및 page path타입 지정</title>
      <link>https://kimbob-world.tistory.com/entry/Nextjs-Navigate-%EB%B0%8F-page-%ED%83%80%EC%9E%85-%EC%A7%80%EC%A0%95</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;Next.js의 페이지 경로는 string이 기본이지만, TypeScript 환경에서 쿼리(?year=2025)를 다루거나 동적 경로를 안전하게 관리하기 위해 &lt;b&gt;UrlObject를 사용하는것이 유리합니다.&lt;/b&gt;타입스크립트에서 페이지를 이동하는 페이지 네비게이션 함수는 대표적으로 두가지가 있다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. &amp;lt;Link href={ pathname }&amp;gt; &amp;lt;/Link&amp;gt;&lt;br /&gt;Link 태그를 통해 href에 pathname을 적어서 하는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. router를 이용한 페이지 이동&lt;/p&gt;
&lt;pre id=&quot;code_1763389949212&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const router = useRouter();

router.push(pathname);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 두가지 태그/함수 중 태그를 사용한 페이지 네비게이션의 경우는 페이지를 미리 로드하는 Prefetching기능을 사용해&lt;br /&gt;&amp;lt;Link href=&quot;/index&quot; /&amp;gt;가 존재한다면 미리 index페이지를 미리 로드해놓는다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;그 외 두가지 네비게이션의 주 사용처는&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1번 Link 태그를 사용하는 경우&lt;/b&gt;&lt;br /&gt;&lt;b&gt;푸터&lt;/b&gt; 혹은&lt;b&gt; 사이드바 링크&lt;/b&gt; 같이 기능없이 즉시 이동되는 경우 a링크 대신 사용하는 태그다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2번 router를 이용한 페이지이동&lt;/b&gt;&lt;br /&gt;로그인 / 회원가입처럼 &lt;b&gt;정보를 받고 검증한 후 페이지를 이동&lt;/b&gt;하는 경우 사용한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래 string 변수도 잘 작동하지만, 쿼리 형태(?year=...)가 포함된 string 변수를 router.push()에 전달할 경우,&lt;br /&gt;&lt;b&gt;TypeScript가 이 변수의 타입을 UrlObject와 혼동하여&lt;/b&gt; 에러를 발생시킬 수 있습니다.&lt;br /&gt;이때 타입을 UrlObject 형태로 명확히 지정해주면 이 문제를 해결할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1128&quot; data-origin-height=&quot;110&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IgrSn/dJMcafdUzF5/K5qrsl6U0vYiHmKFOw7U00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IgrSn/dJMcafdUzF5/K5qrsl6U0vYiHmKFOw7U00/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IgrSn/dJMcafdUzF5/K5qrsl6U0vYiHmKFOw7U00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIgrSn%2FdJMcafdUzF5%2FK5qrsl6U0vYiHmKFOw7U00%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;1128&quot; height=&quot;110&quot; data-origin-width=&quot;1128&quot; data-origin-height=&quot;110&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 타입을 지정해줄때 &lt;b&gt;URLObject형태로 지정&lt;/b&gt;을 해줘야하는데 해당 지정하는 방법을 서술한다.&lt;br /&gt;그리고 object형태로 값을 넣어줄 때는 pathname이 필요하고 거기서 쿼리데이터가 필요하다면 추가로 넣어주는 방법이다.&lt;/p&gt;
&lt;pre id=&quot;code_1763392762827&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import type { UrlObject } from 'next/navigation';

type years = {
    year : number,
    status : string,
    path? : UrlObject ,
    message? : string
};

const yearData : years[] = [
  { year: 2025, status: 'active', path : {pathname : &quot;/intro&quot; ,query : {year : 2025}}},
  { year: 2024, status: 'coming_soon', message: '준비중입니다!' },
  { year: 2023, status: 'active', path: {pathname : &quot;/intro&quot; ,query : {year : 2023}} },
  // { year: 2022, status: 'disabled' } // 나중에 비활성화된 버튼도 쉽게 추가 가능
];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가로 배열에 path(이동할 페이지 위치)가 없는 경우가 있을 수 있는 상황이 있는데&lt;br /&gt;해당 경우에 그대로 &amp;lt;Link href={path} /&amp;gt;를 사용할 경우 path에서 에러가 나는걸 볼 수 있다.&lt;br /&gt;Link 태그에서 path는 무조건 값이 존재 해야하지만 type years에서 path? : UrlObject를 통해 값이 없을 수 있다고 표시했기 때문에&lt;br /&gt;에러가 날 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;842&quot; data-origin-height=&quot;94&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdXdip/dJMcaap8BvH/1P3XWhrK20V4TqWFEGbKm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdXdip/dJMcaap8BvH/1P3XWhrK20V4TqWFEGbKm0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdXdip/dJMcaap8BvH/1P3XWhrK20V4TqWFEGbKm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdXdip%2FdJMcaap8BvH%2F1P3XWhrK20V4TqWFEGbKm0%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;842&quot; height=&quot;94&quot; data-origin-width=&quot;842&quot; data-origin-height=&quot;94&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1763393989275&quot; class=&quot;clojure&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;{yearData.map((item) =&amp;gt; {
    if(item.status == &quot;active&quot;){
        {/* path? 일때는 Link에서 에러가 나기때문에 if문으로 한번 더 확인*/}
        if(item.path){
            return(
                &amp;lt;Link href={item.path}&amp;gt;&amp;lt;/Link&amp;gt;
            )
        }
    }
})}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럴 때 if문을 통해 path의 여부를 미리 확인해 준다면 에러를 사라지게 할 수 있다!&lt;/p&gt;</description>
      <category>프로젝트/개발로그</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/34</guid>
      <comments>https://kimbob-world.tistory.com/entry/Nextjs-Navigate-%EB%B0%8F-page-%ED%83%80%EC%9E%85-%EC%A7%80%EC%A0%95#entry34comment</comments>
      <pubDate>Tue, 18 Nov 2025 01:07:22 +0900</pubDate>
    </item>
    <item>
      <title>[kumamid]외주 졸업작품 웹(JS)을 Next.js로 전환하게 된 이유</title>
      <link>https://kimbob-world.tistory.com/entry/kumamid-%ED%95%9C%EC%98%81%EB%8C%80-%EC%A1%B8%EC%97%85%EC%9E%91%ED%92%88%EC%A0%84-%EC%9B%B9</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;외주로 맡게된 한영대 졸업작품전 웹&lt;/b&gt;&lt;br /&gt;해당프로젝트는 웹빌더(가비아)로 제작된 사이트를 Js로 변환하는 작업을 맡게됐다.&lt;br /&gt;이미 작업된 디자인 시안이 있엇기때문에 1달 반정도에 걸쳐서 웹이 만들어졌고&lt;br /&gt;현재 쓰는 글은 해당 작업 이후 해당웹을 Next js를 이용해TypeScript 및 tainwindCss 적용시키는 과정이다.&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;❓Why? ( 왜 Next.Js로&amp;nbsp; 변경해야 하는가 ? )&lt;/b&gt;&lt;/h2&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;1.&amp;nbsp; 발견된 문제점&lt;/b&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;b&gt;초기 로딩 속도&lt;/b&gt;&lt;br /&gt;고 용량의 사진 및 영상으로 인해 사용자가 들어와서 사진을 보는데 &lt;b&gt;약 2-4초의 초기 로딩시간&lt;/b&gt;이 걸림&lt;br /&gt;(학생 작품을 원본을 최대한 유지해야하는 제약으로 인해 이미지 용량을 kb수준까지 낮추기는 어려운 상황이였습니다.)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;유저의 사용성 저하&lt;br /&gt;&lt;/b&gt;시작화면 비디오의 로드되기까지 딜레이로 인해 &lt;b&gt;사용자가 콘텐츠를 보기 전에&amp;nbsp; 이탈하는 사례&lt;/b&gt;가 있었고,&lt;br /&gt;로딩 스피너를 통해 사진 로딩시간에 대해 임시 조치를 해뒀지만 사진 &lt;b&gt;로딩시간에대한 근본적인 사용자 경험(UX)저하&lt;/b&gt;를 막을 수 없었습니다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;유지 보수의 어려움&lt;br /&gt;일부 애니메이션 및 css를 수정하려고 했으나 애니메이션 / 기존 레이아웃 / 모바일 반응형 처리 등으로 인해&lt;br /&gt;Css하나에 결합도가 너무 높아 특정 스타일을 찾고 수정하는데 시간이 너무 오래걸렸습니다.&amp;nbsp;&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;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.&amp;nbsp; 문제 해결을 위한 기술을 도입(Next.Js)&lt;/b&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;b&gt;(Next.js) SSR을 통한 로딩 속도 개선&lt;/b&gt; &lt;br /&gt;SSR을 도입해 초기 레이아웃 렌더링 속도를 높이고, 고용량 리소스를 &lt;b data-index-in-node=&quot;39&quot; data-path-to-node=&quot;3&quot;&gt;표시 크기에 맞춘 썸네일 기반 로딩&lt;/b&gt;으로 개선했습니다. 이를 통해 로딩 시간을 &lt;b data-index-in-node=&quot;75&quot; data-path-to-node=&quot;3&quot;&gt;기존 2~4초 -&amp;gt; 1초대로 단축&lt;/b&gt;하며 체감 성능을 극대화했습니다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;(TypeScript) 데이터 안정성&lt;br /&gt;&lt;/b&gt; Firebase에서 가져오는 학번, 나이, 사진 등 중요한 학생 데이터를 &lt;b&gt;TypeScript&lt;/b&gt;로 체계화했습니다. &lt;br /&gt;이를 통해 데이터 추가/수정 시 발생할 수 있는 &lt;b&gt;오류를 사전에 방지하여 안정성을 높였습니다.&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;(Tailwind CSS) 유지보수성 향상&lt;br /&gt;유지보수&lt;/b&gt; 문제를 해결하기 위해 스타일링 방식을 분리했습니다.&lt;br /&gt;반응형 UI와 기본 스타일은 &lt;b&gt;Tailwind&lt;/b&gt;로 빠르게 관리하고, 복잡한 애니메이션 로직은 &lt;b&gt;일반 CSS 파일로 분리&lt;/b&gt;하여&lt;br /&gt;코드의 &lt;b&gt;유지보수성을 높였습니다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;해당 3가지의 장점을 모두 가질 수 있는 NextJs로 변경하게 되었습니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로젝트/개발로그</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/33</guid>
      <comments>https://kimbob-world.tistory.com/entry/kumamid-%ED%95%9C%EC%98%81%EB%8C%80-%EC%A1%B8%EC%97%85%EC%9E%91%ED%92%88%EC%A0%84-%EC%9B%B9#entry33comment</comments>
      <pubDate>Mon, 17 Nov 2025 20:57:06 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 알고리즘 해설 정리본(해설만 정리해둠)</title>
      <link>https://kimbob-world.tistory.com/entry/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-2%EC%A3%BC%EB%82%A8%EC%9D%80%EB%8F%99%EC%95%88-%EB%B9%A0%EB%A5%B8%EC%A0%95%EB%A6%AC</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;열심히 푼 문제들 하나씩 해설만 정리해두고 마지막날에 해설보면서 한번씩 쫙 풀어보자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PCCP 1번 기출문제 동영상 재생기&lt;br /&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/340213&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/340213&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;비디오&amp;nbsp;전체길이&amp;nbsp;와&amp;nbsp;현재&amp;nbsp;재생시점이&amp;nbsp;주어지고 &lt;br /&gt;오프닝&amp;nbsp;시작과&amp;nbsp;끝이&amp;nbsp;정해진다 &lt;br /&gt;커맨드에&amp;nbsp;next와&amp;nbsp;prev형태로&amp;nbsp;들어와서&amp;nbsp;+-10초를&amp;nbsp;했을때 &lt;br /&gt;마지막&amp;nbsp;시간결과는&amp;nbsp;몇시에&amp;nbsp;나오나? &lt;br /&gt;오프닝&amp;nbsp;시작과&amp;nbsp;엔드사이에&amp;nbsp;시간이&amp;nbsp;걸쳐있으면&amp;nbsp;end로&amp;nbsp;시간을&amp;nbsp;이동해준다. &lt;br /&gt;&lt;br /&gt;마지막에&amp;nbsp;초를&amp;nbsp;분과&amp;nbsp;초로&amp;nbsp;다시나누어&amp;nbsp;글자에&amp;nbsp;넣어준다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PCCP 1-3 유전 문제&lt;br /&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/15008/lessons/121685&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/15008/lessons/121685&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 분할정복을 통해서 부모(1세대)를 찾아가기&lt;br /&gt;2. 필수법칙 RR의 자식은 ''RR'' rr의 자식또한 &quot;rr&quot;&lt;br /&gt;3. 만약 Rr이라면 남은몫값을 통해 몇번째 자식인지 확인(RR , Rr , Rr , rr)중 남은값 확인&lt;br /&gt;4. 이전 값(n,p)를 각자에서 기억하고 있으면서 부모(Rr)에서 내려오며 현재 자신이 몇번쨰값인지 체크하기&lt;br /&gt;5. 본인의 값은 (n,p)재귀를 통해 본인이 가지고있으며 Rr일때 %4를 통해서 자신이 몇번쨰 Rr의 자식인지 체크하여 내려가기&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PCCP 1-4 운영 체제&lt;br /&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/15008/lessons/121686&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/15008/lessons/121686&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 먼저 정렬을 통해 들어오는 시간별로 정렬을해준다(정렬시간이 같다면 점수별로)&lt;br /&gt;2. 이후 해당백터배열을 받을 우선순위큐를 선언해준다(실행시간 우선순위는 낮아서 정렬에서 밀렸지만 첫번쨰 값 실행시간(5s)보다&lt;br /&gt;시작시간이 낮은 값들 중 점수가 낮아 우선순위가 높다면 먼저 사용되야함.)&lt;br /&gt;3. 대기큐가 비어있으면서 다음접근해야할 배열[i]의 실행시작시간보다 짧다면 현재시간을 실행시작시간으로 JumP&lt;br /&gt;4. 아직 대기큐에 입장하기 않은 큐중에서 현재시간보다 낮은 시작시간을 가진 값을 모두 넣어주기&lt;br /&gt;5. 큐에 값이 있다면 가장 우선순위가 낮은값을 배열에서 하나씩 빼면서 계산해준다!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;BFS&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단어 변환 Lv2&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 큐에는 현재 스트링이 몇레벨인지 체크해준다.&lt;br /&gt;2. 현재 begin을 Words에서 같은글자가 하나인것만 찾아서 큐에 넣어주기&lt;br /&gt;3. 찾은 인덱스는 이미 찾았던값이다라는 visited[인덱스] 를통해 다녀온값 확인해주기&lt;br /&gt;4. 1개 2개 차례차레 넣고 배면서 현재가 몇단게 레벨의 노드인지 확인해주기&lt;/p&gt;</description>
      <category>알고리즘</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/32</guid>
      <comments>https://kimbob-world.tistory.com/entry/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-2%EC%A3%BC%EB%82%A8%EC%9D%80%EB%8F%99%EC%95%88-%EB%B9%A0%EB%A5%B8%EC%A0%95%EB%A6%AC#entry32comment</comments>
      <pubDate>Thu, 6 Nov 2025 00:15:46 +0900</pubDate>
    </item>
    <item>
      <title>[JAVA]일반클래스 , 추상클래스 , 인터페이스의 차이는?</title>
      <link>https://kimbob-world.tistory.com/entry/JAVA%EC%9D%BC%EB%B0%98%ED%81%B4%EB%9E%98%EC%8A%A4-%EC%B6%94%EC%83%81%ED%81%B4%EB%9E%98%EC%8A%A4-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4%EC%9D%98-%EC%B0%A8%EC%9D%B4%EB%8A%94</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;일반 클래스가 완벽한 설계도라면 추상클래스는 미완성된 설계도입니다.&lt;br /&gt;일반클래스는 완벽히 설계되어있기때문에 메인클래스 내에서 인스턴스화하여 값을 불러서 사용할 수 있지만&lt;br /&gt;미완성 설계도인 추상클래스는 멤버변수 혹은 메소드를 가질 수 있고 생성자 메서드 또한 가질 수 있지만&amp;nbsp; 객체화 할 수 없습니다.&lt;br /&gt;그리고 abstract를 메서드 명 앞에 붙인다면&amp;nbsp;&lt;br /&gt;해당 추상클래스를 상속받는 자식클래스라면 무조건 가지고있어야할 공용메소드를 오버라이딩해서 사용해야합니다&lt;br /&gt;인터페이스는 다중상속을 위해 사용되는 구조입니다&lt;br /&gt;인터페이스 내부에 구현코드를 작성할 수 없고 상수(static final)와 구현코드없는 메소드로 이루어져있습니다.&lt;br /&gt;implements를 통해 다양한 인터페이스를 다중상속 할 수 있고 대신 인터페이스 내의 메서드를 모두 오버라이딩해서 사용해야합니다.&lt;br /&gt;(Java 8부터는 default를 사용해서 안할 수 있다고하네용)&lt;/p&gt;</description>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/31</guid>
      <comments>https://kimbob-world.tistory.com/entry/JAVA%EC%9D%BC%EB%B0%98%ED%81%B4%EB%9E%98%EC%8A%A4-%EC%B6%94%EC%83%81%ED%81%B4%EB%9E%98%EC%8A%A4-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4%EC%9D%98-%EC%B0%A8%EC%9D%B4%EB%8A%94#entry31comment</comments>
      <pubDate>Wed, 5 Nov 2025 12:56:40 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스]Lv2 피로도 c++ 문제풀이 /  백트레킹(backtraking)</title>
      <link>https://kimbob-world.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4Lv2-%ED%94%BC%EB%A1%9C%EB%8F%84-c-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4-%EB%B0%B1%ED%8A%B8%EB%A0%88%ED%82%B9backtraking</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;피로도&lt;/b&gt;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/87946&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/87946&lt;/a&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;figure id=&quot;og_1762229104089&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프로그래머스&quot; data-og-description=&quot;SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/87946&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cUMDFE/hyZNbzMgFi/xV2RVuE8fviTRYSGLHjiEK/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/Ad4tB/hyZNeccq3X/gM3221ftxOkqs0CdW667Y0/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/87946&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/87946&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cUMDFE/hyZNbzMgFi/xV2RVuE8fviTRYSGLHjiEK/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/Ad4tB/hyZNeccq3X/gM3221ftxOkqs0CdW667Y0/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960');&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;프로그래머스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;1206&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/x7Wlg/dJMcaboXVSu/2UDX2tb3Dql4AoK6EAPVyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/x7Wlg/dJMcaboXVSu/2UDX2tb3Dql4AoK6EAPVyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/x7Wlg/dJMcaboXVSu/2UDX2tb3Dql4AoK6EAPVyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fx7Wlg%2FdJMcaboXVSu%2F2UDX2tb3Dql4AoK6EAPVyK%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;1102&quot; height=&quot;1206&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;1206&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&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;b&gt;문제 해석&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;완전 탐색 문제로 총 피로도 K값이 있을때 어떻게 돌아야 효율적으로 던전을 돌 수 있을까?&lt;br /&gt;가장 효율적으로 던전을 돌았을때 몇개의 던전을 돌 수 있는지 확인하고 값을 Return하세요&lt;br /&gt;해당문제는 순열탐색으로 모든값을 돌아보고 체크할 수도 있고 백트레킹 기법을 통해 하나씩 돌아보며 필요하지않은경우(남은 피로도가 없는경우) 순열을 돌지않는 방법이 필요하다.&lt;br /&gt;해당문제는 던전 수가 8개로 순열탐색으로 해도 시간초과 에러가 나지않지만 케이스가&amp;nbsp; 더 늘어난다면 O(N!)를 가진 순열탐색은 시간초과가 날 수 밖에없다&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1762229547383&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;

using namespace std;
int answer =0;

//visited는 지역변수가 아닌 주소값 참조를 통한 전역변수화 해주기 -&amp;gt; 수가 계속 변하고 해당 수에 따라서 값이 달라짐
void bt(int result , vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; dgn , vector&amp;lt;bool&amp;gt;&amp;amp; visit , int count){
    
    for(int i=0;i&amp;lt;dgn.size();i++){
        if(result &amp;gt;= dgn[i][0] &amp;amp;&amp;amp; visit[i] == false){
            result -= dgn[i][1];
            count++;
            visit[i] = true; // 다음 값에서는 i을 포함시키지 말고 돌아!
            bt(result , dgn , visit,count);
            //해당 재귀가 종료된 후 값을 되돌려 다른 반복문에도 돌 수 있도록 만들기
            result+= dgn[i][1];
            count--;
            visit[i] = false;
        }
    }
    answer = answer &amp;lt;= count ? count : answer;
    return;
}

int solution(int k, vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; dungeons) {
    answer = 0;
    
    vector&amp;lt;bool&amp;gt; visited(dungeons.size()+1,false);
    
    //총 값 , 던전 , 방문여부 , 카운트
    bt(k,dungeons,visited,0);
    
    return answer;
}&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;1. 해당 던전에 방문여부를 확인하기 위해 bool타입의 visited를 선언해준다.&lt;br /&gt;2. bk라는 백트레킹 함수에 총 피로도 , 던전 , 방문여부 , 던전 몇개를 입장했는지에대한 count(초기값 0)를 보낸다.&lt;br /&gt;3. 파라미터로 값을 받을때 visited(방문여부)는 주소값으로 보내야한다.&lt;br /&gt;==&amp;gt; 그렇지 않으면 visited가 지역변수로 처리되어서 이전에 저장한 visited[i]=true | false 값이 제대로 전달되지 않는다.&lt;br /&gt;4. 반복문을 통해 모든 던전들을 돌면서 던전의 입장피로도를 초과하면서 이전에 입장하지 않은 던전이라면 입장처리해준다.&lt;br /&gt;==&amp;gt; if(result &amp;gt;= dgn[i][0] &amp;amp;&amp;amp; visited[i] == false)&lt;br /&gt;5. 입장을 하면 던전에 입장횟수(count++)를 증가 시키고 , 해당 피로도만큼 result(총 값)에서 빼주고 visited[i](방문값) 또한 true로 변환&lt;br /&gt;6. 이후 다음 for문을 돌면서 방금 입장한 visited[i]=true로 변환했기때문에 해당 피로도와 카운트를 추가하며 입장가능한 피로도를 가지고있다면 계속 탐색한다.&lt;br /&gt;7. 모두 탐색 한 뒤 지금까지 던전을 돌은 횟수 count를 answer에 넣어주고 최대값을 계속 갱신해준다.(삼항연산자)&lt;br /&gt;8. 이후 return&lt;br /&gt;9. 그렇다면 재귀 이후에 방문여부 , count -- , result += dgn[i] 를 통해 피로도 , 카운트 , 방문여부를 초기화 해 다음 던전을 이동 할 수 있게 만들어준다.&lt;br /&gt;10. 그렇게 answer에서는 계속 최대값이 갱신되기때문에 백트레킹을 마친 뒤 answer을 return해주면 끝난다&lt;/p&gt;</description>
      <category>알고리즘</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/30</guid>
      <comments>https://kimbob-world.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4Lv2-%ED%94%BC%EB%A1%9C%EB%8F%84-c-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4-%EB%B0%B1%ED%8A%B8%EB%A0%88%ED%82%B9backtraking#entry30comment</comments>
      <pubDate>Tue, 4 Nov 2025 13:27:18 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스]Lv2 모음사전 C++ 문제풀이</title>
      <link>https://kimbob-world.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4Lv2-%EB%AA%A8%EC%9D%8C%EC%82%AC%EC%A0%84-C-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/84512&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/84512&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1761980278888&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프로그래머스&quot; data-og-description=&quot;SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/84512&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/vYczR/hyZMOeh0aK/V0gPBOk1AKh8ZLAkcMFMyk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/bUYkMZ/hyZMNl7VZp/pefhunaDe6xzePNeem0hp0/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/84512&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/84512&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/vYczR/hyZMOeh0aK/V0gPBOk1AKh8ZLAkcMFMyk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/bUYkMZ/hyZMNl7VZp/pefhunaDe6xzePNeem0hp0/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960');&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;프로그래머스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;727&quot; data-origin-height=&quot;690&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAB0nf/dJMcafLEHFh/8oOTWdbCTaUr9hUUgnvPGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAB0nf/dJMcafLEHFh/8oOTWdbCTaUr9hUUgnvPGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAB0nf/dJMcafLEHFh/8oOTWdbCTaUr9hUUgnvPGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAB0nf%2FdJMcafLEHFh%2F8oOTWdbCTaUr9hUUgnvPGk%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;727&quot; height=&quot;690&quot; data-origin-width=&quot;727&quot; data-origin-height=&quot;690&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&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;[&quot;A&quot;,&quot;E&quot;,&quot;I&quot;,&quot;O&quot;,&quot;U&quot;] 라는 순서를가진 백과사전에서 특정 단어의 순서(인덱스)를 찾는 문제&lt;br /&gt;최대 길이는 5글자이기때문에 재귀를 활용한 백트레킹을 사용해 문제를 풀어냈다.&lt;br /&gt;ex) &quot;AAAAA&quot;라는 글자가 들어온다면 return하고 반복문을 통해 해당배열에 글자를 하나씩 넣어 5글자를 만들어본다.&lt;br /&gt;=&amp;gt; &quot;AAAAE&quot;,&quot;AAAAI&quot;,&quot;AAAAO&quot;,&quot;AAAAU&quot;&lt;br /&gt;해당 방식을통해 &quot;A&quot;부터 &quot;UUUUU&quot;까지 모든 경우의 수를 비교하고 cnt라는 변수를통해 인덱스값을 기억하고&lt;br /&gt;값을 찾으면 return cnt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;내 코드&lt;/h2&gt;
&lt;pre id=&quot;code_1761983073128&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;

using namespace std;
int cnt=0;
int answer=0;

void dfs(string rs,string words){
    
    string lt[] = {&quot;A&quot;,&quot;E&quot;,&quot;I&quot;,&quot;O&quot;,&quot;U&quot;};
    string result;
    
    if(rs == words){
        answer=cnt;
        return;
    }
    if(rs.length() == 5){
        return;
    }
    
    for(int i=0;i&amp;lt;5;i++){
        result= rs + lt[i];
        cnt++;
        dfs(result, words);
    }
}

int solution(string word) {
    
    dfs(&quot;&quot;,word);
    
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DFS함수를 통해 재귀를 구현하고 for문을통해 모든 인덱스 값을 백트레킹을 활용해 값을넣어준다.&lt;br /&gt;해당값이 word(정답)과 일치하면 break;&lt;br /&gt;글자 수가 5글자라면 return을 통해 백트레킹을 실행&lt;br /&gt;ex) &quot;AAAAA&quot;라면 &quot;AAAA&quot;로 돌아가서 for문 실행 &quot;AAAAE&quot; =&amp;gt; 5글자 이상이니 &quot;AAAAI&quot; 실행&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;다른 분들의 좋은 코드&lt;/h2&gt;
&lt;pre id=&quot;code_1761984494621&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;assert.h&amp;gt;
#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;

using namespace std;

int solution(string word)
{
    const int weights[5] = { 781, 156, 31, 6, 1 };
    int answer = 0;
    for (int i = 0; i &amp;lt; word.length(); ++i)
    {
        int current;
        switch (word[i])
        {
        case 'A':
            current = 0;
            break;
        case 'E':
            current = 1;
            break;
        case 'I':
            current = 2;
            break;
        case 'O':
            current = 3;
            break;
        case 'U':
            current = 4;
            break;
        default:
            assert(false);
        }
        ++answer;
        answer += current * weights[i];
    }
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당코드는 생각은 했지만 풀지못했던 방법이였다.&lt;br /&gt;분명 숫자들 사이에 규칙이 있을꺼라 생각했고 5의^n승 이라는 방법을 들었지만 내가 이해하지못해서 풀지못했다.&lt;br /&gt;하지만 코드를 보고나서 이해가 됐엇다.&lt;br /&gt;각 자릿수별 가중치를 미리정해놓고(781,156,31,6,1) 해당 글자수만큼 for문을돌려 모든자리값의 가중치를 더해준다.&lt;br /&gt;=&amp;gt; 가중치 계산법 같은경우는 자릿수별 계산 (5^4 + 5^3 + 5^2 + 5^1 + 5^0 ) + word의 글자 수 ) 을 통해 계산함.&lt;br /&gt;쌍따봉 두개..!&lt;/p&gt;</description>
      <category>알고리즘/C++</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/29</guid>
      <comments>https://kimbob-world.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4Lv2-%EB%AA%A8%EC%9D%8C%EC%82%AC%EC%A0%84-C-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4#entry29comment</comments>
      <pubDate>Sat, 1 Nov 2025 19:03:28 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스]Lv2 전력망 둘로 나누기 C++ 문제풀이</title>
      <link>https://kimbob-world.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4Lv2-%EC%A0%84%EB%A0%A5%EB%A7%9D-%EB%91%98%EB%A1%9C-%EB%82%98%EB%88%84%EA%B8%B0-C-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/86971&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/86971&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;전력망 둘로 나누기&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;730&quot; data-origin-height=&quot;630&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uj3xH/dJMb9MJF23N/k2n3vEWE6yAiKRAOItrvC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uj3xH/dJMb9MJF23N/k2n3vEWE6yAiKRAOItrvC0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uj3xH/dJMb9MJF23N/k2n3vEWE6yAiKRAOItrvC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fuj3xH%2FdJMb9MJF23N%2Fk2n3vEWE6yAiKRAOItrvC0%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;730&quot; height=&quot;630&quot; data-origin-width=&quot;730&quot; data-origin-height=&quot;630&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 풀이&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1부터 N까지 트리구조로 이루어진&amp;nbsp; 노드와 노드를 이어주는 전선(wires)가 존재한다.&lt;br /&gt;전선(wires)들 중 하나를 끊어서&amp;nbsp; &lt;b&gt;A,B&lt;/b&gt; 각 노드들의 갯수를 비슷하게 만들려고 한다면&lt;br /&gt;예시로 주어진 wires중 어떤 값을 잘라야 가장 노드 수가 비슷하게 나오는지 찾고 &lt;b&gt;A - B 두 값의 차이&lt;/b&gt;를 리턴하시오!&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1761397629177&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;queue&amp;gt;
#include &amp;lt;cmath&amp;gt;

using namespace std;

int dfs_wire(int n ,const vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt;&amp;amp; adj){
    
    //1번부터 N번까지 해당 값 여부 체크
    //큐를통해 이미 들어간 값은 제거하기 위해 사용
    vector&amp;lt;bool&amp;gt; visited(n+1,false);    
    queue&amp;lt;int&amp;gt; qe;
    
    qe.push(1);
    visited[1] = true;
    
    int count = 0;
    
    while(!qe.empty()){
        int curr = qe.front();
        qe.pop();
        
        count++; // 방문한 노드
        
        // 큐의 front값과 연결된 이웃값 true로 변환
        for(int x : adj[curr]){
            if(visited[x] == false){
                visited[x] = true;
                qe.push(x); 
            }
        }
    }
    //해당 카운트 반환
    return count;
}

int solution(int n, vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; wires) {
    
    //최소값을 찾기위해 최대 100이하 보다 1높은 101
    int answer = 101;
    
    for(int i=0;i&amp;lt;wires.size();i++){
        // 통신을 끊을 값을 제외한 나머지 수를 저장하기위한 백터 선언
        vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; adj(n+1);
        
        for(int j=0;j&amp;lt;wires.size();j++){
            //끊기로 한 전선이라면 넘어가기
            if(i == j ) {  continue; }
            
            int node1 = wires[j][0];
            int node2 = wires[j][1];
            adj[node1].push_back(node2);
            adj[node2].push_back(node1);
        }
        //최대값 n과 통신을 끊은 값을 제외한 값들을 보냄
        int count = dfs_wire(n,adj);
        //절대값을 찾기위해 abs를 사용
        // 현재인원 -   ( 전체 수 - 현재인원 = 다른 노드 연결 값 ) 을 통해 차이를 가져오기
        int diff = abs(count - (n - count));
        
        //가장 낮은 값 넣어주기
        answer = answer &amp;lt; diff ? answer : diff;
    }
    
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;answer&amp;nbsp; (최종 값)의 최대값은 n&amp;lt;=100 임으로 나올 수 있는 최대값 101 넣어주기&lt;/li&gt;
&lt;li&gt;for문을 통해 통신을 끊을 값을 제외한 나머지 수를 저장하기위해 백터 선언
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;백터같은 경우는 adj[n+1]을 추천하지않는다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;배열의 사이즈를 선언할때 array[]를 사용해서 선언할때는 &lt;b&gt;상수&lt;/b&gt;를 넣어줘야하지만&lt;br /&gt;우리는 n이라는 입력값을 받아와서 사용하기 때문에 &lt;b&gt;n+1(생성자 constuctor)&lt;/b&gt;을 사용해서 유동적인 변화에 따른 사이즈를 선언해준다.&lt;/li&gt;
&lt;li&gt;만약 []를 통해 사용한다면 입력받기 전에 배열의 길이를 할당하려고 하기때문에 에러가 날 수 있음!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;for문을 하나 더 생성해 wires에서 i번째 노드를 제외한 값들을 백터에 넣어준다.
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;adj[node1].push_back(node2);&lt;br /&gt;adj[node2].push_back(node1);&lt;br /&gt;&lt;/b&gt;왜 값을 교차로 넣어주나요?
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;해당 전선의 연결점을 만들어주는 역할을 해줌&lt;/li&gt;
&lt;li&gt;1번노드에 2번노드를 연결하고 2번 노드에 1번노드를 같이 연결&lt;/li&gt;
&lt;li&gt;각 노드에 연결된 번호들을 모두 추가해주기 위해 사용함.(key value 개념)&lt;/li&gt;
&lt;li&gt;이를 통해 각 노드에 연결되어있는 항목 및 숫자 들을 알 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;dfs_wire(n,adj)를 통해 &lt;b&gt;배열크기를 지정해줄 N&lt;/b&gt; , 해당 wires에서 &lt;b&gt;i값을 제외한 나머지 연결된 노드 값 adj&lt;/b&gt;를&amp;nbsp;보내준다.&lt;/li&gt;
&lt;li&gt;각 노드들의 연결된 값 및 갯수를 파악할 &lt;b&gt;count &lt;/b&gt;가져온 노드에서 중복값을 삭제하기위한 변수 &lt;b&gt;visited를&lt;/b&gt; 선언해준다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;1번부터 트리구조로 이어져있기때문에 &lt;b&gt;큐&lt;/b&gt;에 &lt;b&gt;1&lt;/b&gt;을 넣어주고 해당값 &lt;b&gt;true&lt;/b&gt;로 변환
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;만약 1번이끊어져있다면 1을 pop()하고 해당 1번과 이웃이 없다면&amp;nbsp;&lt;/li&gt;
&lt;li&gt;다음 큐에 넣을 값이 없기때문에 count 1을 하고 return 해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;while문을 이용해서 큐에서 하나씩 값을 빼며 count++(본인 포함 연결된 노드 수를 찾기위한 변수)를 실행한다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;내부에서 for문을 실행해 해당 값 &lt;b&gt;( 처음 기준 1 )&lt;/b&gt;과 연결된 숫자를 큐에 넣어준다&lt;/li&gt;
&lt;li&gt;해당 숫자들의 중복을 체크하기위해 이미 넣은값은 visitied[x]를 통해 true로 변경&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;반복문을 통해 해당 숫자와 연결된 갯수(queue)만큼 반복문을 돌려 노드 수를 확인 후 리턴
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해당 값 - (전체 수 - 해당값)을 통해서 두 수의 차이를 반환해준다.&lt;/li&gt;
&lt;li&gt;값에 상관없이 (절대값+,-) 양수를 받아야하기때문에 &lt;b&gt;abs&lt;/b&gt;를 사용해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이전에 나온 차이값과 현재 값을 비교해서 더 작은 수를 리턴한다.&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>알고리즘/C++</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/28</guid>
      <comments>https://kimbob-world.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4Lv2-%EC%A0%84%EB%A0%A5%EB%A7%9D-%EB%91%98%EB%A1%9C-%EB%82%98%EB%88%84%EA%B8%B0-C-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4#entry28comment</comments>
      <pubDate>Sat, 25 Oct 2025 22:47:50 +0900</pubDate>
    </item>
    <item>
      <title>[자료구조]정렬(Sorting) 알고리즘</title>
      <link>https://kimbob-world.tistory.com/entry/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0%EC%A0%95%EB%A0%ACSorting-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%9D%B4%EB%9E%80</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;정렬 알고리즘이란?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력된 값을 오름차순(낮은 값부터 높은 값까지 순서대로 정렬) 또는 내림차순 형태에 따라 재배열하는 형태의 알고리즘&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;알고리즘의 종류&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 버블 정렬 (Bubble Sort)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 선택 정렬 (Selection Sort)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 삽입 정렬 (Insertion Sort)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 퀵 정렬 (Quick Sort)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 병합 정렬 (Merge Sort)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. &lt;b&gt;버블 정렬 (Bubble Sort)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;서로&amp;nbsp;인접한&amp;nbsp;두&amp;nbsp;값을&amp;nbsp;비교하여&amp;nbsp;자리를&amp;nbsp;바꾸는&amp;nbsp;방식으로 &lt;br /&gt;가장 큰값이 배열의 오른쪽으로 이동하여 값을 사용자가 지정한 차순에따라 정렬하는 알고리즘&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;int main(){
    int numbers[] = {5,1,2,4,3}; //정렬 해줄 값
    int arrsize = sizeof(numbers) / sizeof(numbers[0]);

    for(int i=0;i&amp;lt;arrsize - 1;i++){ //배열 값&amp;sup2;만큼 반복문
        for(int j=0;j&amp;lt;(arrsize -i)-1 ; i++){
            if(numbers[j] &amp;lt; numbers[j]+1){ //현재 값이 다음배열에 값보다 높다면 위치 교환
                int temp = numbers[j];
                numbers[j] = numbers[j+1];
                numbers[j+1] = temp;
        }
    }

}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;현재&amp;nbsp;배열의&amp;nbsp;값이&amp;nbsp;우측에&amp;nbsp;있는&amp;nbsp;값보다&amp;nbsp;크다면&amp;nbsp;?&amp;nbsp;배열의&amp;nbsp;위치를&amp;nbsp;서로&amp;nbsp;변경해주기 &lt;br /&gt;해당&amp;nbsp;코드를&amp;nbsp;통해&amp;nbsp;높은&amp;nbsp;값을&amp;nbsp;맨&amp;nbsp;오른쪽에&amp;nbsp;하나씩&amp;nbsp;쌓으면서&amp;nbsp;반복문&amp;nbsp;횟수를&amp;nbsp;줄여준다. &lt;br /&gt;i가&amp;nbsp;0일&amp;nbsp;때&amp;nbsp;반복문&amp;nbsp;{5,1,2,4,3}&amp;nbsp;-&amp;gt;&amp;nbsp;5와&amp;nbsp;1을&amp;nbsp;비교&amp;nbsp;변경&amp;nbsp;-&amp;gt;&amp;nbsp;{1,5,2,4,3}&amp;nbsp;-&amp;gt;&amp;nbsp;5와&amp;nbsp;2를&amp;nbsp;비교&amp;nbsp;-&amp;gt;&amp;nbsp;{1,2,5,4,3}&amp;nbsp;.....&amp;nbsp;-&amp;gt;&amp;nbsp;{1,2,4,3,5} &lt;br /&gt;해당&amp;nbsp;반복문을&amp;nbsp;통해&amp;nbsp;배열의&amp;nbsp;수&amp;nbsp;만큼&amp;nbsp;반복문을&amp;nbsp;돌려서&amp;nbsp;{1,2,3,4,5}를&amp;nbsp;만든다.&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ef6f53;&quot;&gt;&lt;b&gt;시간 복잡도의 경우는 완전히 배열히 1,2,3,4,5로 되어있을 경우 O(n) 최악 O(n&amp;sup2;)이다.&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. &lt;b&gt;선택 정렬 (Selection Sort)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;선택&amp;nbsp;정렬은&amp;nbsp;들어갈&amp;nbsp;배열에서&amp;nbsp;현재&amp;nbsp;값이&amp;nbsp;들어갈&amp;nbsp;위치에&amp;nbsp;데이터를&amp;nbsp;넣어준다 &lt;br /&gt;가장 큰/작은 값을 0번째 주소값부터 시작해서 차례대로 넣어준다.&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;int numbers[] = {5,1,2,4,3}; //값

for(int i=0;i&amp;lt;numbers.length() - 1;j++){
    int min= i;
    int temp=0;
    int arrsize = sizeof(numbers) / sizeof(numbers[0]);

    for(int j=i+1;j&amp;lt;arrsize;j++){
        //만약 더 작은 값이면 그 위치를 새로운 최소값으로 변환
        if(numbers[j] &amp;lt; numbers[min]){
            min = j;
        }
    }
    //i에있던 위치 값과 min을 통해 들어온위치값을 서로 변경해준다.
    temp = numbers[i];
    numbers[i] = numbers[min];
    numbers[min] = temp;
}&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;오름차순&amp;nbsp;기준&amp;nbsp;현재값보다&amp;nbsp;낮은값이&amp;nbsp;확인되면&amp;nbsp;해당&amp;nbsp;자리(min)과&amp;nbsp;해당인덱스(i)와&amp;nbsp;위치를&amp;nbsp;변경해준다.&lt;/b&gt;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ef6f53;&quot;&gt;&lt;b&gt;선택 정렬의 시간복잡도는 아직 정렬되지 않은 전체 배열을 확인하여 가장 작은 /큰 값을 가져와 맞는 인덱스에 넣어주기 때문에 O(n&amp;sup2;)이다.&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style1&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. 삽입 정렬 (Insertion Sort)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;삽입&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;값이 &lt;br /&gt;더 작다면 기존 정렬된 배열을 한칸씩 미뤄서 정렬하는 알고리즘&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;    int numbers[] = {5,1,2,4,3}; //값
    //1번 인덱스부터 시작함 0번째값은 이미 정렬된것으로 간주
    int arrsize = sizeof(numbers) / sizeof(numbers[0]);
    for(int i=1;i&amp;lt;arrsize - 1;i++){
        //정렬할 값을 key에 저장하기 
        int key = numbers[i];
        int j= i-1;

       // key를 이미 정렬된 numbers[0]부터 numbers[j]까지 확인
       // 해당 코드를 통해 들어갈 위치를 확인 하여 넣어준다.
       // j가 0보다 크면서 numbers[j]가 key보다 크다면 반복 
       while(j&amp;gt;= 0 &amp;amp;&amp;amp; numbers[j] &amp;gt; key){
            numbers[j+1] = numbers[j];
            j= j-1;
        }
        // 찾은 위치에 정렬할 값(key)를 삽입
        numbers[j+1] = key;
    }&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;while을 통해 j가 1 이상이고 내 앞에 있는 키값(i-1)이 현재 값보다 크다면&lt;br /&gt;키값 공간을 위해 기존값을 오른쪽으로 한칸 씩 미루고&lt;br /&gt;반복문이 끝나고 해당 Key값을 해당 인덱스 위치에 넣어준다.&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ef6f53;&quot;&gt;&lt;b&gt;시간복잡도는 평균적으로 값은 중간에 삽입되지만 최악의 경우O(n&amp;sup2;) 보다는 적지만 BIG-O 표기법 상 최고차항을 생각하면 O(n&amp;sup2;)이다.&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. 퀵 정렬 (Quick Sort)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;분할정복이라는&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;방식 &lt;br /&gt;피벗(pivot)이라는&amp;nbsp;기준점을&amp;nbsp;이용해&amp;nbsp;전체&amp;nbsp;그룹을&amp;nbsp;두&amp;nbsp;그룹으로&amp;nbsp;나누어&amp;nbsp;정렬하는&amp;nbsp;방식 &lt;br /&gt;B(피벗)라는&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;B(피벗)을만들어&amp;nbsp;정렬한다.&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;코드코드&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5. 병합 정렬 (Merge Sort)&lt;/b&gt;&lt;/h3&gt;</description>
      <category>자료구조</category>
      <category>버블정렬</category>
      <category>병합정렬</category>
      <category>삽입정렬</category>
      <category>선택정렬</category>
      <category>알고리즘</category>
      <category>자료구조</category>
      <category>정렬</category>
      <category>정렬알고리즘</category>
      <category>퀵정렬</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/27</guid>
      <comments>https://kimbob-world.tistory.com/entry/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0%EC%A0%95%EB%A0%ACSorting-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%9D%B4%EB%9E%80#entry27comment</comments>
      <pubDate>Mon, 20 Oct 2025 04:35:32 +0900</pubDate>
    </item>
    <item>
      <title>[자료구조] 힙(heap)</title>
      <link>https://kimbob-world.tistory.com/entry/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%ED%9E%99heap%EC%9D%B4%EB%9E%80</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;힙이란 &lt;b&gt;&lt;span style=&quot;color: #ef6f53;&quot;&gt;완전이진트리&lt;/span&gt;&lt;/b&gt;의 일종으로 구성되어 있으며 &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;우선순위를 빠르게 처리하기위한 자료구조&lt;/b&gt;&lt;/span&gt;이다.&lt;br /&gt;예를들면 최대값 혹은 최소값을 찾아내고 우선순위에따라 재정렬되는 구조에 사용하기좋은 알고리즘이다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ef6f53;&quot;&gt;완전 이진트리란?&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ef6f53;&quot;&gt;&lt;b&gt;이진트리 + 특정 조건으로 마지막 레벨을 제외하고 모든 레벨이 왼쪽부터 채워져있어야하는 조건을 뜻함.&lt;br /&gt;현재 이미지 구조는 완전 이진트리로 구성된 min_heap이며&lt;br /&gt;부모 노드는 무조건 자식노드보다 높거나(max_heap) 낮아야함(min_hea)&lt;br /&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;b&gt;해당 구조(min_heap)에서 만약 &lt;span style=&quot;color: #f89009;&quot;&gt;1번&lt;/span&gt;&amp;nbsp;최상위노드가 삭제된다면 최하위 노드인&lt;span style=&quot;color: #f89009;&quot;&gt; 6번&lt;/span&gt;이 &lt;span style=&quot;color: #f89009;&quot;&gt;1번&lt;/span&gt;자리로 오고&lt;br /&gt;부모 노드는 항상 자식노드보다 작아야한다는 규칙이 있기때문에&lt;br /&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;6번&lt;/span&gt; -&amp;gt; 자식노드 중 &lt;span style=&quot;color: #f89009;&quot;&gt;2번&lt;/span&gt;과 &lt;span style=&quot;color: #f89009;&quot;&gt;3&lt;/span&gt;번중 더 작은값과 변경 = &lt;span style=&quot;color: #f89009;&quot;&gt;2번&lt;/span&gt;과 자리 변경 -&amp;gt; &lt;span style=&quot;color: #f89009;&quot;&gt;5번&lt;/span&gt;과 &lt;span style=&quot;color: #f89009;&quot;&gt;4번&lt;/span&gt;중 더 작은것 비교해서 작은것으로 이동 =&amp;gt;&lt;br /&gt;그렇게 되면 좌측은 &lt;span style=&quot;color: #f89009;&quot;&gt;2&lt;/span&gt;-&amp;gt; &lt;span style=&quot;color: #f89009;&quot;&gt;4&lt;/span&gt; -&amp;gt; &lt;span style=&quot;color: #f89009;&quot;&gt;5&lt;/span&gt; |&amp;nbsp; &lt;span style=&quot;color: #f89009;&quot;&gt;6&lt;/span&gt; 형태의 노드로 완성된다.&amp;nbsp;&lt;/b&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;537&quot; data-origin-height=&quot;394&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l4I59/btsQ4WGXrPn/ka43MDBGT6yb27XmlHUkTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l4I59/btsQ4WGXrPn/ka43MDBGT6yb27XmlHUkTk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l4I59/btsQ4WGXrPn/ka43MDBGT6yb27XmlHUkTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl4I59%2FbtsQ4WGXrPn%2Fka43MDBGT6yb27XmlHUkTk%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;537&quot; height=&quot;394&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;394&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;그렇게 완전이진트리형태로 계산되기때문에&lt;br /&gt;완전 이진트리구조를 가진 힙(heap)의 데이터 삽입/삭제의 시간복잡도는 평균 O(log n)의 구조를 가진다.&lt;/b&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;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size18&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;b&gt;이걸 어디에 써?&lt;/b&gt;&lt;/h3&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;b&gt;우선순위 큐 (Priority Queue):&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;힙의 가장 대표적인 활용 예시&lt;/li&gt;
&lt;li&gt;응급실에서 가장 위급한 환자를 먼저 치료하는 시스템&lt;/li&gt;
&lt;li&gt;은행에서 누가 먼저 번효표를뽑았는가?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;힙 정렬 (Heapsort)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터를 힙에 모두 넣었다가 하나씩 꺼내면 자연스럽게 정렬이 되는 원리를 이용한 정렬 알고리즘&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&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&gt;수많은 경로 중 가장 비용이 적은 경로를 계속해서 찾아 나갈 때 다음으로 탐색할 최적의 경로를&lt;br /&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;</description>
      <category>자료구조</category>
      <category>c++</category>
      <category>Heap</category>
      <category>자료구조</category>
      <category>힙</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/26</guid>
      <comments>https://kimbob-world.tistory.com/entry/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%ED%9E%99heap%EC%9D%B4%EB%9E%80#entry26comment</comments>
      <pubDate>Sun, 12 Oct 2025 20:27:29 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스]Lv3 이중우선순위큐 C++ 문제풀이</title>
      <link>https://kimbob-world.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4Lv3-%EC%9D%B4%EC%A4%91%EC%9A%B0%EC%84%A0%EC%88%9C%EC%9C%84%ED%81%90-C-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42628&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/42628&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;이중우선순위큐&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;977&quot; data-origin-height=&quot;564&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czqhgc/btsQ5YDIHMJ/On29kVP6STrsVNqQeU7JMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czqhgc/btsQ5YDIHMJ/On29kVP6STrsVNqQeU7JMk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czqhgc/btsQ5YDIHMJ/On29kVP6STrsVNqQeU7JMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fczqhgc%2FbtsQ5YDIHMJ%2FOn29kVP6STrsVNqQeU7JMk%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;977&quot; height=&quot;564&quot; data-origin-width=&quot;977&quot; data-origin-height=&quot;564&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;문제풀이&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;우선순위 큐(priority_queue)를 통해 값이 들어오면 최대값 , 최소값을 계속 재정렬하고&lt;br /&gt;최대값과 최소값을 어떻게 동기화 할것인가?를 고민한 문제.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1760261982273&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;queue&amp;gt;
#include &amp;lt;sstream&amp;gt;
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;algorithm&amp;gt;
#include &amp;lt;map&amp;gt;

using namespace std;

vector&amp;lt;int&amp;gt; solution(vector&amp;lt;string&amp;gt; operations) {
    vector&amp;lt;int&amp;gt; answer;
    priority_queue&amp;lt;int&amp;gt; pq;
    priority_queue&amp;lt;int,vector&amp;lt;int&amp;gt;,greater&amp;lt;int&amp;gt;&amp;gt; min_pq;
    map&amp;lt;int,int&amp;gt; mpq;
    
    //동기화 시키는법..
    for(const string&amp;amp; op : operations){
        //공백 나누기
        stringstream ss(op);
        string word;
        vector&amp;lt;string&amp;gt; str;
        
        while(ss &amp;gt;&amp;gt; word){
            str.push_back(word);
        }
        
        if(str[0] == &quot;I&quot;){//값넣기
            int st = stoi(str[1]);
            mpq[st]++;
            pq.push(st);
            min_pq.push(st);
        }else if(str[0] == &quot;D&quot;){
            if(str[1] == &quot;1&quot;){ // 최대값 삭제
                //실제 값 삭제
                if(!pq.empty()){
                    mpq[pq.top()]--;
                    pq.pop();
                }
            }else{ // 최소값 삭제
                //맵안에 0인것들은 min의 top과 같다면 pop
                //max에는 123이 남아있다..
                //현재는 값이 들어오면 동기화 후 재정렬 하기
                // 1.동기화 후 출력? map을통해 값정렬 두번하기
                if(!min_pq.empty()){
                    mpq[min_pq.top()]--;            
                    min_pq.pop();
                }
            }
            //없는값 삭제
            while(!pq.empty() &amp;amp;&amp;amp; mpq[pq.top()] == 0){
                pq.pop();
            }
            while(!min_pq.empty() &amp;amp;&amp;amp; mpq[min_pq.top()] == 0){
                    min_pq.pop();
                }
        }
    }
    
    int max = pq.empty() ? 0 : pq.top();
    int min = min_pq.empty() ? 0 : min_pq.top();
    answer.push_back(max);
    answer.push_back(min);
    
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;스플릿을 통해서 공백을 기준으로 들어오는 값을 나눴다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;I일 경우 그 다음값을 숫자로 변환하기&lt;/li&gt;
&lt;li&gt;D일경우 그 다음들어오는 문자열로 최소값인지 최대값인지 확인(str[0] == &quot;D&quot;) { if (str[1] == 1) { //최대값&amp;nbsp; } }&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;I일경우 최대값 , 최소값을 따로나눠서 우선순위 큐에 저장하고 이들을 동기화할 map에 들어온 값을 key로 넣고 +1을 해준다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;이 후 값이 제거될 경우 -1을 통해서 true false확인 장치&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;D를 통해 값이 들어올경우 1 과 -1을 체크해서 최대/최소값
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;if문을 통해 우선순위 큐에 값이 없을때 삭제되는 경우를 방지&lt;/li&gt;
&lt;li&gt;동기화를 위해 pq.top() //삭제되는 값을 map[pq.top()] --; 를 통해 false로 만들어주기&lt;/li&gt;
&lt;li&gt;맵에 저장 후 최대값을 배열에서 삭제 pq.pop();&lt;/li&gt;
&lt;li&gt;-1도 동일하게 장치해둠 (최소값을 제거하는 다른 우선순위 큐 min_pq)&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;이 후 최대값 우선순위큐(pq)와 최소값(min_pq)를 돌며 제거된값 확인하기
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;현재각 우선순위에 있는 값(최소,최대)이 이미 제거된 값인지 확인0
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;!min_pq.empty() &amp;amp;&amp;amp; map[pq.top()] == 0 //!min_pq.empty() 우선 배치해서&amp;nbsp; 값이 비어있으면 이후 체크x&lt;/li&gt;
&lt;li&gt;max_pq도 동일&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&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;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;삽질삽질&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1760262976166&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;queue&amp;gt;
#include &amp;lt;sstream&amp;gt;
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;algorithm&amp;gt;
#include &amp;lt;map&amp;gt;

using namespace std;

vector&amp;lt;int&amp;gt; solution(vector&amp;lt;string&amp;gt; operations) {
    vector&amp;lt;int&amp;gt; answer;
    priority_queue&amp;lt;int&amp;gt; pq;
    priority_queue&amp;lt;int,vector&amp;lt;int&amp;gt;,greater&amp;lt;int&amp;gt;&amp;gt; min_pq;
    map&amp;lt;int,int&amp;gt; mpq;
    
    //동기화 시키는법..
    for(const string&amp;amp; op : operations){
        //공백 나누기
        stringstream ss(op);
        string word;
        vector&amp;lt;string&amp;gt; str;
        
        while(ss &amp;gt;&amp;gt; word){
            str.push_back(word);
        }
        
        if(str[0] == &quot;I&quot;){//값넣기
            int st = stoi(str[1]);
            mpq[st]++;
            pq.push(st);
            min_pq.push(st);
        }else if(str[0] == &quot;D&quot;){
            if(str[1] == &quot;1&quot;){ // 최대값 삭제
                //없는값 삭제
                while(!pq.empty() &amp;amp;&amp;amp; mpq[pq.top()] == 0){
                    pq.pop();
                }
                
                //실제 값 삭제
                if(!pq.empty()){
                    mpq[pq.top()]--;
                    pq.pop();
                }
               
            }else{ // 최소값 삭제
                //맵안에 0인것들은 min의 top과 같다면 pop
                //max에는 123이 남아있다..
                //현재는 값이 들어오면 동기화 후 재정렬 하기
                // 1.동기화 후 출력? map을통해 값정렬 두번하기
                while(!min_pq.empty() &amp;amp;&amp;amp; mpq[min_pq.top()] == 0){
                    min_pq.pop();
                }
                
                if(!min_pq.empty()){
                    mpq[min_pq.top()]--;            
                    min_pq.pop();
                }
            }
        }
    }
    
    int max = pq.empty() ? 0 : pq.top();
    int min = min_pq.empty() ? 0 : min_pq.top();
    answer.push_back(max);
    answer.push_back(min);
    
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;삽질보다는 중간과정이 맞을꺼다..&lt;br /&gt;값이 -1로 들어오거나 1로 들어올때마다 동기화를 해줬더니 D를통해 마지막에 값이 삭제되면&lt;br /&gt;둘 중 하나에는 값이 제거가 되지않아 삭제가 안되는 버그가 생겼다.&lt;br /&gt;그래서 값이 삭제되는 D라는 입력값이 들어오면 체크해서 최대/최소값을 삭제 후 둘다 동기화 될 수있게 변경했다.&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;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;프로그래머스 다른분이 풀은 좋은 코드&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1760263265789&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;set&amp;gt;

using namespace std;

vector&amp;lt;int&amp;gt; solution(vector&amp;lt;string&amp;gt; arguments) {
    vector&amp;lt;int&amp;gt; answer;
    multiset&amp;lt;int&amp;gt; que;
    multiset&amp;lt;int&amp;gt;::iterator iter;
    string sub;

    for(auto s : arguments) {
        sub =s.substr(0, 2);
        if(sub==&quot;I &quot;) que.insert(stoi(s.substr(2,s.length()-2))); 
        else if(s.substr(2,1)==&quot;1&quot;&amp;amp;&amp;amp;que.size()&amp;gt;0) { que.erase(--que.end()); }
        else if(que.size()&amp;gt;0) { que.erase(que.begin()); }
    }

    if(que.size()==0) { answer.push_back(0); answer.push_back(0); }
    else { 
        iter = --que.end(); answer.push_back(*iter); 
        iter = que.begin(); answer.push_back(*iter);
    }

    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;굉장히 짧은코드라 인상적이였다.&lt;br /&gt;멀티셋을 통해서 중복값을 삭제하며 자동정렬이 되는 기능이 있기때문에 사용하신거같고&lt;br /&gt;substr을 이용해 들어온값을 잘라서 확인하고 마지막에 iter를 이용해 시작값(최소값)과 끝값(최대값)을 answer에 넣어줌으로써ㅏ&lt;br /&gt;코드를 완성한 코드였다.&lt;br /&gt;&lt;b&gt;2따봉..&lt;/b&gt;&lt;/p&gt;</description>
      <category>알고리즘</category>
      <category>queue</category>
      <category>이중우선순위큐</category>
      <category>자료구조</category>
      <category>큐</category>
      <category>프로그래머스</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/25</guid>
      <comments>https://kimbob-world.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4Lv3-%EC%9D%B4%EC%A4%91%EC%9A%B0%EC%84%A0%EC%88%9C%EC%9C%84%ED%81%90-C-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4#entry25comment</comments>
      <pubDate>Sun, 12 Oct 2025 19:06:01 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] Lv3 디스크 컨트롤러 C++ 문제풀이</title>
      <link>https://kimbob-world.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv3-%EB%94%94%EC%8A%A4%ED%81%AC-%EC%BB%A8%ED%8A%B8%EB%A1%A4%EB%9F%AC-C-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42627&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/42627&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;디스크 컨트롤러&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;문제&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;525&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IKODv/btsQ5Z3Ku6v/9SZyUHzTy6wcp4cFTALwSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IKODv/btsQ5Z3Ku6v/9SZyUHzTy6wcp4cFTALwSK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IKODv/btsQ5Z3Ku6v/9SZyUHzTy6wcp4cFTALwSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIKODv%2FbtsQ5Z3Ku6v%2F9SZyUHzTy6wcp4cFTALwSK%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;755&quot; height=&quot;525&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;525&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;728&quot; data-origin-height=&quot;547&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ciMfsB/btsQ5TWqYnx/MkJma1uLCbbsTaq1yW1o6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ciMfsB/btsQ5TWqYnx/MkJma1uLCbbsTaq1yW1o6K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ciMfsB/btsQ5TWqYnx/MkJma1uLCbbsTaq1yW1o6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FciMfsB%2FbtsQ5TWqYnx%2FMkJma1uLCbbsTaq1yW1o6K%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;728&quot; height=&quot;547&quot; data-origin-width=&quot;728&quot; data-origin-height=&quot;547&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디스크들을 요청시각별로 정렬 한 후 같은요청 시각일 경우 작업하는데 걸리는 시간을 계산해서 먼저 되는것 부터 계산하기&lt;br /&gt;작업하는데 걸리는 시간까지 동일하다면 작업 번호를 기준으로 정렬하여 우선순위 정하기&lt;br /&gt;구조체를 사용하여 인덱스까지 모두 저장한 후 우선순위 큐를 사용하여 정렬방식을 정해줬다.&lt;/p&gt;
&lt;pre id=&quot;code_1760261847982&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;queue&amp;gt;
#include &amp;lt;algorithm&amp;gt;

using namespace std;

struct diskControl{
    int st,second,index;
    
    diskControl(int start , int s, int i) : st(start),second(s),index(i) {} // 생성자 정의
    
    bool operator&amp;lt;(const diskControl d) const {
        //소요시간이 같으면
        if(this-&amp;gt;second == d.second){
            //시작시간이 같다면 인덱스를 비교해서 우선순위 아니라면 시작시간비교
           return (this-&amp;gt;st == d.st ? this-&amp;gt;index &amp;gt; d.index : this-&amp;gt;st &amp;gt; d.st);
        }else{
            return this-&amp;gt;second &amp;gt; d.second;    
        }
    }
};

//[[0,3] , [1,9] , [3,5]]  return 8 //작업 요청시각 , 작업 소요시간
//우선순위 소요시간짧음 &amp;gt; 작업의 요청 시각이 빠름 &amp;gt; 작업 번호가 작음
// [0,3] -&amp;gt; [3,5] -&amp;gt; [1,9]
int solution(vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; jobs) {
    int answer = 0;
    int index=0;
    int currentTime=0;
    int averageSize = jobs.size();
    //구조체를 통해 순서 정렬
    priority_queue&amp;lt;diskControl&amp;gt; pq;
    vector&amp;lt;diskControl&amp;gt; jbs;
    

    for(int i=0;i&amp;lt;averageSize;i++){
        jbs.push_back(diskControl(jobs[i][0],jobs[i][1],i));
    }
    
    sort(jbs.begin(),jbs.end(),[] (auto &amp;amp;a , auto &amp;amp;b){
        return a.st &amp;lt; b.st;
    });
    
    //모든 인덱스 다 검사할때까지
    while(index &amp;lt; averageSize || !pq.empty() ){
        //현재 시간대에 있는 디스크만 삽입
        while(index &amp;lt; averageSize &amp;amp;&amp;amp; jbs[index].st &amp;lt;= currentTime){
            pq.push(diskControl(jbs[index].st,jbs[index].second , jbs[index].index ));
            index++;
        }

        if (!pq.empty()) {
            // 현재시간 + 시간 계산 작업중요소 pop으로 제외
            currentTime += pq.top().second;
            answer += currentTime - pq.top().st;
            pq.pop();
            
        } else {
            //큐가 비어있다면 인덱스의 디스크시간으로 업데이트
            currentTime = jbs[index].st;
        }
    }
    answer /= averageSize;
         
         
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에있는 요소들을 맨처음 시간별로만 정의하기 위해서 sort를 사용했고 한번만 하면되기때문에 람다함수를 사용했다.&lt;br /&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;priority_queue를 사용해 대기프로세스에 큐가 들어오고 나갈 때 마다 재정렬해줬고 &lt;br /&gt;그 규칙을 만들기위해 &lt;span style=&quot;text-align: start;&quot;&gt;operator&amp;lt;를 사용해서 구조체를 만들어 이후 디스크 내부에있는 작업들의 순서를 계속 재정렬해줬다.&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;br /&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;br /&gt;참고자료 : &lt;a href=&quot;https://kbj96.tistory.com/15&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://kbj96.tistory.com/15&lt;/a&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;우선순위 큐에대해 알아보던 중 구조체를 사용하셔서 정렬하시는 블로그를 참조했다 !&lt;/span&gt;&lt;/b&gt;&lt;/h4&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;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;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>LV3</category>
      <category>디스크컨트롤러</category>
      <category>문제풀이</category>
      <category>알고리즘</category>
      <category>자료구조</category>
      <category>프로그래머스</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/24</guid>
      <comments>https://kimbob-world.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv3-%EB%94%94%EC%8A%A4%ED%81%AC-%EC%BB%A8%ED%8A%B8%EB%A1%A4%EB%9F%AC-C-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4#entry24comment</comments>
      <pubDate>Sat, 11 Oct 2025 00:36:23 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스]Lv2 더 맵게 C++ 문제풀이</title>
      <link>https://kimbob-world.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4Lv2-%EB%8D%94-%EB%A7%B5%EA%B2%8C-C-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42626&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/42626&lt;/a&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;더 맵게&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1135&quot; data-origin-height=&quot;704&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/slMg3/btsQ4PmRQzD/oob7W0rLxhhL3YH0CkRNRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/slMg3/btsQ4PmRQzD/oob7W0rLxhhL3YH0CkRNRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/slMg3/btsQ4PmRQzD/oob7W0rLxhhL3YH0CkRNRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FslMg3%2FbtsQ4PmRQzD%2Foob7W0rLxhhL3YH0CkRNRK%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;1135&quot; height=&quot;704&quot; data-origin-width=&quot;1135&quot; data-origin-height=&quot;704&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;문제 해석&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;값을 작은 순서부터 나열한 다음 첫번째값 + (두번째값*2)하여 값을 배열에 넣어준다.&lt;br /&gt;이 후 첫번쨰와 두번쨰값을 지우고 다시 정렬하며 K값보다 작은값이 있는지 확인함.&lt;br /&gt;한번 돌때마다 return값을 ++해준다.&lt;br /&gt;예외처리 : 모든 값을 더했지만 배열사이즈가 하나라면 (size == 1&amp;nbsp; &amp;amp;&amp;amp; scoville[0]&amp;lt; K) return -1;&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;pre id=&quot;code_1760092571205&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;queue&amp;gt;
#include &amp;lt;functional&amp;gt;

using namespace std;

int solution(vector&amp;lt;int&amp;gt; scoville, int K) {
    int answer = 0;
    priority_queue&amp;lt;int , vector&amp;lt;int&amp;gt;,greater&amp;lt;int&amp;gt;&amp;gt; pq;
    
    for(const int&amp;amp; sv : scoville){
        pq.push(sv);
    }
    while(pq.size() &amp;gt; 1){
        //제일 작은값이 7 이하라면
        int result=0;
        if(pq.top() &amp;lt; K){
            result += pq.top();
            pq.pop();
            result += pq.top()*2;
            pq.pop();
            pq.push(result);
            answer++;
        }else{
            break;
        }
    }
    if(pq.size() == 1 &amp;amp;&amp;amp; pq.top() &amp;lt; K){ return -1; }
    
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선순위 큐를 활용해서 풀어낸 방식이다.&lt;br /&gt;priority_queue를통해 우선큐를 사용하고 int 타입 vector배열로 선언 , greater&amp;lt;int&amp;gt;를 통해 내림차순 정렬을 한다.&lt;br /&gt;그리고 result를 통해 최상단 값을 더해서 top()을 통해 가장 낮은값(0번째인덱스)에 접근한다.&lt;br /&gt;이후 pop()을 이용해 값을 제거하고 다음값을 top()으로 접근해 top()*2를 통해 최종값을 result에 넣어준다&lt;br /&gt;priority_queue를 통해 자동으로 내림차순이 되기때문에 새로운 낮은 값중 K이하 인것들을 더해준다.&lt;br /&gt;모든 값을 더했지만 K값 이하일때 return -1; 을 해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 이 우선순위 큐를 몰라서 for문을통해 접근을 했을때 시간초과에러가 우수수났엇다..&lt;br /&gt;그 코드를 공유함&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;삽질삽질..&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1760092909508&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;algorithm&amp;gt;

using namespace std;

int solution(vector&amp;lt;int&amp;gt; scoville, int K) {
    int answer = 0;
    while(scoville.size() &amp;gt; 1){
        sort(scoville.begin(),scoville.end());
        int result = scoville[0];
        if(scoville[0] &amp;lt; K ){
            //scoville[0]번째 값
            result += scoville[1] * 2;
            scoville[0] = result;
            //삭제하기
            scoville.erase(scoville.begin() + 1);
            answer++;
        }else{
            break;
        }
    }
    if(scoville[0] &amp;lt; K ){ return -1; }
    
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sort를 통해 계속 값을 작은값부터 나열했다&lt;br /&gt;그리고 size가 1보다 작으면 멈추고 해당값을 체크해서 K보다 작으면 -1를 했지만&lt;br /&gt;한번 체크할때마다 sort를 통해 나열을 해서 시간초과 에러가 낫다..&lt;br /&gt;아래 AI피드백을 보니 힙을 활용해 우선순위큐를 활용하라고 써있어서 구글서치를 통해서 해결했다..따봉&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;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중간에 궁금해서 검색해본 priority_queue&amp;lt;int , vector&amp;lt;int&amp;gt; || deque&amp;lt;int&amp;gt;, greater&amp;lt;int&amp;gt;&amp;gt;에서&lt;br /&gt;vector와 deque의 차이가 뭘까? 를 검색해봤는데&lt;br /&gt;deque는 배열에 값이 동적으로 늘어날때 위 아래에 하나씩 추가가 되는 방식이고&lt;br /&gt;vector는 모든 배열을 복사해서 새로 추가된 배열에 추가되기때문에 동적인 배열에서는 deque가 유리하다는 사실을 알았다.&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘</category>
      <category>c++</category>
      <category>Lv2</category>
      <category>priority_queue</category>
      <category>문제풀이</category>
      <category>알고리즘</category>
      <category>프로그래머스</category>
      <category>힙</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/23</guid>
      <comments>https://kimbob-world.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4Lv2-%EB%8D%94-%EB%A7%B5%EA%B2%8C-C-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4#entry23comment</comments>
      <pubDate>Fri, 10 Oct 2025 19:46:18 +0900</pubDate>
    </item>
    <item>
      <title>[자료구조] 스택 / 큐 (Stack &amp;amp; Queue)</title>
      <link>https://kimbob-world.tistory.com/entry/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%8A%A4%ED%83%9D-%ED%81%90-Stack-Queue</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;스택 (Stack)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;후입 후출 LIFO(Last In Last Out)구조를 가진 자료구조&lt;/li&gt;
&lt;li&gt;ex) 상자를 쌓아두고 빼는 구조 =&amp;gt; 마지막에 쌓은 상자를 처음 꺼내야 뒤에 상자를 꺼낼 수 있음&lt;/li&gt;
&lt;li&gt;데이터가 일자형태를 가진 선형구조&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stackimg.png&quot; data-origin-width=&quot;711&quot; data-origin-height=&quot;569&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqSsyP/btsQ3d2Aopl/1tAslhsVh2gxedrCzOysNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqSsyP/btsQ3d2Aopl/1tAslhsVh2gxedrCzOysNK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqSsyP/btsQ3d2Aopl/1tAslhsVh2gxedrCzOysNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqSsyP%2FbtsQ3d2Aopl%2F1tAslhsVh2gxedrCzOysNK%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;711&quot; height=&quot;569&quot; data-filename=&quot;stackimg.png&quot; data-origin-width=&quot;711&quot; data-origin-height=&quot;569&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Stack에서 호출하는 함수&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;stack.push(&quot;box&quot;)&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;스택안에 data를 쌓는 함수&lt;/li&gt;
&lt;li&gt;&quot;box&quot;데이터를 제일 상단(Top)에 올린다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;stack.top() / stack.peek()&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;스택은 가장 상단의 값에만 접근이 가능하다&lt;/li&gt;
&lt;li&gt;상단에 값에 접근하기위해 만들어진 함수&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;stack.pop()&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;해당 상단값을 제거하기위해 사용하는 함수&lt;/li&gt;
&lt;li&gt;ex) [4,3,2,1]기준 1을 제거하고 [4,3,2]만 남긴다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;stack.size()&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;스택에 들어간 배열의 사이즈를 반환한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;stack.empty()&lt;/b&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;스택이 비어있는지 확인하는 함수 boolean타입으로 정의됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1759994645549&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int solution(int n){
	
    stack&amp;lt;int&amp;gt; st;
    cout &amp;lt;&amp;lt; st.empty(); // true 비어있음을 뜻함
    st.push(&quot;data&quot;); //[&quot;data&quot;]
    st.push(&quot;data2&quot;); //[&quot;data&quot;,&quot;data2&quot;]
    cout &amp;lt;&amp;lt; st.top(); //&quot;data2&quot;을 출력함.
    cout &amp;lt;&amp;lt; st.size(); // 2를 출력
    st.pop(); // &quot;data2&quot;를 삭제
    cout &amp;lt;&amp;lt; st.top(); // &quot;data&quot; 출력
    
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;큐 (Queue)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;선입선출 FiFO(First In First Out)구조를 가진 자료구조&lt;/li&gt;
&lt;li&gt;은행에서 번호표를 먼저 뽑은 사람이 먼저 일처리를 하는 구조&lt;/li&gt;
&lt;li&gt;데이터는 선형구조로 첫데이터에만 접근가능하며 다른 데이터에 접근하려면 이전 데이터를 빼내야하는것은 동일&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;queueimg.png&quot; data-origin-width=&quot;699&quot; data-origin-height=&quot;691&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhMTGQ/btsQ2VnvRQU/0yGCpxqsTvt5UJWPqtgAgk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhMTGQ/btsQ2VnvRQU/0yGCpxqsTvt5UJWPqtgAgk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhMTGQ/btsQ2VnvRQU/0yGCpxqsTvt5UJWPqtgAgk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhMTGQ%2FbtsQ2VnvRQU%2F0yGCpxqsTvt5UJWPqtgAgk%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;699&quot; height=&quot;691&quot; data-filename=&quot;queueimg.png&quot; data-origin-width=&quot;699&quot; data-origin-height=&quot;691&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Queue에서 호출하는함수&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;queue.push(&quot;box&quot;)&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;큐 안에 데이터를 쌓는 함수&lt;/li&gt;
&lt;li&gt;&quot;box&quot;데이터 값을 첫 데이터로 넣는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;queue.front()&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;큐는 먼저 들어온 값 또는 마지막값을 반환가능&lt;/li&gt;
&lt;li&gt;front를 통해 처음으로 들어간 데이터(값)을 반환한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;queue.back()&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;마지막에 들어온 값을 반환해서 사용하기 위해 쓰는 함수&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;queue.pop()&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;front를 통해 접근할수있는 상단의 값을 빼준다.&lt;/li&gt;
&lt;li&gt;queue는 다음 데이터에 접근하기위해 기존값을 제거해줘야한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;queue.size()&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;큐의 사이즈를 확인하는 함수&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;queue.empty()&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;true/false를 통해 비어있는지 여부 확인&lt;/li&gt;
&lt;li&gt;큐 배열 내부가 비어있는지 확인하는 함수&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1759996690822&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int solution(int n){

	queue&amp;lt;int&amp;gt; qe;
    
    qe.push(&quot;data1&quot;)//데이터 푸시
    qe.push(&quot;data2&quot;)
    qe.push(&quot;data3&quot;)
    /* [&quot;data1&quot;,&quot;data2&quot;,&quot;data3&quot;]  */
    cout &amp;lt;&amp;lt; qe.front(); //먼저들어온 &quot;data1&quot;을 출력
    cout &amp;lt;&amp;lt; qe.back(); // 마지막에 들어온 &quot;data3&quot;을 출력
    
    qe.pop() // 처음 들어온 &quot;data1&quot;을 제거함[&quot;data2&quot;,&quot;data3&quot;]
    cout &amp;lt;&amp;lt; qe.size(); //pop이후 사이즈를 반환 =&amp;gt; 2
    cout &amp;lt;&amp;lt; qe.empty(); // 2개가 있기때문에 false를 반환

	return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>자료구조</category>
      <category>c++</category>
      <category>queue</category>
      <category>stack</category>
      <category>스택</category>
      <category>알고리즘</category>
      <category>자료구조</category>
      <category>큐</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/22</guid>
      <comments>https://kimbob-world.tistory.com/entry/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%8A%A4%ED%83%9D-%ED%81%90-Stack-Queue#entry22comment</comments>
      <pubDate>Thu, 9 Oct 2025 16:58:49 +0900</pubDate>
    </item>
    <item>
      <title>[자료구조] 해시(Hash)</title>
      <link>https://kimbob-world.tistory.com/entry/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%ED%95%B4%EC%8B%9CHash</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #ef6f53;&quot;&gt;&lt;b&gt;해시&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;key(고유한 식별자)와 value(저장할 데이터)로 이루어진 자료구조&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;해시 함수(hash function)을 사용해 key를 해시값(hash value)로 변환하고&lt;/b&gt;&lt;br /&gt;&lt;b&gt;해당 해시값을 해시 테이블(hash table)의 인덱스로 사용하여 데이터를 빠르게 저장/탐색/삭제한다.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;key를 통해 데이터에 접근하기때문에 시간복잡도는 평균적으로 O(1)이다.&lt;/b&gt;&lt;/h4&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;style3&quot; /&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;&gt;
&lt;li&gt;서로 다른 Key가 같은 해시값(hash value)로 변환되는현상&lt;/li&gt;
&lt;li&gt;다른 key가 같은 인덱스에 연결되어 충돌현상이 일어남&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;b&gt;충돌이 나는 이유가 뭐야?&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해시 테이블(배열)의 인덱스공간은 유한하지만 저장하려는 데이터(key)는 무한할 수 있기에 오류가 발생&lt;/li&gt;
&lt;li&gt;ex) 방 10개가 있는데 20명이 들어온다면? 해당 방에는 함께 들어갈 수밖에 없음 =&amp;gt; 충돌(collision)&lt;/li&gt;
&lt;li&gt;hash(&quot;dog&quot;) =3; hash(&quot;cat&quot;) = 3; 한다면 같은칸으로 계산됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;그럼 충돌의 해결 방법은?&lt;/b&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;체이닝(Channing)방식&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;같은 인덱스안에 여러 데이터를 연결리스트(Linked List)로 저장하는 방식&lt;/li&gt;
&lt;li&gt;3번인덱스 --&amp;gt; [A,90] -&amp;gt; [B,85] -&amp;gt; [C,80];&lt;/li&gt;
&lt;li&gt;C를 찾는다고 했을 때 해시함수를 통해 3번인덱스에 접근하여 A를 확인 B를 확인 C까지 연결 리스트를 확인하여 체크 후 꺼냄&lt;/li&gt;
&lt;li&gt;평균적으로 짧지만 한 인덱스에 값이 많다면 속도가 O(1) -&amp;gt; O(n)으로 떨어질 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;오픈 어드레싱(Open Addressing)&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;충돌 발생 시 , 빈 칸을 찾아 &quot;다른 인덱스&quot;에 저장하는 방식&lt;/li&gt;
&lt;li&gt;ex) 3번인덱스에 값을 저장하려했지만 이미 차있다면 4번인덱스로 바꾸어 저장&lt;/li&gt;
&lt;li&gt;만약 값을 저장하려했는데 인덱스가 없다면? 리해싱(rehashing)을 통해 배열의 크기를 늘린다&lt;/li&gt;
&lt;li&gt;보통 7-80%정도의 테이블이 차면 리해싱이 일어남.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;그럼 나는 왜 C++로 알고리즘을 풀면서 충돌나는걸 느끼지 못했지?&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;unordered_map을 사용해서 해시알고리즘을 구현&lt;/li&gt;
&lt;li&gt;해당 unordered_map은 데이터가 들어오면 자동으로 체이닝구조를 통해 연결 리스트(Linked List)를 만듦&lt;/li&gt;
&lt;li&gt;이 또한 테이블이 일정수준(0.75)를 넘기면 자동으로 리해시(테이블 확장)하여 충돌 확률을 낮춤&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>자료구조</category>
      <category>c++</category>
      <category>hash</category>
      <category>알고리즘</category>
      <category>자료구조</category>
      <category>해시</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/21</guid>
      <comments>https://kimbob-world.tistory.com/entry/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%ED%95%B4%EC%8B%9CHash#entry21comment</comments>
      <pubDate>Thu, 9 Oct 2025 07:14:25 +0900</pubDate>
    </item>
    <item>
      <title>[자료구조] 공간 복잡도(Space Complexity)란?</title>
      <link>https://kimbob-world.tistory.com/entry/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EA%B3%B5%EA%B0%84-%EB%B3%B5%EC%9E%A1%EB%8F%84Space-Complexity%EB%9E%80</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;공간 복잡도&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램이 실행될 때 필요한 총 메모리 양을 입력 N에 따라 표현한 함수.&lt;br /&gt;입력크기 N이 커질때마다 &lt;span style=&quot;color: #ef6f53;&quot;&gt;&quot;메모리 사용량이 얼마나 증가되는가?&quot;&lt;/span&gt; 를 나타냄.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;구성요소&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&amp;nbsp;고정 공간 (Fixed Part)&lt;br /&gt;&lt;/b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;b&gt;&lt;span style=&quot;color: #6164c6;&quot;&gt;상수 , 코드 , 전역 변수&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;가변 공간 (Variable Part)&lt;br /&gt;&lt;/b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;b&gt;&amp;nbsp;&lt;span style=&quot;color: #6164c6;&quot;&gt;매개 변수 , 지역 변수&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;입력 공간 (Input Space)&lt;br /&gt;&lt;/b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;b&gt;&lt;span style=&quot;color: #6164c6;&quot;&gt;입력 데이터 자체가 차지하는 공간&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;동적 공간 (Dynamic Space)&lt;br /&gt;&lt;/b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;b&gt;&lt;span style=&quot;color: #6164c6;&quot;&gt;실행 중 동적 할당 (malloc , new , vector , map 등)&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;해당 구성 또한 Big-O표기법을 그대로 사용함&lt;/b&gt;&lt;br /&gt;메모리 사용량을 거의 일정하기에 최상,평균,최악은 따로 구분하지않음&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;O(1) - 상수 공간
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;추가 메모리없이 단일변수의 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1759945136724&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//for문을 5번 돌리며 n을 합연산 해줌.
//result변수 하나에 합연산함으로 추가메모리 할당 필요 x
int solution(int n){
	int result=0;
    for(int i=0;i&amp;lt;5;i++){
    	result+=n;
    }
    
	return 0;    
}&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;O(n) - 선형공간
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;배열, 리스트 처럼 입력된 크기만큼 공간을 할당함.&lt;/li&gt;
&lt;li&gt;입력 크기에 비례해 메모리 사용량 증가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1759945436978&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int solution(int n){

    int arr[];
    for(int i=1;i&amp;lt;n;i++){
    	arr[i] = i*n;
    }

	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;O(log n) / O(n&amp;sup2;)은 시간복잡도에 써놓은 예시와 같아서 추가로 글을 쓰지않음.&lt;br /&gt;&lt;a href=&quot;https://kimbob-world.tistory.com/19&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://kimbob-world.tistory.com/19&amp;nbsp;&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1759945656713&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;[자료구조] 시간복잡도 Big-O란?&quot; data-og-description=&quot;1. 시간복잡도알고리즘을 풀 때 걸리는 시간을 3가지 형태로 큰 틀 3가지로 나눠놓은 형태최상의 경우 : 오메가 표기법(Big-&amp;Omega;)평균의 경우 : 세타 표기법(Big-&amp;Theta;)최악의 경우 : 빅오 표기법(Big-O)2. 시&quot; data-og-host=&quot;kimbob-world.tistory.com&quot; data-og-source-url=&quot;https://kimbob-world.tistory.com/19&quot; data-og-url=&quot;https://kimbob-world.tistory.com/19&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/kGpSY/hyZKkLqnte/7LlKDyGTLAkIjsectssH61/img.png?width=800&amp;amp;height=402&amp;amp;face=0_0_800_402,https://scrap.kakaocdn.net/dn/bjDCJK/hyZKJcmaKa/4myxG1RYrShrIn6kL5ylz1/img.png?width=800&amp;amp;height=402&amp;amp;face=0_0_800_402&quot;&gt;&lt;a href=&quot;https://kimbob-world.tistory.com/19&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://kimbob-world.tistory.com/19&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/kGpSY/hyZKkLqnte/7LlKDyGTLAkIjsectssH61/img.png?width=800&amp;amp;height=402&amp;amp;face=0_0_800_402,https://scrap.kakaocdn.net/dn/bjDCJK/hyZKJcmaKa/4myxG1RYrShrIn6kL5ylz1/img.png?width=800&amp;amp;height=402&amp;amp;face=0_0_800_402');&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;[자료구조] 시간복잡도 Big-O란?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;1. 시간복잡도알고리즘을 풀 때 걸리는 시간을 3가지 형태로 큰 틀 3가지로 나눠놓은 형태최상의 경우 : 오메가 표기법(Big-&amp;Omega;)평균의 경우 : 세타 표기법(Big-&amp;Theta;)최악의 경우 : 빅오 표기법(Big-O)2. 시&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;kimbob-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;동적공간 (Dynamic Space)&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;입력데이터 외에 알고리즘의 중간결과 또는 보조자료구조를 저장하기위해 직접 생성하는 추가적인 공간&lt;/li&gt;
&lt;li&gt;실질적인 알고리즘의 공간 효율성을 정함.&lt;/li&gt;
&lt;li&gt;입력크기 n에 비례하거나 , 더 빠르게 늘어날 수 있다.&lt;/li&gt;
&lt;li&gt;ex) vector를 통해 가져온 데이터를 복사해서 사용할때&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1759946464260&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; copyArray(vector&amp;lt;int&amp;gt;&amp;amp; arr) {
	//기존 arr은 입력공간 , 동적공간 = vector를통해 copy로 복사한 추가공간
    vector&amp;lt;int&amp;gt; copy;            // 새로운 배열을 만든다 (동적 공간)
    for (int x : arr)
        copy.push_back(x);       // arr 크기만큼 copy에 새 데이터 추가
    return copy;
}&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;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1759946504859&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int factorial(int n) {
    if (n == 1) return 1;
    return n * factorial(n - 1);
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>자료구조</category>
      <category>공간복잡도</category>
      <category>복잡도</category>
      <category>시간복잡도</category>
      <category>팩토리얼</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/20</guid>
      <comments>https://kimbob-world.tistory.com/entry/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EA%B3%B5%EA%B0%84-%EB%B3%B5%EC%9E%A1%EB%8F%84Space-Complexity%EB%9E%80#entry20comment</comments>
      <pubDate>Thu, 9 Oct 2025 03:04:08 +0900</pubDate>
    </item>
    <item>
      <title>[자료구조] 시간복잡도 Big-O란?</title>
      <link>https://kimbob-world.tistory.com/entry/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%8B%9C%EA%B0%84%EB%B3%B5%EC%9E%A1%EB%8F%84-Big-O%EB%9E%80</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 시간복잡도&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;text-align: left;&quot;&gt;알고리즘을 풀 때 걸리는 시간을 3가지 형태로 큰 틀 3가지로 나눠놓은 형태&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;최상의 경우 : 오메가 표기법(Big-&amp;Omega;)&lt;br /&gt;평균의 경우 : 세타 표기법(Big-&amp;Theta;)&lt;br /&gt;최악의 경우 : 빅오 표기법(Big-O)&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 시간복잡도의 종류와 사용처&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;color: #ef6f53;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;오메가 표기법(Big-&amp;Omega;&lt;/span&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;/li&gt;
&lt;li&gt;예시 : 비교를 통해 정렬하는 알고리즘은(n Log n)이라는 하한선이 존재 // O(n log n)보다 빠를 순 없다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;퀵 / 병합 / 힙정렬 등등&lt;/li&gt;
&lt;li&gt;[A,B,C,D]가 있다고 했을 때 (A &amp;gt;= B) , (C &amp;gt;= D) 먼저 비교 후 서로 높 / 낮 은것 끼리 비교해서 순서를 정함&lt;/li&gt;
&lt;li&gt;이 알고리즘이 더 빠를수있는가? 라는 질문이 왔을때 이미 수학적으로는 한계다 라는 증명을 할 때 사용함.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&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;color: #ef6f53;&quot;&gt;평균의 경우 : 세타 표기법(Big-&amp;Theta;)&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상한선(O)과 하한선(&amp;Omega;)이 동일할 때를 의미&lt;/li&gt;
&lt;li&gt;해당 알고리즘은 항상 N정도의 시간이 걸린다.&lt;/li&gt;
&lt;li&gt;아무리빨라도 O(n) 아무리느려도 O(n)일때를 말함.&lt;/li&gt;
&lt;li&gt;예시 :&amp;nbsp;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;단순 반복문 : for(int i=0;i&amp;lt;n;i++) { cout &amp;lt;&amp;lt; i &amp;lt;&amp;lt; endl; } =&amp;gt; 항상 n번 수행되며 입력크기에 비례해 수행 시간이 일정&lt;/li&gt;
&lt;li&gt;이진탐색 : 중간값을 기준 좌/우를 나누는 이진탐색같은경우도 아무리빨라도 log N을 가진다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;O(log n) : 실행시간이 입력크기에 비례하지않고 매번 절반비율로줄어드는 알고리즘을 뜻함.&lt;span style=&quot;color: #ef6f53;&quot;&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&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;color: #ef6f53;&quot;&gt;최악의 경우 : 빅오 표기법(Big-O)&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;아무리 느려도 이보다 느려질 수 없다는 상한선을 의미하며 수행시간이 아닌 N에대한 수학적 함수로 표현한 방법&lt;/li&gt;
&lt;li&gt;최악의 경우 시간 복잡도를 기준으로 안정성을 평가.&lt;/li&gt;
&lt;li&gt;Big-O의 대표적 시간복잡도 표현 방법&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;O(1) - 상수시간
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;입력 크기와 관계없이 항상 일정한 시간이 걸린다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1759935299206&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int solution(int n){
	int arr[] = [1,2,3,4,5];
	cout &amp;lt;&amp;lt; arr[n]; 
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc; color: #333333; text-align: left;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;O(log n)- 로그시간
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;매번 절반씩 줄어드는 구조&amp;nbsp; ex) 이진탐색&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1759936167759&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//특정 위치를 통해 1/2로 나누며 찾는 이진탐색 방법
//이진탐색 같은경우는 정렬이되어있어야함.
//N값 찾기
int solution(int n){ //2
    int arr[] = {1, 2, 3, 4, 5};  
    int left = 0;
    int right = (sizeof(arr) / sizeof(arr[0])) - 1; 
while(left &amp;lt;= right){
	int mid = (left+right)/2;
    //값이 동일하다면 return
    if(arr[mid] == N) return mid;
    //해당 값이 N보다 크면 왼쪽값만남기기
    else if (arr[mid] &amp;lt; N) left = mid+1;
    //해당 값이 N보다 작다면 오른쪽 값만 남기기
    else if(arr[mid] &amp;gt; N) right = mid -1;
    //값이 없다면 -1 반환
    return -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&gt;O(n) - 선형시간
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;입력 1개당 1회처리 (N번 반복)&lt;/li&gt;
&lt;li&gt;단순 for문&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1759936564191&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int solution(int n){

	for(int i=0;i&amp;lt;n;i++){
    	     cout &amp;lt;&amp;lt; &quot;hello world&quot; &amp;lt;&amp;lt; endl;
    }
    return 0;
}&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;O(n&amp;sup2;) - 제곱 시간
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 값을 확인 중첩반복문에 사용&lt;/li&gt;
&lt;li&gt;버블정렬 또는 이중 for문 =&amp;gt; N의 값에따라 n&amp;sup2;번 반복&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1759936869157&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int solution(int n){//2
	int arr[]={1,2,3,4,5}
    
    for(int i=0;i&amp;lt;n;i++){
    	for(int j=0;j&amp;lt;=n;j++){
        	cout &amp;lt;&amp;lt; j*arr[i] &amp;lt;&amp;lt; endl;
        }
    }
	return 0;    
}&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;O(2ⁿ) - 지수시간
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;n의 값에따라 폭발적으로 커지는 복잡도 =&amp;gt; N이 1증가할때마다 연산횟수가 2배증가&lt;/li&gt;
&lt;li&gt;모든 경우의 수를 탐색하는 완전탐색에 사용
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;재귀적 조합 탐색(부분집합 , DFS 완전탐색)&lt;/li&gt;
&lt;li&gt;ex) 비효율적인 파보나치 수열&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1759940408806&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int fib(int n) {
    if (n &amp;lt;= 1) return n;
    return fib(n - 1) + fib(n - 2);
}
// 각각재귀를 호출하며 트리형으로 확산함
// 해당 함수 호출 수가 대략 2ⁿ으로 증가&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;O(n!) - 팩토리얼
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;N의 값이 늘어남에 따라 가능한 모든 순서(경우의 수)을 탐색하는 알고리즘&lt;/li&gt;
&lt;li&gt;N개의 도시를 다 순회하고 최적의 루트 찾기&lt;/li&gt;
&lt;li&gt;ex) 1,2,3의 가능한 순서를 전부 출력한다면 3!=6의 경우를 가짐&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1759940736475&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
void permutation(vector&amp;lt;int&amp;gt;&amp;amp; arr, int depth, int n) {
    if (depth == n) { //재귀 종료조건
        for (int x : arr) cout &amp;lt;&amp;lt; x &amp;lt;&amp;lt; &quot; &quot;;
        cout &amp;lt;&amp;lt; endl;
        return;
    }
    for (int i = depth; i &amp;lt; n; i++) { //현재 depth의 위치를 바꾸며 순열 생성
        swap(arr[depth], arr[i]); // 위치 교환
        permutation(arr, depth + 1, n); //다음 깊이 재귀호출
        swap(arr[depth], arr[i]); // 원상복구
    }
}
/*
[1,2,3]
&amp;darr;
1 고정 &amp;rarr; [2,3] 순열 생성
2 고정 &amp;rarr; [1,3] 순열 생성
3 고정 &amp;rarr; [1,2] 순열 생성

*/&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;color: #f89009;&quot;&gt;&lt;b&gt;이상 간단해보이지만 간단하지않은 시간복잡도 설명을 끝마치며...&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;이해 가지않지만 이해안가는부분은 문제 풀다보면 풀리지않을까 라는 생각&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>자료구조</category>
      <category>c++</category>
      <category>복잡도</category>
      <category>시간복잡도</category>
      <category>알고리즘</category>
      <category>자료구조</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/19</guid>
      <comments>https://kimbob-world.tistory.com/entry/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%8B%9C%EA%B0%84%EB%B3%B5%EC%9E%A1%EB%8F%84-Big-O%EB%9E%80#entry19comment</comments>
      <pubDate>Thu, 9 Oct 2025 01:29:08 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] Lv2 기술개발 C++ 문제풀이</title>
      <link>https://kimbob-world.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv2-%EA%B8%B0%EC%88%A0%EA%B0%9C%EB%B0%9C-C-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42586&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/42586&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;기능개발&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;문제&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1003&quot; data-origin-height=&quot;590&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dL8STB/btsQ4kZ4s1j/QIL8LpGbm3EZn9KeGdo4WK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dL8STB/btsQ4kZ4s1j/QIL8LpGbm3EZn9KeGdo4WK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dL8STB/btsQ4kZ4s1j/QIL8LpGbm3EZn9KeGdo4WK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdL8STB%2FbtsQ4kZ4s1j%2FQIL8LpGbm3EZn9KeGdo4WK%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;1003&quot; height=&quot;590&quot; data-origin-width=&quot;1003&quot; data-origin-height=&quot;590&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;문제 해석&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 progresses 배포일자를 speed기준으로 구하고 ((100-93)/7) , ((100-30) / 30 )&lt;br /&gt;다음 인덱스가 해당 배포하는데 걸린 시간보다 적다면 함께 배포한다.&lt;br /&gt;ceil을통해 올림을 해준다면 배포가능 날짜가나오니 그것으로 풀어냄.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;pre id=&quot;code_1759469018375&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;cmath&amp;gt;

using namespace std;

vector&amp;lt;int&amp;gt; solution(vector&amp;lt;int&amp;gt; progresses, vector&amp;lt;int&amp;gt; speeds) {
    vector&amp;lt;int&amp;gt; answer;
    int count=-1;
    double temp=0;
    double max;
    for(int i=0;i&amp;lt;progresses.size();i++){
        temp = ceil((double)(100-progresses[i])/speeds[i]);
        //1 1 1 5 10 20
        if(max &amp;lt; temp){
            count++;
            answer.push_back(1);
            max = temp;
        }else if(max &amp;gt;= temp){
            answer[count] +=1;
        }
       max = max &amp;gt;= temp ? max : temp; 
    }
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;큐/스택으로 풀진못했지만 뭔가좀 뿌듯한코드&lt;br /&gt;반복문하나로 각 인덱스마다 처리해줌으로써 시간복잡도 O(N)까지 동일해서 좀 뿌듯해서 올린리뷰코드&lt;/p&gt;</description>
      <category>알고리즘/C++</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/18</guid>
      <comments>https://kimbob-world.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv2-%EA%B8%B0%EC%88%A0%EA%B0%9C%EB%B0%9C-C-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4#entry18comment</comments>
      <pubDate>Fri, 3 Oct 2025 14:25:36 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스]Lv3 베스트앨범 C++ 문제풀이</title>
      <link>https://kimbob-world.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4Lv3-%EB%B2%A0%EC%8A%A4%ED%8A%B8%EC%95%A8%EB%B2%94-C-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42579&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/42579&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;베스트앨범&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;문제 :&amp;nbsp;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;659&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/o00JJ/btsQ3wGHTNt/22WtL4sVeGerkYsveVlQMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/o00JJ/btsQ3wGHTNt/22WtL4sVeGerkYsveVlQMK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/o00JJ/btsQ3wGHTNt/22WtL4sVeGerkYsveVlQMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fo00JJ%2FbtsQ3wGHTNt%2F22WtL4sVeGerkYsveVlQMK%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;726&quot; height=&quot;659&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;659&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;문제 해석&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장르와 플레이 수의 인덱스 번호는 같고 플레이 횟수는 다르다.&lt;br /&gt;map을 두개를 선언해 하나에는 반복문과 map(a)을 활용해 key:value값으로 장르별 plays를 합연산 해준다.&lt;br /&gt;다른 map(b)은 key와 value , index값을 미리저장해 이전에 저장해둔 map(a)의 합연산한것을 기준으로 출력해준다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;사용한 함수&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;sort (람다식을 활용한 value 내림차순 구현)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;map을 sort를 사용해서 정렬을 하려했지만&lt;br /&gt;key와 value의 형태로 되어있어서 vector를 통해 배열형태로 변경해준뒤 정렬해야한다.&lt;/p&gt;
&lt;pre id=&quot;code_1759466958983&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;bool cmp(pair&amp;lt;string,int&amp;gt; &amp;amp;a, pair&amp;lt;string,int&amp;gt; &amp;amp;b) { // 순서를 정하기위한 기준 함수
    return a.second &amp;gt; b.second; // value 기준 내림차순
}
map &amp;lt;string , int&amp;gt; temp; //map으로 장르와 value를 합연산을 통해 저장
vector&amp;lt;pair&amp;lt;string,int&amp;gt;&amp;gt; v(temp.begin),temp.end()); //sort를 통해 정렬하기위해 vector로 변환
//지정해둔 함수를 통해 비교할 값 a,b를 넘긴 후 내림차순 정렬
//a.second를 해준 이유는 장르 , 재생수 중 재생수를 기준으로 순서를 정하기 때문에 두번쨰값을 참조
sort(v.begin(),v.end(),cmp); 
//람다식 정렬
//일회용으로 사용할 것이라면 람다식을 활용해 굳이 함수화하지않는다.
sort(v.begin(),v.end(),([]auto &amp;amp;a , auto &amp;amp;b){
	return a.second &amp;gt; b.second;
})&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1759466590657&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;map&amp;gt;
#include &amp;lt;algorithm&amp;gt;
#include &amp;lt;iostream&amp;gt;

using namespace std;
//sort를 위해 정렬기준함수
bool cmp(pair&amp;lt;string,int&amp;gt; &amp;amp;a, pair&amp;lt;string,int&amp;gt; &amp;amp;b) {
    return a.second &amp;gt; b.second; // value 기준 내림차순
}

vector&amp;lt;int&amp;gt; solution(vector&amp;lt;string&amp;gt; genres, vector&amp;lt;int&amp;gt; plays) {
    vector&amp;lt;int&amp;gt; answer;
    map &amp;lt;string,int&amp;gt; temp;
    map &amp;lt;string , vector&amp;lt;pair&amp;lt;int,int&amp;gt;&amp;gt;&amp;gt; alldata;
    vector&amp;lt;string&amp;gt; sortsong;
    //키에 값을 넣고 해당값의 합을 일단 구해
    //그리고 그 값으로 순서를 정해
    for(int i=0;i&amp;lt;genres.size();i++){
        temp[genres[i]] += plays[i]; // 키  : 합
        alldata[genres[i]].push_back({plays[i],i}); // 키 : 값 , 인덱스
    }
    //각 종류들의 합을 구하기위해 map 사용
    //value값을 통해 비교해서 정렬하기위해 다시 vector로 변환
    vector&amp;lt;pair&amp;lt;string,int&amp;gt;&amp;gt; v(temp.begin(),temp.end());
    // 시작 , 끝 , 비교함수
    // 람다식 알고리즘을 활용해 1회용 메소드 생성 a,b를 매개변수에넣고 비교
    sort(v.begin(), v.end(),cmp);
    //키 : 값,인덱스
    for(auto &amp;amp;ss : alldata){
        auto &amp;amp;songs = ss.second;
        sort(songs.begin(),songs.end(),[](auto a,auto b){
            return a.first &amp;gt; b.first;
        });
    }
    for(int i=0;i&amp;lt;v.size();i++){
        for(int j=0;j&amp;lt;min(2,int(alldata[v[i].first].size()));j++){
        answer.push_back(alldata[v[i].first][j].second);
        }
    }
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떻게 풀어야할지는 알겟는데 방법을 모르는 느낌이였다.&lt;br /&gt;sort를통해서 정렬해야하는건 알겟지만 map은 key와 value형태로저장되어있어서&lt;br /&gt;어떻게 정렬해야할지 모르겠엇고 검색을 통해 sort의 사용법을 알게되서 풀었다.&lt;br /&gt;마지막 출력할때도 출력할때 하나만있을 가능성을 생각해서 min을 써준것 도움받은게 컸다..&lt;br /&gt;나중에 활용해야지&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignCenter&quot; data-emoticon-type=&quot;friends1&quot; data-emoticon-name=&quot;012&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/012.gif&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/012.gif&quot; width=&quot;150&quot; /&gt;&lt;/figure&gt;</description>
      <category>알고리즘/C++</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/17</guid>
      <comments>https://kimbob-world.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4Lv3-%EB%B2%A0%EC%8A%A4%ED%8A%B8%EC%95%A8%EB%B2%94-C-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4#entry17comment</comments>
      <pubDate>Fri, 3 Oct 2025 14:01:30 +0900</pubDate>
    </item>
    <item>
      <title>[STL] STL 도구 모음(알고리즘 풀이용)</title>
      <link>https://kimbob-world.tistory.com/entry/STL-STL-%EB%8F%84%EA%B5%AC-%EB%AA%A8%EC%9D%8C%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%ED%92%80%EC%9D%B4%EC%9A%A9</link>
      <description>&lt;pre id=&quot;code_1759749675817&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,1,2,3,4,5};
v.erase(unique(v.begin(),v.end()),v.end()); 
// unique를 통해 중복값을 얻고 earse를 통해 값을 삭제한다&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;내가 볼려고 만드는 알고리즘 풀이용 라이브러리 도구 모음&lt;/h1&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;하나씩 하나씩 추가해보자&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;#include &amp;lt;bits/stdc++.h&amp;gt;&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1.unordered_set**&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;중복 된 값들을 모두 없애고 들어온 순서대로 정렬해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;#include &amp;lt;map&amp;gt;&lt;map&gt;&lt;/map&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;map
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;key , value 로 값을 관리한다.&lt;/li&gt;
&lt;li&gt;key의 중복을 허용하지않는다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;key를 자동으로 정렬해서 순회 및 탐색에 유리하다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;범위 탐색 및 a-b부터 값을 순서대로 정렬하여 꺼내야할 때 유리함.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;multimap
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;key,value로 관리하는건 같지만 key의 중복을 허용한다.&lt;/li&gt;
&lt;li&gt;insert , erase를 통해 키의 입력 삭제를 관리&lt;/li&gt;
&lt;li&gt;하나의 키값으로 여러개를 관리할때 사용함.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;unordered_map
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자동으로 정렬되지않는다는 단점이 있지만 메모리 속도가 상향된다.&lt;/li&gt;
&lt;li&gt;키값의 검색을 통해 벨류값을 알아내고 수정/삭제 하는데 특화되어있음.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이전에 해당값이 있엇는지 확인하거나 , 특정 키값의 등장횟수를 세야할 때 유리함.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;#include&amp;lt;cmath&amp;gt;&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;sqrt
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;숫자의 제곱근을 구할때 쓰는 함수&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;#include &amp;lt;unordered_set&amp;gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. unordered_set&lt;br /&gt;&lt;/b&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;/li&gt;
&lt;li&gt;정렬되지않는 채로 없애주기때문에 속도가 빠름&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;#include &amp;lt;set&amp;gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. set&lt;/b&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;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;#include &amp;lt;algorithm&amp;gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. unique&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 배열은 그대로 유지한채로 중복된 값을 다른 쓰레기값으로 변경한다.&lt;br /&gt;ex) 1 1 2 3 4 1 1&amp;nbsp; =&amp;gt;&amp;nbsp; 1 2 3 4 1 1 1&lt;br /&gt;- erase함수를 통해 사용을 해야 1 2 3 4 1로 쓰레기값을 지우고 나온다.&lt;br /&gt;=&amp;gt; unique함수는 중복값을 제외하고 나머지는 쓰레기값으로 벡터의 배열을 채움.&lt;br /&gt;erase를 통해 시작값 = 찾은 중복값인덱스 부터 =&amp;gt; 맨뒤값까지는 삭제한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. sort&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 배열을 정렬해준다.&lt;br /&gt;&amp;nbsp; =&amp;gt; 숫자 : 1 2 3 4 5 8 9 =&amp;gt; 1 2 3 4 5 8 9&lt;br /&gt;- 문자도 가능&lt;br /&gt;sort(첫번째 값 , 마지막 값)&lt;br /&gt;=&amp;gt; vector : sort(arr.begin(),arr.end());&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;#include &amp;lt;vector&amp;gt;&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;find&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;백터에서 찾는 값에 인덱스를 반환한다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;find(백터 시작값 , 마지막값 , 찾을 값)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;ex) find(vector.begin(),vector.end(),찾을 값)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;distance&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;백터에서 시작 인덱스에서 내가 찾는 수의 주소값을 반환한다.&lt;/li&gt;
&lt;li&gt;distance(백터의 시작값 , 찾는 값)&lt;/li&gt;
&lt;li&gt;ex ) distance(vector.begin() , find(vector.begin(),vector.end() , &quot;찾을 값&quot;) );&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;erase&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;vector내부에서 값을 제거하기위해 사용하는 함수&lt;/li&gt;
&lt;li&gt;erase(백터 내부의 지울 값)&lt;/li&gt;
&lt;li&gt;ex) erase(vector.begin + &quot;find를통해 찾은 주소&quot; )&lt;/li&gt;
&lt;li&gt;ex) erase(vector.begin + 5) 를한다면 5번째 인덱스값을 삭제함.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;#include &amp;lt;queue&amp;gt;&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;priority_queue&lt;/b&gt; (우선 큐)
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;기본 vector구조로 이루어져있다&lt;/li&gt;
&lt;li&gt;priority_queue&amp;lt;변수타입(int , string ...) , 배열 타입(vector&amp;lt;int&amp;gt; , deque&amp;lt;int&amp;gt;) , 차순정리(greater&amp;lt;int&amp;gt;))&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;#include &amp;lt;cctype&amp;gt;&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;toupper()&lt;/b&gt;&lt;br /&gt;대문자로 바꾸기위해 사용하는 함수&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>자료구조</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/16</guid>
      <comments>https://kimbob-world.tistory.com/entry/STL-STL-%EB%8F%84%EA%B5%AC-%EB%AA%A8%EC%9D%8C%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%ED%92%80%EC%9D%B4%EC%9A%A9#entry16comment</comments>
      <pubDate>Wed, 1 Oct 2025 19:42:15 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스]Lv1 완주하지 못한 선수 C++ 문제 풀이</title>
      <link>https://kimbob-world.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4Lv1-%EC%99%84%EC%A3%BC%ED%95%98%EC%A7%80-%EB%AA%BB%ED%95%9C-%EC%84%A0%EC%88%98-C-%EB%AC%B8%EC%A0%9C-%ED%92%80%EC%9D%B4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42576&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/42576&lt;/a&gt;&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;해시 자료구조에서 Map을 사용했는데&lt;br /&gt;중복 값을 처리하기위해 Multimap 을 사용해서 구현했다.&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;size14&quot;&gt;수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때,&lt;br /&gt;완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;제한사항&lt;br /&gt;마라톤 경기에 참여한 선수의 수는 1명 이상 100,000명 이하입니다.&lt;br /&gt;completion의 길이는 participant의 길이보다 1 작습니다.&lt;br /&gt;참가자의 이름은 1개 이상 20개 이하의 알파벳 소문자로 이루어져 있습니다.&lt;br /&gt;참가자 중에는 동명이인이 있을 수 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;입출력 예&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 81.0465%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 40.7752%; text-align: left;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;participant&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25.8914%; text-align: left;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;completion&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.3798%; text-align: left;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;return&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 40.7752%; text-align: center;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;[&quot;leo&quot;, &quot;kiki&quot;, &quot;eden&quot;]&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25.8914%; text-align: center;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;[&quot;eden&quot;, &quot;kiki&quot;]&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.3798%; text-align: center;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&quot;leo&quot;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 40.7752%; text-align: center;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;[&quot;marina&quot;, &quot;josipa&quot;, &quot;nikola&quot;, &quot;vinko&quot;, &quot;filipa&quot;]&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25.8914%; text-align: center;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&amp;nbsp;[&quot;josipa&quot;, &quot;filipa&quot;, &quot;marina&quot;, &quot;nikola&quot;]&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.3798%; text-align: center;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&amp;nbsp;&quot;mislav&quot;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 40.7752%; text-align: center;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;[&quot;mislav&quot;, &quot;stanko&quot;, &quot;mislav&quot;, &quot;ana&quot;]&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25.8914%; text-align: center;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;[&quot;stanko&quot;, &quot;ana&quot;, &quot;mislav&quot;]&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.3798%; text-align: center;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&quot;mislav&quot;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&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;participant 값 안에 있으면서&amp;nbsp; completion 배열에 없는 선수를 찾는문제.&lt;br /&gt;이름 중복이 있을수 있음으로 해당 선수만 삭제할 것&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;&lt;b&gt;MuiltiMap&lt;br /&gt;&lt;/b&gt;기존 Map으로는 key값 중복처리가 어려워&lt;br /&gt;key값이 중복 가능한 MultyMapd을 사용하게됨.&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;pre id=&quot;code_1759309581007&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;map&amp;gt;

using namespace std;

string solution(vector&amp;lt;string&amp;gt; participant, vector&amp;lt;string&amp;gt; completion) {
    string answer = &quot;&quot;;
    multimap&amp;lt;string,bool&amp;gt; runners;
    
    for(const string&amp;amp; ss : participant){
        runners.insert({ss,true});
    }
    
    for(const string&amp;amp; cprunner: completion){
        auto it = runners.find(cprunner);
        runners.erase(it);
    }
    for(const auto&amp;amp; laterunner: runners ){
        answer = laterunner.first;
    }
    
    return answer;
}&lt;/code&gt;&lt;/pre&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;multimap을 통해 true false 로 값을 저장하고 //사실 벨류는 크게 의미가 없다;&lt;br /&gt;erase를 통해 completion에 있는 값을 지워준다.&lt;br /&gt;완주목록에 없는 유저를 마지막에 answer에 넣어준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 문제는 쉬웠지만 해당 코드를 리뷰하는 이유는&lt;br /&gt;기존에 사용하던 map과 헷갈리는 부분이 많아서 에러나는 부분이 많았다.&lt;br /&gt;해당문제를 나중에 만났을 때 실수를 하지않고싶어서 리뷰를 한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;1. insert를 이용해 값넣기&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;map은 runner[key] = true ; 방식으로 값을 넣었다면&lt;br /&gt;MultiMap은 insert 사용해서 넣어야한다.&lt;br /&gt;runner.insert({ key , true});&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;2. 값 수정 및 삭제할때 주의가 필요하다.&lt;br /&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 runner[key] = false; 를 통해서 수정했다면 여기서는 find함수를 통해 iterator(포인터의 주소) 값을 찾고 수정해줘야한다.&lt;br /&gt;(아니면 중복되는 모든 key값의 벨류가 변경됨)&lt;br /&gt;auto it = runner.find(key) 를통해 해당 키값의 주소를 it에 넣어주고&lt;br /&gt;runner.erase(it) 실행한다면 해당 주소값에 있는 키만 삭제된다&lt;br /&gt;수정 시&amp;nbsp; runner.secone(value)를 통해 접근해야한다. // first : key , second : value&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;3. Key에 접근&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;answer = laterunner 로 접근했을때 에러가 났다.&lt;br /&gt;해당 값에는 key와 value로 이루어져있기 때문이였고&lt;br /&gt;그래서 key값인 first를 통해 key값으로 접근해야했다.&lt;/p&gt;</description>
      <category>알고리즘/C++</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/15</guid>
      <comments>https://kimbob-world.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4Lv1-%EC%99%84%EC%A3%BC%ED%95%98%EC%A7%80-%EB%AA%BB%ED%95%9C-%EC%84%A0%EC%88%98-C-%EB%AC%B8%EC%A0%9C-%ED%92%80%EC%9D%B4#entry15comment</comments>
      <pubDate>Wed, 1 Oct 2025 18:43:49 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스]Lv2 전화번호 목록 C++ 문제풀이</title>
      <link>https://kimbob-world.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4Lv2-%EC%A0%84%ED%99%94%EB%B2%88%ED%98%B8-%EB%AA%A9%EB%A1%9D-C-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42577&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/42577&lt;/a&gt;&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;왜 다양한 알고리즘을 풀어야하는지에 대한 궁금함이 있엇는데&lt;br /&gt;이번 문제를 통해 어느정도 풀린 것 같다.&lt;br /&gt;사실 처음에는 for문으로 풀고있엇는데 해시를 공부하고싶어서 들어온 문제인데 내가 해시를 몰라서 검색을 해봤다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해시란 Key와 value로 이루어진 값을 말한다.&lt;br /&gt;기존 배열은 인덱스를 통해서 value를 찾아야한다면 해시는 key를 통해 value를 찾을 수 있는 장점이 있다.&lt;br /&gt;ex) 배열 : a[0] = &quot;김밥&quot; , a[1] = &quot;김밥천국&quot;&lt;br /&gt;해시 : a[김밥] = &quot;김밥천국&quot; 처럼 김밥이라는 key를 통해 &quot;김밥천국&quot;이라는 데이터를 가져 올 수 있기때문에 &lt;br /&gt;속도면에서 확실한 우위를 가져온다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[ TMI ]&lt;/b&gt;&lt;br /&gt;이전 오픈채팅방을 풀때 for문으로 풀어서 오류난 부분을&lt;br /&gt;map함수를 사용해서 key,value를 통해 관리하라고 했는데&lt;br /&gt;그 방법또한 해시라는 자료구조를 사용해서 해결한 문제가 맞는것 같다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;사용한 기능&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;unordered_map&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;map을 통해 키-값을 관리하던 중&lt;br /&gt;해시태그와 map의 연관성을 묻던 중 unordered_map으로 풀면 검색기능에 유리하다는 말에 서치를 해보니&lt;br /&gt;map은 자동정렬 방식으로 데이터가 순서대로 쌓이기때문에&lt;br /&gt;데이터 순회나 범위 검색에 유리하지만 해당문제는 정렬은 필요가 없고&lt;br /&gt;unordered_map은 자동정렬은 안되는 대신&lt;br /&gt;key값을 참조해서 원하는 데이터를 즉시 확인하고 바로 값을 바꿀수 있기때문에 효율적이여서 사용하게됐다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;map.count(&quot;값&quot;)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;map내부에서 어떤 키를 찾을지 검색하면 존재 여부에 따라 0과 1의 반환값을 준다.&lt;br /&gt;조건문에서 해당 값이 key에 있는지 확인하기 위해 사용했다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;652&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5U1E2/btsQVujtzHA/KCsZF2modNsJn2LTtDKbc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5U1E2/btsQVujtzHA/KCsZF2modNsJn2LTtDKbc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5U1E2/btsQVujtzHA/KCsZF2modNsJn2LTtDKbc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5U1E2%2FbtsQVujtzHA%2FKCsZF2modNsJn2LTtDKbc0%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;729&quot; height=&quot;652&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;652&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세번째를 입출력 예제로 든다면 1번째 인덱스인 &quot;123&quot;은 0번째인덱스 값인 &quot;12&quot;값으로 시작하기 때문에&lt;br /&gt;접두어 문자라고 해석했다.&lt;br /&gt;&quot;123&quot; 또한 &quot;1235&quot;라는 숫자안에 &quot;123&quot;으로 똑같이 시작하기때문에 접두어 문자이다.&lt;br /&gt;&lt;b&gt;i+1 인덱스가 이 i로 시작하는가 ?&lt;/b&gt; 이루어진 문제를 푸는것이라고 생각했다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;pre class=&quot;cpp&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;unordered_map&amp;gt;

using namespace std;

bool solution(vector&amp;lt;string&amp;gt; phone_book) {
    bool answer = true;

    //map에 담아주기위해 key값 생성
    unordered_map&amp;lt;string ,bool&amp;gt; ph_book;

    //배열별로 나눠서 key : true 로 저장
    for(const string&amp;amp; ph : phone_book){
        ph_book[ph] = true;
    }

    for(const string&amp;amp; n : phone_book){
        //문자열 하나씩 추가하며 비교
        string pf = &quot;&quot;;
        for(char c:n){
            //해당 배열의 값을 하나씩 pf에 넣기
            pf+=c;
            //pf값이 ph_book안에 있는지 확인
            // pf !=n  =&amp;gt; 자기자신은 x
            if(ph_book.count(pf) &amp;amp;&amp;amp; pf != n){
                answer = false;
                return answer;
            }
        }
    }

    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;for문을 통해 구현하다가 이건 해시가 아니지않나 라는 생각에 검색하여 Map으로 구현하게 됐고&lt;br /&gt;사용하다보니 오픈채팅방 구조와 비슷해서 초반구조를 가져왔다.&lt;br /&gt;이후 구조는 ai에게 피드백받으며(많이) 수정된 코드이다. (_ _) 반성하는 표정&lt;/p&gt;</description>
      <category>알고리즘/C++</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/14</guid>
      <comments>https://kimbob-world.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4Lv2-%EC%A0%84%ED%99%94%EB%B2%88%ED%98%B8-%EB%AA%A9%EB%A1%9D-C-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4#entry14comment</comments>
      <pubDate>Wed, 1 Oct 2025 03:12:01 +0900</pubDate>
    </item>
    <item>
      <title>[React]리액트 마크다운 ( Toast ui Editor )</title>
      <link>https://kimbob-world.tistory.com/entry/React%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%A7%88%ED%81%AC%EB%8B%A4%EC%9A%B4-Toast-ui-Editor</link>
      <description>&lt;h1 id=&quot;리액트-toast-ui-editor-적용법&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;리액트 Toast ui Editor 적용법&lt;/h1&gt;
&lt;h2 id=&quot;1-에디터-다운로드&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;1. 에디터 다운로드&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;npm install --save @toast-ui/react-editor&lt;/p&gt;
&lt;h2 id=&quot;2-해당-에디터를-임포트-시키기&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;2. 해당 에디터를 임포트 시키기&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해당 에디터를 임포트할 때 css도 같이 임포트를 해오셔야합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;nginx&quot; style=&quot;background-color: #fbfcfd; color: #212529; text-align: start;&quot;&gt;&lt;code&gt;import { Editor } from '@toast-ui/react-editor';
import '@toast-ui/editor/dist/toastui-editor.css';&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그 외 임포트한 것들의 설명에 대해 아래 에딧정보를 쓰며 설명하겟습니다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; style=&quot;background-color: #fbfcfd; color: #212529; text-align: start;&quot;&gt;&lt;code&gt;import React, { useEffect, useState } from 'react'

import { Editor } from '@toast-ui/react-editor';
import '@toast-ui/editor/dist/toastui-editor.css';
import '@toast-ui/editor/dist/theme/toastui-editor-dark.css';
import colorSyntax from '@toast-ui/editor-plugin-color-syntax';

function WritePage() {

    const textRef = React.createRef();

    const [descriptions, setDescriptions] = useState(&quot;&quot;)


    const handleChangeInput = () =&amp;gt; {
 		setDescriptions(textRef.current.getInstance().getMarkdown()
     	)
     }

    return (
          &amp;lt;div className='Write_page'&amp;gt;
              &amp;lt;Editor
                  ref={textRef}  // input값을 가져오기 위해 ref생성
                  previewStyle=&quot;vertical&quot;  // 미리보기 유형 (tab , vertical)
                  initialValue={description}  // input 입력 값
                  height=&quot;840px&quot;  // 에디터의 높이값  width 값의 변경을 원한다면 상위 컴포넌트의 값을 변경해주세요 !
                  autofocus={false}  // 페이지 들어올 시 자동으로 포커스
                  initialEditType=&quot;markdown&quot;  // 타입  : 'markdown' 과 일반 텍스트형태인 'wvsiwyg' 존재 
                  theme='dark'  // 테마입니다 다크모드 가능!
                  useCommandShortcut={true}
                  onChange={handleChangeInput}  // 해당 이벤트를 통해 값을 status에 저장합니다 
                  placeholder=&quot;내용을 입력해주세요 :)&quot; 

              /&amp;gt;
          &amp;lt;/div&amp;gt;


    )
}

export default WritePage&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&quot;기능별-정리&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;기능별 정리&lt;/h1&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 id=&quot;1-ref&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;1. ref&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;textRef를 이용해 Edit의 인풋값을 onchange이벤트로 값을 descriotion으로 넣습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;coffeescript&quot; style=&quot;background-color: #fbfcfd; color: #212529; text-align: start;&quot;&gt;&lt;code&gt;const handleChangeInput = () =&amp;gt; {
        setDescriptions(
   			textRef.current.getInstance().getMarkdown()
        )
    }&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;2-previewstyle&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;2. previewStyle&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;미리보기의 스타일을 지정하는 값입니다.&lt;/p&gt;
&lt;pre class=&quot;ini&quot; style=&quot;background-color: #fbfcfd; color: #212529; text-align: start;&quot;&gt;&lt;code&gt;previewStyle=&quot;vertical&quot;  // 미리보기 유형 (tab , vertical)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;vertival&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;vertival&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;vertival은 쓰면서 바로바로 적용된 마크다운을 볼 수 있습니다.&lt;br /&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;644&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vL486/btsQXJTHJjO/PqC8KncEI9TOq7iTrVLNP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vL486/btsQXJTHJjO/PqC8KncEI9TOq7iTrVLNP0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vL486/btsQXJTHJjO/PqC8KncEI9TOq7iTrVLNP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvL486%2FbtsQXJTHJjO%2FPqC8KncEI9TOq7iTrVLNP0%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;1280&quot; height=&quot;644&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;644&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;tab&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;tab&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;tab는 마크다운 미리보기와 글쓰는곳이 따로떨어져있습니다.&lt;br /&gt;상단 preview를 누른다면 쓴 글에 대한 마크다운을 볼 수 있습니다.&lt;br /&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;638&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blfbMO/btsQVNCWr92/Vq087Hzzo9HdG48Ac4OSB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blfbMO/btsQVNCWr92/Vq087Hzzo9HdG48Ac4OSB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blfbMO/btsQVNCWr92/Vq087Hzzo9HdG48Ac4OSB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblfbMO%2FbtsQVNCWr92%2FVq087Hzzo9HdG48Ac4OSB0%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;1280&quot; height=&quot;638&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;638&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;3-initialvalue&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;3. initialValue&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;input 요소의 value값이라고 생각하시면 됩니다.&lt;br /&gt;하지만 조금 다른것은 ref를 통해 값을 description에 넣어줘야합니다.&lt;br /&gt;값을 onChange 이벤트를 통해 마크다운 안의 값을 description 안에 넣습니다.&lt;/li&gt;
&lt;li style=&quot;background-color: #fbfcfd;&quot;&gt;ref = {textRef} initialValue = {description} onChange = {handleChangeInput}&lt;/li&gt;
&lt;li&gt;onChange이벤트를 사용하여 ref를 통해 마크다운 값을 description에 넣습니다.&lt;/li&gt;
&lt;li&gt;
&lt;pre class=&quot;jboss-cli&quot; style=&quot;background-color: #fbfcfd;&quot;&gt;&lt;code&gt;const handleChangeInput = () =&amp;gt; {
        setDescriptions(
            textRef.current.getInstance().getMarkdown()
              {/* 마크다운 방식으로 저장합니다
              ex) 
              # 김밥이에요
              1. 안녕하세요
              2. 반가워요
              */}

            OR

            textRef.current.getInstance().getHTML()
              {/* html 방식으로 저장합니다
              ex)
                &amp;lt;h1&amp;gt; #김밥이에요 &amp;lt;/h1&amp;gt;
                &amp;lt;h2&amp;gt; 1. 안녕하세요 &amp;lt;/h2&amp;gt;
              */}
        )
    }&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;4-initialedittype&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;4. initialEditType&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;마크다운 방식을 지정합니다&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;markdown&lt;br /&gt;markdown 방식을 사용하여 글쓰는 타입입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;javascript&quot; style=&quot;background-color: #fbfcfd; color: #212529; text-align: start;&quot;&gt;&lt;code&gt;// 마크다운 방식 저장 방법
const handleChangeInput = () =&amp;gt; {
        setDescriptions({
        description: 
            textRef.current.getInstance().getMarkdown()
        })
    }&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;wysiwyg&lt;br /&gt;텍스트 , 코드 , 사진 등을 쓸 수 있는 텍스트 창입니다&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;javascript&quot; style=&quot;background-color: #fbfcfd; color: #212529; text-align: start;&quot;&gt;&lt;code&gt;// html 방식 저장 방법
const handleChangeInput = () =&amp;gt; {
        setDescriptions({
        description: 
            textRef.current.getInstance().getHTML()
        })
    }&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;5-theme--다크모드&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;5. theme / 다크모드&lt;/h2&gt;
&lt;h3 id=&quot;해당-에디터의-다크모드를-설정가능하게-해주는-설정입니다&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;해당 에디터의 다크모드를 설정가능하게 해주는 설정입니다&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일단 다크모드 설정을 위한 임포트를 하나 해줘야 해요&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;nginx&quot; style=&quot;background-color: #fbfcfd; color: #212529; text-align: start;&quot;&gt;&lt;code&gt;import '@toast-ui/editor/dist/theme/toastui-editor-dark.css'&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;상단에 다크모드 css를 임포트 한 후 Editor에&lt;br /&gt;theme = ' dark '&lt;br /&gt;설정을 해주시면 완료됩니다&lt;/p&gt;
&lt;pre class=&quot;xml&quot; style=&quot;background-color: #fbfcfd; color: #212529; text-align: start;&quot;&gt;&lt;code&gt;&amp;lt;Editor
 	theme='dark'       
 /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이미지도 업로드기능은 아직 완전한 이해를 못해&lt;br /&gt;차차 기능을 추가하며 업로드할 생각이다&lt;/p&gt;</description>
      <category>React/Library</category>
      <category>react</category>
      <category>TOAST UI</category>
      <category>리액트</category>
      <category>리액트마크다운</category>
      <category>마크다운</category>
      <category>마크다운에디터</category>
      <category>에디터</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/13</guid>
      <comments>https://kimbob-world.tistory.com/entry/React%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%A7%88%ED%81%AC%EB%8B%A4%EC%9A%B4-Toast-ui-Editor#entry13comment</comments>
      <pubDate>Tue, 30 Sep 2025 20:36:46 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] Lv2 점찍기 C++ 문제풀이</title>
      <link>https://kimbob-world.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv2-%EC%A0%90%EC%B0%8D%EA%B8%B0-C-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/140107&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/140107&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;점찍기&lt;/b&gt;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제 :&lt;/h2&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;좌표평면을 좋아하는 진수는 x축과 y축이 직교하는 2차원 좌표평면에 점을 찍으면서 놀고 있습니다. 진수는 두 양의 정수 k, d가 주어질 때 다음과 같이 점을 찍으려 합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;원점(0, 0)으로부터 x축 방향으로 a*k(a = 0, 1, 2, 3 ...), y축 방향으로 b*k(b = 0, 1, 2, 3 ...)만큼 떨어진 위치에 점을 찍습니다.&lt;/li&gt;
&lt;li&gt;원점과 거리가 d를 넘는 위치에는 점을 찍지 않습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;예를 들어, k가 2, d가 4인 경우에는 (0, 0), (0, 2), (0, 4), (2, 0), (2, 2), (4, 0) 위치에 점을 찍어 총 6개의 점을 찍습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;정수 k와 원점과의 거리를 나타내는 정수 d가 주어졌을 때, 점이 총 몇 개 찍히는지 return 하는 solution 함수를 완성하세요.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;제한 사항&lt;/h2&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;1 &amp;lt;= k &amp;lt;= 1,000,000&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;1 &amp;lt;= d &amp;lt;= 1,000,000&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;예제 입 출력&lt;/h2&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;k&lt;/th&gt;
&lt;th&gt;d&lt;/th&gt;
&lt;th&gt;result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;문제 해석&lt;/h3&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;2차원 좌표 평면에서 좌표값이 k(2)씩 이동하면서 원점거리 d를 넘을 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;((0 0) , (0,2) (0,4),(2,0),(2,2),(4,0))&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;좌표값 거리계산 공식 x&amp;sup2; * y&amp;sup2; = d&amp;sup2; 을 사용해서 문제를 풀었다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;사용한 함수&lt;/b&gt;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;sqrt&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제곱근을 찾아주는 함수.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;x와 d가 제공되어있으니 x를 이항하여 d&amp;sup2;-x&amp;sup2;=y 로 계산하여 y의 제곱근을 계산하기위해 사용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소수값이 나와도 필요한건 소숫점을 제외한 정수이기 때문에 double타입으로 계산&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제풀이&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 2중 for문을 돌려&amp;nbsp; 변수 &lt;span&gt;&lt;b&gt;i&lt;/b&gt; , &lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;j&lt;/b&gt;&lt;/span&gt; 두개 선언하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 방법을 통해 계산을 했더니 통과는되지만 일부 100만이 넘는 테스트케이스에서 실행시간오류가 났다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 for문을 하나만 사용하게 됐으며 내가 사용한 풀이방법은&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;반복문 하나없이 어떻게 x가 한번 움직일때마다 j만큼 움직이게 할 수 있을까였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 필요한건 &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;( j x j )&lt;/b&gt;&lt;/span&gt; 값 이였기 때문에 d&amp;sup2; -&amp;nbsp; i&amp;sup2; = y ( j x j )까지는 쉽게 계산이 됐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 y의 제곱근 / k(한번 이동할때 이동 수) 를 해준다면 점을 몇번 찍었는지 횟수가 나왔다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 첫시작값&amp;nbsp;&lt;span style=&quot;color: #ef5369;&quot;&gt;ex) (0,0) , (2,0) , (4,0)&lt;/span&gt; 은 계산되지않기 때문에 +1을 통해 시작값을 하나 넣어주고시작했다.&lt;/p&gt;
&lt;pre class=&quot;matlab&quot;&gt;&lt;code&gt;if((i*i) * (j*j) &amp;lt;= d*d){
        answer++;
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;cpp&quot;&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;cmath&amp;gt;

using namespace std;

long long solution(int k, int d) {
    long long answer = 0;
    long long i,y,temp=d;
    for(i=0;i&amp;lt;=d;i+=k){
        y = (temp * temp) - (i*i);

        y=std::sqrt(y);
        answer += (y/k)+1;
    }

    return answer;
}&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;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;삽질코드 모음&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1759225548223&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdbool.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

//거리값을 계산
//좌표값이 거리값 d를 넘으면 안됨
//x*x * y*x &amp;lt;= d*d

long long solution(int k, int d) {
    long long answer = 0;
    int count=0;
    for(int i=0;i&amp;lt;=d;i+=k){
        for(int j=0;j&amp;lt;=d;j+=k){
            if((j*j) + (i*i) &amp;lt;= d*d){
                answer++;
            }
        }
    }
    
    
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 최초의 2중반복문을 활용한 코드다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 i와 j값에 int를 사용해서 에러가 많이났다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;검색을 통해 int가 아닌 long long을 사용했고 여기서 answer 에 long long이 왜 붙은지 이해했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1759225701201&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdbool.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

//거리값을 계산
//좌표값이 거리값 d를 넘으면 안됨
//x*x * y*x &amp;lt;= d*d

long long solution(int k, int d) {
    long long answer = 0;
    long long i,j;
    
    for(i=0;i&amp;lt;=d;i+=k){
        for(j=0;j&amp;lt;=d;j+=k){
            if((i*i) + (j*j) &amp;lt;= (long long)d*d){
                answer++;
            }
        }
    }
    
    
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 수정하고 d*d도 강제로 long long으로 형변환해줬지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;for문이 두개라는 문제점때문에 3개정도의 테스트케이스에서 시간초과 에러가 나서 반려된 코드다&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;color: #ef6f53;&quot;&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;color: #ef6f53;&quot;&gt;&lt;b&gt;for문 두개로 하면쉽지만 처음으로 시간복잡도라는걸 경험한 코드이고&lt;br /&gt;for문 두개를 하나로 줄이는 작업은 &lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #ef6f53;&quot;&gt;&lt;b&gt;오래걸렸지만 정말 즐거운 경험이였다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>알고리즘/C++</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/12</guid>
      <comments>https://kimbob-world.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv2-%EC%A0%90%EC%B0%8D%EA%B8%B0-C-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4#entry12comment</comments>
      <pubDate>Tue, 30 Sep 2025 18:50:06 +0900</pubDate>
    </item>
    <item>
      <title>Fragment를 이용한 일부 레이아웃 전환시 다음Fragment에 값 전달하기</title>
      <link>https://kimbob-world.tistory.com/entry/Fragment%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EC%9D%BC%EB%B6%80-%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83-%EC%A0%84%ED%99%98%EC%8B%9C-%EB%8B%A4%EC%9D%8CFragment%EC%97%90-%EA%B0%92-%EC%A0%84%EB%8B%AC%ED%95%98%EA%B8%B0</link>
      <description>&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Fragment란?
&lt;pre class=&quot;kotlin&quot;&gt;&lt;code&gt; class SignUpFragment02 : Fragment() {

     // binding함수를 이용한 id객체값 참조하기.
     private var _binding: FragmentSignup02Binding? = null
     private val binding get() = _binding!!

     // fragment를 사용하기위한 핵심파라미터 
     // inflater =&amp;gt; xml -&amp;gt; View로 바꾸는 도구
     // container =&amp;gt; 이 Fragment가 들어갈 부모 뷰
     // savedInstanceState =&amp;gt; 앱이 꺼졌다 다시 켜졌을때 기존 입력을 복구할 상태 정보
     override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
         _binding =  FragmentSignup02Binding.inflate(inflater, container, false)
         return binding.root
     }

     override fun onViewCreated(view:View,savedInstanceState:Bundle?){
         ...뷰 내부 함수 

         // 뷰 내부의 btn_next라는 id값의 버튼 클릭 시 이벤트 함수
         view.findViewById&amp;lt;Button&amp;gt;(R.id.btn_next).setOnClickListener{
             //binding함수를 통해 emailInputField의 text정보를 가져와 String형태로 변환
             val currentEmail = binding.emailInputFiled.text.toString()

             // Bundle을 이용해 데이터를 Key-Value값으로 전달해준다.
             // email이라는 key값으로 사용자 입력값 을 저장장
             val bundle = Bundle().apply{
                 putString(&quot;email&quot;,currentEmail)
             }

             // 다음 Fragment를 지정해준 뒤 Fragment에있는 arguments라는 프로퍼티를 통해 값을 전달하고 받아와서 사용한다
             // key-value값 형태로 &quot;email&quot; Key값 전송 
             val nextFragment = SignUpFragment03().apply{
                 argument = bundle
             }

             // 부모값의 fragmeLayout8(바뀌는 UI부분)를 nextFragment로 변경해준다.
             // 뒤로가기 활용을 위한 스택 저장 
             // commit()을 통해 지금까지 정의한 작업들을 실행합니다.
             parentFragmentManager.beginTransaction()
                 .replace(R.id.frameLayout8, nextFragment)
                 .addToBackStack(null)
                 .commit()
         }
     }
 }

     class SignUpFragment02 : Fragment() {
         private var _binding: FragmentSignup03Binding? = null
         private val binding get() = _binding!!

         override fun onCreateView(...){
             ...
         }
         override fun ViewCreated(...){
             super.onViewCreated(view,savedInstanceState)

             // 코틀린은  Null에 민감하다!
             // NPE(Null Point Exception) 을 조심하자자
             // 바로 앱 크래시 나버림
             val email = arguments?.getString(&quot;email&quot;) ?: &quot;&quot;

             //binding함수를 이용해 emailTextView라는 id값에 text형태로 넣어주기.
             binding.emailTextView.text = &quot;${email}\n 해당 이메일로 인증번호를 발송했습니다.&quot;
         }

     }&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;하나의 Activity내에서 일부화면을 구성하는 모듈화 컴포넌트이다.&lt;br /&gt;화면 전환 시 전체를 바꾸지않고 fragment를 활용하여 일부 레이아웃만 동적으로 변경할 수 있다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>안드로이드 스튜디오</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/11</guid>
      <comments>https://kimbob-world.tistory.com/entry/Fragment%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EC%9D%BC%EB%B6%80-%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83-%EC%A0%84%ED%99%98%EC%8B%9C-%EB%8B%A4%EC%9D%8CFragment%EC%97%90-%EA%B0%92-%EC%A0%84%EB%8B%AC%ED%95%98%EA%B8%B0#entry11comment</comments>
      <pubDate>Mon, 29 Sep 2025 14:15:39 +0900</pubDate>
    </item>
    <item>
      <title>Binding 함수를 이용해 id값을 참조하여 이벤트 구현</title>
      <link>https://kimbob-world.tistory.com/entry/Binding-%ED%95%A8%EC%88%98%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%B4-id%EA%B0%92%EC%9D%84-%EC%B0%B8%EC%A1%B0%ED%95%98%EC%97%AC-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EA%B5%AC%ED%98%84</link>
      <description>&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Binding 함수를 이용해 id값을 참조하여 이벤트 구현
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Fragment에서의 활용&lt;/li&gt;
&lt;li&gt;Fragment같은 경우 Activity와 다르게 하나의 화면에서 일부레이아웃만 변동되기 때문에&lt;br /&gt;기존 Fragment가 살아남아있으며 메모리 누수 또는 NPE(Null Point Exception)를 일으킬 수 있다.&lt;br /&gt;그렇기 때문에 _binding을 통해 생명주기를 관리해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;kotlin&quot;&gt;&lt;code&gt;    //예시) 작성된 이메일 인증번호 입력 시 EditText 자동이동

    import com.example.onstartMobileApp.databinding.FragmentSignup03Binding

    //FragmentSignup03Binding &amp;lt;- 해당 파일은 xml 생성 시 자동으로 생성 
    //ex)FragmentSignup03.xml &amp;lt;- 생성 시 자동으로 생성됨

    private var _binding : FragmentSignup03Binding? = null //Null 허용
    private val binding get() = _binding!! // 실제 사용시에는 !!(non-null)을 통해 해당값이 Null이 아님을 명시해준다.

    // 1. View 생성
    override fun onCreateView(inflater: LayoutInflater, contrainer: ViewGroup?, savedInstanceState: Bundle?):View{
        _binding = FragmentSignup03Binding.inflate(inflater,container,false)
        return binding.root
    }
    // 2. View 생성 이후 사용 이때 binding 함수 사용
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val email = arguments?.getString(&quot;email&quot;) ?: &quot;&quot;

        //binding을 통해 CheckedEmailId라는 ID값을 가진 항목을 참조에 해당 text를 넣어준다.
        binding.CheckedEmailId.text=&quot;${email}\n 해당 이메일로 인증번호를 발송했습니다.&quot;

        setupEditTextAutoMove() // 텍스트 오토무브 함수
        binding.finishBtn.setOnClickListener {
            startActivity(Intent(requireContext(), HomeActivity::class.java))
        }
    }

    // 3. View소멸 시 binding해제
    override fun onDestoryView(){
        _binding = null //메모리 누수방지를 위한 Null 처리
        super.onDestroyView()
    }
    //그 외 **함수**
    private fun setupEditTextAutoMove(){
        ...이메일 오토무브 함수
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;_binding&lt;/span&gt;&lt;/b&gt;을 해주는 이유는 실제 View가 &lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;onCreateView &lt;/b&gt;&lt;/span&gt;생성 이전에는 값을 참조할 수 없기 때문에 Nullable(널 허용)형태로 초기한 후 View 생성 이후에는 &lt;br /&gt;val binding get = _binding!!(non-null)을 통해 선언해준 뒤 &lt;br /&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;onCreateView&lt;/span&gt;&lt;/b&gt; 또는 &lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;onViewCreated &lt;/b&gt;&lt;/span&gt;통해 View의 생명주기가 살아있는 동안에만&lt;br /&gt;안전하게 접근해야합니다.&lt;br /&gt;그 후 해당 View 종료 이후에도 참조값(binding.Eidt.text = &quot;asdf&quot;)이 남아있다면&lt;br /&gt;&lt;span style=&quot;color: #00b1d2;&quot;&gt;메모리 누수&lt;/span&gt;가 발생하거나 &lt;span style=&quot;color: #00b1d2;&quot;&gt;없는 값을 참조하여 크래시현상&lt;/span&gt;이 날 수 있기 때문에 &lt;span style=&quot;color: #000000;&quot;&gt;onDestroyView&lt;/span&gt; 함수를 통해 모든 View객체 참조를 명시적으로 제거해줍니다. &lt;br /&gt;#### 한줄정리 : View는 &lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;onCreateView&lt;/span&gt;&lt;/b&gt;를 통해 생성되고 &lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;onDestroyView&lt;/span&gt;&lt;/b&gt;를 통해 사라지기때문에 생명주기 동안 안전하게 &lt;b&gt;&lt;span style=&quot;color: #ed6f63;&quot;&gt;binding&lt;/span&gt;&lt;/b&gt;을 사용하기위해 변수로 구분한다.&lt;/p&gt;</description>
      <category>안드로이드 스튜디오</category>
      <category>binding</category>
      <category>안드로이드스튜디오</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/10</guid>
      <comments>https://kimbob-world.tistory.com/entry/Binding-%ED%95%A8%EC%88%98%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%B4-id%EA%B0%92%EC%9D%84-%EC%B0%B8%EC%A1%B0%ED%95%98%EC%97%AC-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EA%B5%AC%ED%98%84#entry10comment</comments>
      <pubDate>Mon, 29 Sep 2025 13:43:50 +0900</pubDate>
    </item>
    <item>
      <title>[매일메일] 실행 컨텍스트란?</title>
      <link>https://kimbob-world.tistory.com/entry/%EB%A7%A4%EC%9D%BC%EB%A9%94%EC%9D%BC-%EC%8B%A4%ED%96%89-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8%EB%9E%80</link>
      <description>&lt;h3&gt;&amp;amp; 실행 컨텍스트&lt;/h3&gt;
&lt;h4&gt;실행 컨텍스트란 코드가 실행될때 만들어지는 작업환경입니다.&lt;/h4&gt;
&lt;p&gt;이 환경은 코드가 어디에서 사용할 수 있는지를 결정해주는데&lt;br&gt;크게 전역 실행/함수 실행 컨텍스트로 나뉘며&lt;br&gt;전역실행 컨텍스트란 프로그램이 시작할때 실행되며 전역변수 , 함수등이 포함됩니다.&lt;br&gt;이 컨텍스트는 프로그램내에서 어디서든 불러올수있는 환경의 변수를 뜻합니다&lt;br&gt;함수실행 컨텍스트란 함수가 실행될떄 내부의 매개변수 , 내부함수들을 포함한 합니다.&lt;br&gt;이 컨택스트내에서 실행된 변수나 함수는 해당 함수내에서만 사용 가능하며 해당함수가 종료되면 함께 종료됩니다.&lt;br&gt;이와 같이, 실행 컨텍스트는 코드 실행 시 필요한 변수, 함수, 스코프 체인, 그리고 this 바인딩 등의 정보를 관리하여 코드가 올바르게 동작하도록 돕습니다.&lt;/p&gt;</description>
      <category>면접질문 정리</category>
      <category>면접</category>
      <category>면접질문</category>
      <category>실행컨텍스트</category>
      <category>컨텍스트</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/9</guid>
      <comments>https://kimbob-world.tistory.com/entry/%EB%A7%A4%EC%9D%BC%EB%A9%94%EC%9D%BC-%EC%8B%A4%ED%96%89-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8%EB%9E%80#entry9comment</comments>
      <pubDate>Mon, 29 Sep 2025 13:28:22 +0900</pubDate>
    </item>
    <item>
      <title>[매일메일] 클로저란 ?</title>
      <link>https://kimbob-world.tistory.com/entry/%EB%A7%A4%EC%9D%BC%EB%A9%94%EC%9D%BC-%ED%81%B4%EB%A1%9C%EC%A0%80%EB%9E%80</link>
      <description>&lt;h1&gt;- 클로저란 ?&lt;/h1&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;함수가 선언될 시 외부변수(스코프)를 통해 기억 후&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;나중에 해당변수를 통해 재사용하기위한 함수&lt;/h3&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;function outer() {
    let count = 0;

    return function inner() {
        count++;
        console.log(count);
    };
}

const counter1 = outer();
counter1(); // 1
counter1(); // 2

const counter2 = outer(); // 새로운 클로저 생성
counter2(); // 여기서 다시 1부터 시작!&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;amp; 활용처&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;외부에서 접근하지 못하게 내부 데이터를 숨기고 싶을 때&lt;/li&gt;
&lt;li&gt;마치 private 변수처럼 만들 수 있음&lt;/li&gt;
&lt;li&gt;특정 함수를 만들어 내부변수 변경 가능함&lt;/li&gt;
&lt;li&gt;예시) 기존비밀번호를 숨기며 비밀번호 변경 !질문 Q&amp;amp;A
&lt;pre class=&quot;actionscript&quot;&gt;&lt;code&gt;나중에 해당변수를 통해 재사용하기위한 함수라면 모듈화를 말하는 건가요?
그리고 활용처에서 나온 말 중 외부에서 내부 변수를 숨기고 싶을 때 쓴다면
캡슐화 public private이런 것과 같은 건가요?&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;q. 캡슐화와 비슷한 건가요
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;A. : 네 맞습니다.
    캡슐화 같은경우 setName으로 초기화하거나 getName으로 값을 불러와야합니다.
    그와 비슷하게 closer또한 내부함수를 통해 값을 불러온다는 기능은 같습니다.&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Q. 해당변수를 통해 재사용하기위한 것이라면 모듈화를 뜻하는것인가요?
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code style=&quot;letter-spacing: 0px;&quot;&gt;A. : 모듈화와 비슷한 구조를 가지고있습니다
    데이터를 재사용함에 있어서는 모듈화와 비슷하지만
    함수 내부의 특정 데이터를 숨기거나 기억해서 지속적으로 사용할수있게 만든 기능입니다.&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;외부변수를 스코프라고 부르나요?
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;A. : 아닙니다.
    외부변수란 함수내부에서 사용하는 함수밖의 변수를 뜻합니다.
    스코프란 변수를 사용할 수 있는 범위 내를 뜻하는 말입니다.&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1774322877532&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function createUser(name) { 
	let secret = &quot;my-secret&quot;;
    return { getName: () =&amp;gt; name, getSecret: () =&amp;gt; 
    	secret setSecret: (newScreat) =&amp;gt; { secreat = newScreat }};
    }
const user = createUser(&quot;홍길동&quot;);
console.log(user.getSecret()); // &quot;my-secret&quot; user.setSecret(&quot;비밀변경됨!&quot;);
console.log(user.getSecret()); // &quot;비밀변경됨!&quot;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>면접질문 정리</category>
      <category>면접</category>
      <category>질의응답까지정리</category>
      <category>클로저</category>
      <category>프론트엔드</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/8</guid>
      <comments>https://kimbob-world.tistory.com/entry/%EB%A7%A4%EC%9D%BC%EB%A9%94%EC%9D%BC-%ED%81%B4%EB%A1%9C%EC%A0%80%EB%9E%80#entry8comment</comments>
      <pubDate>Mon, 29 Sep 2025 13:22:17 +0900</pubDate>
    </item>
    <item>
      <title>[백준] 진법변환 알고리즘</title>
      <link>https://kimbob-world.tistory.com/entry/%EB%B0%B1%EC%A4%80-%EC%A7%84%EB%B2%95%EB%B3%80%ED%99%98-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98</link>
      <description>&lt;h1&gt;2025.07.30&lt;/h1&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;C++ 알고리즘&lt;/h3&gt;
&lt;pre class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;#### 진법 변환하기
```
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

int main(){

    int n;
    char str[100];
    scanf(&quot;%s %d&quot;,str,&amp;amp;n);
    int result = 0;
    int gop=1;
    int temp;
    int len=strlen(str);
    for(int i=len-1; i &amp;gt;= 0; i--){
        if(str[i]-'A' &amp;lt; 0){
            temp=str[i]-'0';
        }else{
            temp = (str[i] - 'A' +10);
        }
        result += (temp * gop);
        gop *= n;
    }
    printf(&quot;%d&quot;,result);
    return 0;
}
```&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&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;&lt;br /&gt;if문을 이용하여 입력받은 값을 str[i]\(입력문자) - 'A'\(문자의 시작)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아스키값으로계산하여 문자는 10부터 시작한 숫자는 0부터시작한 후&amp;nbsp;&amp;nbsp;str[i] * gop을 통해 result를 통해 값을 누적 해 준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;gop에는&amp;nbsp;처음에는&amp;nbsp;10의0승이기때문에&amp;nbsp;1&amp;nbsp;&amp;nbsp;str[i]&amp;nbsp;x&amp;nbsp;1로&amp;nbsp;계산&amp;nbsp;한&amp;nbsp;뒤&amp;nbsp;gop*n&amp;nbsp;으로&amp;nbsp;해당&amp;nbsp;진수를&amp;nbsp;누적하여&amp;nbsp;36의&amp;nbsp;N승을&amp;nbsp;만들며&amp;nbsp;reulst를&amp;nbsp;이용해&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;하지만 맞춘 이후 c++문법을 보니 쉬운 함수가 있엇다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;strtol 진법변환 함수strtol(&quot;%d, (int)strtol(c,NULL,n));&lt;br /&gt;&lt;br /&gt;strtol을 통해 값,참조형NULL,바꾸고싶은 진수로 하면 쉽게 변환되는 함수가있엇다.&lt;br /&gt;&lt;br /&gt;Goat..이렇게 백준을 풀면서 알고리즘실력을 늘리고 다른사람 코드를 보며 비교하고 좋은 함수가있다면 익히며 나아가야겟다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1774705684025&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;cstdio&amp;gt; #include &amp;lt;cstdlib&amp;gt;
int main(){
char c[255];
int n;
scanf(&quot;%s %d&quot;, c, &amp;amp;n);
printf(&quot;%d&quot;, (int)strtol(c, NULL, n)); }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/C++</category>
      <category>c++</category>
      <category>알고리즘</category>
      <category>진법변환</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/7</guid>
      <comments>https://kimbob-world.tistory.com/entry/%EB%B0%B1%EC%A4%80-%EC%A7%84%EB%B2%95%EB%B3%80%ED%99%98-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98#entry7comment</comments>
      <pubDate>Mon, 29 Sep 2025 13:10:57 +0900</pubDate>
    </item>
    <item>
      <title>US:CODE 한달살이 (전체 개발프로세스 경험) 후기</title>
      <link>https://kimbob-world.tistory.com/entry/USCODE-%ED%95%9C%EB%8B%AC%EC%82%B4%EC%9D%B4-%EC%A0%84%EC%B2%B4-%EA%B0%9C%EB%B0%9C%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EA%B2%BD%ED%97%98-%ED%9B%84%EA%B8%B0</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;의성에서 한달간 지내며 얻은 것들&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 해커톤에서 떨어진 후 uscode에서 문자가 왔다.&lt;/p&gt;
&lt;pre class=&quot;prolog&quot;&gt;&lt;code&gt;로컬에서 살아보며, 문제해결 프로젝트도
[Web발신]
로컬에서 살아보며, 문제해결 프로젝트도 할 수 있는 프로그램 Us:Code 아카데미를 모집합니다.
평소 생각만 했던 프로젝트를 고객 검증까지 할 수 있는 절호의 기회!

전공자가 아니어도, 팀이 없어도 프로젝트를 하고싶으면 신청가능한 프로그램입니다.
AI를 활용한 바이브코딩 교육도 준비되어 있으니 한달안에 서비스 런칭이 가능!

모두 준비되어 있으니 가벼운 마음으로 몸만 오셔도 참여 가능합니다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;08.04~08.29 한달정도 의성에서 지내며 프로젝트를 하며&lt;br /&gt;식사와 숙소를 제공해주기에 개발자라면 안 갈 이유가없어 바로신청했고&lt;br /&gt;다행히 붙어서 가게되었다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1주차&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1일차는 서로 간단한 소개를 했고&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2일차에는 서로 소개하며 추구하는 아이디어나 기술을 말하고 팀빌딩을 이루었다.&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 구글스프린트를 진행하며 스토리보드,&lt;br /&gt;피그마를통한 프로토타입 제작 장기목표 및 타겟층을 잡으며&lt;br /&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;팀원은 Node.js에 경험이 있어 Docker 기반 통합 개발환경을 구축한 뒤,&lt;br /&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;이전 프로젝트에서 한 파일에 1600줄 이상 코드를 작성했던 바이브 코딩 문제가 있었기에&lt;br /&gt;최대한 컴포넌트를 세부화 하고 프론트엔드에서는 Mock API를 활용해&lt;br /&gt;필요한 스키마를 정의해 이를 백엔드 개발자에게 제공하여실제 API 개발이 빠르게 진행될 수 있도록 협업했습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;실제 이 부분에서 성장한걸 느꼈다는게 프로젝트 초기 AI의 도움을 받으며 &lt;br /&gt;내가 해야할 것을 명확히 설정하고 빠르게 진행한 점에서 성장함이 뿌듯했다.&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3 ~ 7일차&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아이디어 검증을 위해 직접 발로 뛰며&lt;br /&gt;상인분들과 대화했고&lt;br /&gt;의성에 실제로 필요한 것이 무엇인지 파악했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순한 개발보다는 기획과 사용자 요구를 탐색하는 데 더 집중한 프로젝트였습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2주차&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2주차에는 공무원분들과 대화할 기회가 있었고,&lt;br /&gt;그 전에 메이드인피플 대표님께서 기획의 단점과 보완점을&lt;br /&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;기존 QR/스탬프 랠리는 너무 평범하다는 의견에 따라&lt;br /&gt;게이미피케이션 요소를 추가했고,그 결과 루트형 퀘스트 방식을 도입했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 퀘스트 완료 보상으로 의성 대표 굿즈와 카드 스티커를 제공하는 아이디어를 더해 기획을 수정했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 PPT 작업과 실제 사례를 보강하며 하고 싶은 프로젝트가 아닌&lt;br /&gt;실제로 필요한 프로젝트로 다듬어 나갔습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;발표&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 발표에 군청분들과 얘기할 기회는저희에게 너무나 소중한 경험이였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에 개발만 하며 개발자만의 세상을 살다가 사람들의 니즈와&lt;br /&gt;내 프로젝트의 필요성을 시험하는 자리의 느낌이였고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저도 확신이 없었던 &lt;b&gt;&quot;이게 실제로 될까? &quot;&lt;/b&gt; 라는 느낌은 그 분들에게도&lt;br /&gt;&lt;b&gt;&quot;왜 의성에서 ?&quot;&lt;/b&gt; , &lt;b&gt;&quot;음 심심한데&quot;&lt;/b&gt; , &lt;b&gt;&quot;현실적으로 가능한가?&quot; &lt;/b&gt;느낌으로 다가온거 같습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;amp; 현실적인 질문들이 많았고 나는 추상적이였다.&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;QR만 두면 참여하겠지, 보상만 있으면 하겠지.&amp;rdquo;&lt;/b&gt;라고 생각했지만,&lt;br /&gt;돌아온 질문은 단순했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;&amp;ldquo;사람들이 굳이 QR을 찍을까요?&amp;rdquo;&lt;/b&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;br /&gt;실제로 참여할 이유와 경험을 만드는 데 집중하게 되었다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3주차&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;레퍼런스 참여&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1일차&lt;/b&gt;&lt;br /&gt;다양한 개발자 / 마케터 / 디자이너 분들이 오셨다.&lt;br /&gt;그분들은 현재 AI가 나왔고 우리는 그에맞춰서 어떻게 나아가는지&lt;br /&gt;어떻게 응용/사용하여 발전하고 있는지 설명해주셨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;되게 인상적인 말은 디자이너분의 말이였다.&lt;br /&gt;&quot;예전에는 각자의 역할이 있엇다면 지금은 역할의 공유다.&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;질문시간이 있어 내가 물었다.&lt;br /&gt;&lt;b&gt;&quot;사실 이제 AI가 뚝딱하면 디자인과 프론트가 만들어지는데 계속 공부해야할지 백엔드로 가야할지 모르겠어요&quot;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그에대한 답변을 해주셨다.&lt;br /&gt;&lt;b&gt;&amp;ldquo;백엔드 개발자분도 똑같이 말한다. AI가 다 만들어준다고.&lt;br /&gt;하지만 프론트엔드 개발자는 UI/UX, 즉 사용자 경험을 향상시키는 일을 고민하다 보면 오히려 더 바빠질 수밖에 없다.&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 말이 전부터 생각했지만 한번 더 생각하게 되는 계기가 됐고&lt;br /&gt;지금 날 또 불태울 수 있는 장작으로 쓰고있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2일차&lt;/b&gt;&lt;br /&gt;개발자로 지내다가 로컬에 오셔서 창업하신 분들을 만나는 자리였다.&lt;br /&gt;왜 개발자를 하다가 시골로 오시게됐는지 ,&lt;br /&gt;개발을 어떻게 응용하고 계신지 이 날은 개발적인 부분보다는 사업적인 얘기가 흥미로웠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사람들에게 필요한 니즈 , 하고싶은건 돈이 안되는것들이 많고 하고싶은 것을 하려면 투잡을 할정도로 바쁘게 일하시는 분 되게 멋있엇다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서는 현실을 들을 수 있엇다.&lt;br /&gt;2일차에 기억나는 말은&lt;br /&gt;&lt;b&gt;&quot;좀 약한데 , 이게 될까요 라는 말을 듣고 직접 만들어서 판매하며&lt;br /&gt;만들어 증명하는 방법밖엔 없었다&quot; &lt;/b&gt;였던거 같다. 기억을 더듬어서 하는거라 정확하지 않지만&lt;br /&gt;실제 군에서 사업을 따낼때 하셨다고 한다.&lt;br /&gt;안될꺼 같다했을 때 증명을 해서 해냈다는 사실이 되게 멋있어서 기억에 남는다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3주차 3-7일&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3주차에는 새로운 분들이 들어왔다.&lt;br /&gt;다양한 나라를 여행하시던 분도 계시고 10년차이상 개발자분, 등 많은분들이 왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀빌딩을 하시고 진행을 하시며 프로젝트 관련 다양한 얘기를 한 거같다. 마케팅을 어떻게 했는지 사실 개발자 뿐만아니라 마케터 , 데이터분석가 다양한분들이 있어 오히려 좋은 경험이였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마케팅을 어떻게 하시는지 그 마케팅을 데이터 분석가가 어떻게 쓰는지 되게 좋은 경험이였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 참고하여 내가 다녀온곳에 고양이 이미지를 띄우고 그것을 영상으로 만들어 랜선여행을 기획했다.&lt;br /&gt;그리고 프로젝트 지원금으로 광고를 하며 다양한 개발 프로세스를 느끼는 경험이였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자가 이만큼 들어오고 내 홈페이지에 들어왔구나&lt;br /&gt;관심을 가지는구나 하며 그것을 데이터로 만들고 ppt영상에 사용할 생각에 행복했다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4주차&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4주차는 대부분 발표 준비와 기획&amp;middot;마케팅에 시간을 집중했다.&lt;br /&gt;그동안 다녔던 장소들을 바탕으로 고양이 이미지를 합성해 영상을 만들고, 인스타에 업로드하며 광고도 진행했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 결국 중요한 질문은&lt;br /&gt;&lt;b&gt;&amp;ldquo;실제로 사람들이 어떻게 사용하게 만들 수 있을까?&amp;rdquo;&lt;/b&gt;,&lt;br /&gt;&lt;b&gt;&amp;ldquo;어떻게 해야 내 프로젝트가 선택될 수 있을까?&amp;rdquo;&lt;/b&gt;였다. 나름 열심히 했다고 생각했지만 아쉬움이 남았지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이번 경험을 통해 전체 개발 프로세스를 직접 체감할 수 있었고, 무엇보다 아이디어 검증 과정이 흥미로웠다.&lt;/b&gt;&lt;/p&gt;</description>
      <category>외부활동</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/6</guid>
      <comments>https://kimbob-world.tistory.com/entry/USCODE-%ED%95%9C%EB%8B%AC%EC%82%B4%EC%9D%B4-%EC%A0%84%EC%B2%B4-%EA%B0%9C%EB%B0%9C%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EA%B2%BD%ED%97%98-%ED%9B%84%EA%B8%B0#entry6comment</comments>
      <pubDate>Mon, 29 Sep 2025 13:03:09 +0900</pubDate>
    </item>
    <item>
      <title>[React] JWT를 이용한 로그인 유지</title>
      <link>https://kimbob-world.tistory.com/entry/JWT%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EC%9C%A0%EC%A7%80</link>
      <description>&lt;h1&gt;jwt (json wep token)&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 로그인 방식은 로그인 시 access_token 과 refresh_token을 발급해서&lt;br /&gt;로그인의 여부를 체크하는 방식입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex)해당 유저의 data를 받아오거나 보낼 때 access_token을 헤더에 같이 붙여서 보냅니다.&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt; const getCategoryList = () =&amp;gt; {
    axios.get(`url, data ,
    {
      headers:{
        Authorization : `Bearer ${localStorage.getItem('access_token')}`
    } 
    })
    .then(res =&amp;gt; { // 성공시 
     console.log(&quot;success&quot;)
    }).catch(error =&amp;gt; { // 실패 시 
      console.log(error)
  })
  }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 해당 access_token 및 refresh_token을 로컬스토리지에 저장했습니다&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;로그인 시 localStorage 저장 방법
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;const Login = (e) =&amp;gt;{
      axios.post(&quot;url&quot;, input)
      .then(res =&amp;gt;{ // 로그인 성공 시
          if (res.data.access_token){ //데이터에 access_token이 있다면
              localStorage.setItem('access_token', res.data.access_token)
              localStorage.setItem('refresh_token', res.data.refresh_token)
              alert(&quot;로그인 성공&quot;)
              navigate(&quot;/&quot;)
          }
          }
      ).catch(res =&amp;gt;{ // 로그인 실패 시
          alert(&quot;존재하지않는 이메일 이거나 비밀번호가 틀립니다.&quot;);
      })
  };&lt;/code&gt;&lt;/pre&gt;
서버에 아이디 비밀번호를 보내 db에서 정보를 확인 후&lt;br /&gt;access_token , refresh tokrn을 발급해줍니다.&lt;br /&gt;&lt;img src=&quot;https://velog.velcdn.com/images/h-young/post/56e1ff7a-7fdd-4845-b1ae-a33a672ce82c/image.png&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하면 이제 access_token과 refesh토큰은 무슨 역할인가?&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;access_token&lt;br /&gt;일부데이터를 보내거나 받을 때 해당 유저의 로그인 여부를 확인할 때 사용합니다.&lt;br /&gt;ex )&lt;br /&gt;로그인 시 발급받은 access_token을 해당 headers에 담아 보낸다.
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;      axios.post(`url`, formData,
              {
              headers: {
                   Authorization: `Bearer ${localStorage.getItem('access_token')}`
                  }
              })
              .then(res =&amp;gt; { // 성공 시 요청 실행
               console.log('success')
              }
              ).catch(error =&amp;gt; {
              console.log(error)
              })&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;refresh_token&lt;br /&gt;access_token의 경우 2시간정도 만료시간을 두는데 해당 access_token이 만료시 리프레시토큰으로 재발급을 받는 방식입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런방식으로 리프레시토큰에게 7일이상 정도의 만료기간을 주고&lt;br /&gt;해당 리프레시 토큰을 이용해 access_token이 만료됐다면 리프레시토큰을 서버로 보내 다시 access_token을 재발급 받아 사이트 로그인을 유지합니다.&lt;br /&gt;ex)&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;axios.post(&quot;http://127.0.0.1:8000/api/accounts/token/refresh/&quot;, 리프레시 토큰 유효 검사
        {
             refresh: localStorage.getItem('refresh_token')
         }).then(res =&amp;gt; { // 리프레시토큰이 만료되지않았다면 access_token 재발급
             localStorage.setItem('access_token' , res.data.access)
         }).catch(error =&amp;gt; {
             //리프레시가 없거나 만료상태 시 로그인 잔행
             localStorage.clear(); // 로컬스토리지 초기화
             window.location.href=&quot;/login&quot;

         })&lt;/code&gt;&lt;/pre&gt;</description>
      <category>React/기능구현</category>
      <category>API</category>
      <category>jwt</category>
      <category>PYTHON</category>
      <category>react</category>
      <category>로그인유지</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/5</guid>
      <comments>https://kimbob-world.tistory.com/entry/JWT%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EC%9C%A0%EC%A7%80#entry5comment</comments>
      <pubDate>Mon, 29 Sep 2025 12:56:31 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스]Lv2. 오픈채팅방 문제풀이 (stringstream,map)</title>
      <link>https://kimbob-world.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4Lv2-%EC%98%A4%ED%94%88%EC%B1%84%ED%8C%85%EB%B0%A9-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;C++ 문법을 모르는 나에게 3일정도를 쓰고도 Ai를 사용해서 풀게한 감사한 문제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42888&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/42888&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;오픈 카톡방&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 :&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카톡방에 들어온 유저가 이름을 변경 했을 때 이전 &quot;입장 로그&quot;에서 닉네임을 변경해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유저가 이름을 변경할 수 있는 방법은&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;재 입장(Enter) , 닉네임 변경(Change)가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;자세한 문제는 링크에서 확인하세요!&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #263747; color: #b2c0cc; text-align: left; border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody style=&quot;color: #000000;&quot;&gt;
&lt;tr style=&quot;color: #000000;&quot;&gt;
&lt;td style=&quot;background-color: #202b3d; color: #000000;&quot;&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;[&quot;Enter uid1234 Muzi&quot;, &quot;Enter uid4567 Prodo&quot;,&quot;Leave uid1234&quot;,&quot;Enter uid1234 Prodo&quot;,&quot;Change uid4567 Ryan&quot;]&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #202b3d; color: #000000;&quot;&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;[&quot;Prodo님이 들어왔습니다.&quot;, &quot;Ryan님이 들어왔습니다.&quot;, &quot;Prodo님이 나갔습니다.&quot;, &quot;Prodo님이 들어왔습니다.&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;&lt;span style=&quot;color: #ee2323;&quot;&gt;값은 vector를 통해 제공된다&lt;/span&gt;&lt;/p&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;span style=&quot;color: #f89009;&quot;&gt;stringstream&lt;/span&gt; 이란 문법하나를 가져왔다.&lt;/h4&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;- 사용한 주요 라이브러리 코드&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;stringstream&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;string을통해 받은 값을 공백을 기준으로 나누어 저장하고 값에따라 int나 float 으로 유동적으로 변환할수 있기때문에 사용&lt;/span&gt;&lt;/p&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Map&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #333333; text-align: start;&quot;&gt;유저의 입력을 Key,value 로 나누어 쓰려고 활용&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;처음에는 Map을 몰라서 모르는 채로 풀었는데 for문이 너무많아지면서 일부는 성공 일부는 실행시간 초과 오류 발생&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;Ai를 통한 검색 Map함수와 사용법을 알려줘서 유저아이디와 이름을Key,value로나누어 사용&lt;/span&gt;&lt;/p&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;for(const string&amp;amp; s : record)&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;처음에 vector에 담긴 입력값(record)를 받아와서 읽기위해서 사용 &lt;br /&gt;&amp;amp;를 사용하여 데이터를 하나 더 복사해서 사용하는게 아닌 참조하여 사용할 수 있도록 하여 메모리 낭비를 줄임.&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;해당 참조문자를 통해 원본데이터를 가져다 쓰는것이니 const를 활용하여 원본 문자가 변동되지 않도록 함.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;find&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;백터 값 시작 , 끝 , 찾을값을 넣어서 해당 배열에서 값이 있는지 찾음&lt;/span&gt;&lt;span&gt;변수로 저장 시 해당 배열의 주소값을 받을 수 있음&lt;/span&gt;&lt;span&gt;ex) &lt;/span&gt;&lt;span&gt;vector&amp;lt;string&amp;gt; str;&lt;/span&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; auto it = (str.begin(),str.end(),&quot;30&quot;)&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;distance&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;find를 통해 값이 있는지 확인하여 it(변수)에 저장&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;백터로 저장된 string 내부에서 해당값의 index위치를 찾기 위해 distance사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;int index = distance(string.begin(),it);&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;pre id=&quot;code_1759050462572&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;sstream&amp;gt;
#include &amp;lt;map&amp;gt;

using namespace std;

//구글링과 ai에게 질문해서 만들어진 코드

vector&amp;lt;string&amp;gt; solution(vector&amp;lt;string&amp;gt; record) {
    vector&amp;lt;string&amp;gt; answer;
    map&amp;lt;string, string&amp;gt; userInfo; // &amp;lt;Key: uid, Value: nickname&amp;gt; 형태의 map
    
    for(const string&amp;amp; str : record){
        //string값을 받아와 공백 기준으로 나눠준 뒤 
        // 문자열은 string 숫자 int로 자동변환을 위한 stringstream 사용
        stringstream ss(str);
        //map내부에 값을 넣기 위해 변수 선언(enter,uid1234,prodo)
        string command,uid,nickname;
        
        //ss를 통해 받아온 0번째 인덱스값의 Enter와 uid1234넣기
        ss &amp;gt;&amp;gt; command &amp;gt;&amp;gt; uid;
        
        //닉네임 변경 조건(재입장 , 닉네임변경)
        if(command == &quot;Enter&quot; || command == &quot;Change&quot;){
            //다 받고 남은 마지막 인덱스값 nickname에 할당
            ss &amp;gt;&amp;gt; nickname;
            //유저 이름을 uid라는 키값 안에 할당하기
            //uid가 중복된다면 nickname만 변경됨
            userInfo[uid] = nickname;
        }
    }
    for(const string&amp;amp; str:record){
        stringstream ss(str);
        string command,uid,nickname;
        ss &amp;gt;&amp;gt; command &amp;gt;&amp;gt; uid;
        
        if(command == &quot;Enter&quot;){
            answer.push_back(userInfo[uid] + &quot;님이 들어왔습니다.&quot;);
        }else if(command == &quot;Leave&quot;){
            answer.push_back(userInfo[uid] + &quot;님이 나갔습니다.&quot;);
        }
    }
    
    return answer;
}&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;Ai의 도움을 받아 Map함수를 이용해 구현한 코드다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Map을 통해 key에 uid값을 넣고 key에 해당하는 value에 nickname을 넣어준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Map의 특성상 key값은 중복 될 수 없기 때문에 같은 uid에 nickname이 새로 들어오면 최신 값으로 변경해준다.&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;이 후 최신화를 통해 저장된 userInfo의 uid : nickname을 입장/퇴장만 순서대로 표시해주면 끝난다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;해당 페이지 부터는&amp;nbsp; 2일간의 삽질..코드다&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1759053221221&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;sstream&amp;gt;
#include &amp;lt;algorithm&amp;gt;

using namespace std;

vector&amp;lt;string&amp;gt; solution(vector&amp;lt;string&amp;gt; record) {
    vector&amp;lt;string&amp;gt; answer;
    vector&amp;lt;string&amp;gt; temp;
    string word;
    vector&amp;lt;string&amp;gt; testTemp;

    int j=0;
    for(const string&amp;amp; str : record){
        istringstream ss(str);
        while(ss &amp;gt;&amp;gt; word){
            temp.push_back(word);    
        }
    }
    
    for(int i=0;i&amp;lt; record.size();i++){
        if(record[i].find(&quot;Enter&quot;) != string::npos){
            for(int l=0;l&amp;lt;testTemp.size();l++){
                if(testTemp[l].find(temp[j+1]) != string::npos){
                    testTemp[l +1] = temp[j+2];
                }
            }
                
            testTemp.push_back(temp[j+1]);
            testTemp.push_back(temp[j+2]);
            end:
            j+=3;
        }
        else if(record[i].find(&quot;Change&quot;) != string::npos){
            for(int k=0;k&amp;lt;testTemp.size();k++){
                if(testTemp[k].find(temp[j+1]) != string::npos ){
                    testTemp[k+1] = temp[j+2];
                }
            }
            j+=3;
        }else if(record[i].find(&quot;Leave&quot;) != string::npos ){
            for(int f=0;f&amp;lt;temp.size();f++){ //아이디값을 통해 이름으로 변경
                if(temp[f].find(temp[j+1]) != string::npos){
                    //찾은 인덱스값 +1을 통해 닉네임 가져와 testTemp[i]에 저장
                    testTemp.push_back(temp[f]);
                    testTemp.push_back(temp[f+1]);
                    break;
                }
            }
            j += 2;
        }
    }
    
    int a=1;
    for(int z=0;z&amp;lt;record.size();){
        if(record[z].find(&quot;Enter&quot;) != string::npos){
            answer.push_back(testTemp[a] + &quot;님이 들어왔습니다.&quot;);
        }else if(record[z].find(&quot;Leave&quot;) != string::npos){
            answer.push_back(testTemp[a] + &quot;님이 나갔습니다.&quot;); 
        }
        a += 2;
        z++;
    }
    

    return answer;
}&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;매 값의 0번째 인덱스를 읽어 입장/퇴장/변경을 읽고&lt;br /&gt;다음 인덱스값을 입장/변경 기준 J+3 을통해 변경 나가는건 +2를 통해 인덱스값을 참조했다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게하고 각 입/퇴장마다 반복문을 돌리니 값이 작은건 괜찮지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조금 늘어난 테스트케이스에서는 여지없이 시간초과 에러가 낫다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(물론 Leave처리도 잘못되어있어서 다른케이스 에러나는것도있음)&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;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;다음 삽질한 코드&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1759062987330&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;sstream&amp;gt;
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;algorithm&amp;gt;

using namespace std;

vector&amp;lt;string&amp;gt; solution(vector&amp;lt;string&amp;gt; record) {
    vector&amp;lt;string&amp;gt; answer;
    vector&amp;lt;string&amp;gt; uids;
    vector&amp;lt;string&amp;gt; nickname;
    
    string word;
    // 1. 배열 문자 나누기
    // 2. 하나씩 나눠서 command , uid , name에 넣기
    // 3. 아이디가 이미 존재한다면 기존 아이디도 변경
    
    for(const string&amp;amp; str : record){
        stringstream ss(str);
        string command , uid , name;
        ss &amp;gt;&amp;gt; command &amp;gt;&amp;gt; uid;
        
        if(command == &quot;Enter&quot; || command == &quot;Change&quot;){
            ss &amp;gt;&amp;gt; name;
            
            //find 반환되는 값에 따라 int , float , string 자동 변환
            auto it = find(uids.begin(),uids.end(),uid);
            //있다면?
            if(it != uids.end()){
                int index = distance(uids.begin(),it);
                nickname[index] = name;
            }else {
                uids.push_back(uid);
                nickname.push_back(name);
            }
        }
    }
    //메시지 생성
    for(const string&amp;amp; str : record){
        stringstream ss(str);
        string command, uid;
        ss &amp;gt;&amp;gt; command &amp;gt;&amp;gt; uid;
        
        if(command == &quot;Enter&quot; || command == &quot;Leave&quot;){
            auto it = find(uids.begin(),uids.end(),uid);
            int index = distance(uids.begin(),it);
            string lastName = nickname[index];
            if(command == &quot;Enter&quot;){
                answer.push_back(lastName + &quot;님이 들어왔습니다.&quot;);
            }else if(command == &quot;Leave&quot;){
                answer.push_back(lastName + &quot;님이 나갔습니다.&quot;);
            }
        }
    }
    
    
    return answer;
}&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;여기서는 구글링을 통한 다른분의 코드와 ai의 코드 훔쳐와 풀기 시작했다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비슷한 흐름이지만 Map만 사용하지 않고 distance를 활용해 uid의 인덱스 값을 가져와서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 index와 함께 저장된&amp;nbsp; nickname에 인덱스를 참조하도록 하여 풀었다.&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;힘들어서 쓰긴했지만 알고리즘에 Ai의 도움을 받으면 기분이 너무 찝찝한건 어쩔 수 없나보다.&lt;/span&gt;&lt;/h4&gt;</description>
      <category>알고리즘/C++</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/3</guid>
      <comments>https://kimbob-world.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4Lv2-%EC%98%A4%ED%94%88%EC%B1%84%ED%8C%85%EB%B0%A9-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4#entry3comment</comments>
      <pubDate>Sun, 28 Sep 2025 16:24:16 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] Lv2. 예상 대진표 C++ 문제 풀이</title>
      <link>https://kimbob-world.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv2-%EC%98%88%EC%83%81-%EB%8C%80%EC%A7%84%ED%91%9C-C-%EB%AC%B8%EC%A0%9C-%ED%92%80%EC%9D%B4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;프로그래머스에서 시작하는 1차 C++ 기본 입출력으로 문제 풀기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/12985&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/12985&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;예상 대진표&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 :&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대진표를 통해 2의N승만큼의 인원(팀)이 있다고 했을 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A팀과 B팀은 몇번 째 대진에서 만나는가?&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;예상 문제 입력 4 7 8&amp;nbsp; &amp;nbsp;/&amp;nbsp; &amp;nbsp;answer : 3&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;h4 data-ke-size=&quot;size20&quot;&gt;내 해결방법 :&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 현재 인원 ( N(8)명 / 2 )를 통해 2의제곱 수 만큼 반복문을 돌린다.(최대 횟수 구하기: 8명일경우 3번)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 시작할때 홀수/짝수를 체크해서 홀수면 +1을 통해 짝수를 만들어 준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 이 후 값이 동일하면 서로 만났음을 확인 break;를 통해 반복문을 종료 후 종료&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 동일하지 않다면 /2를 통해 한칸 위로올라간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. a = 1 이여도 처음에 a+1을 통해 짝수로 만들어주기때문에 a/2를 해도 최소값은 1이다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;

using namespace std;
int solution(int n, int a, int b){
    //8명 참여 A는4번 B는 7번
    int answer = 0;
    for(n; n &amp;gt; 1; n /= 2){
        a = a%2 == 0 ? a : a+1;
        b = b%2 == 0 ? b : b+1;
        if(a==b){
            answer++;
            break;
        }else{
            a = a / 2;
            b = b / 2;
            answer++;
        }

    }
    cout &amp;lt;&amp;lt; answer &amp;lt;&amp;lt; endl;
    
    return answer;

}&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;이후 다른분의 코드 해결 방법 좋은것을 하나 훔쳐옴&lt;/b&gt;.&lt;/p&gt;
&lt;pre id=&quot;code_1759043011864&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 solution(int n, int a, int b){
    a--;
    b--;
    int answer=0;
    while(a!=b){
        a=a/2;
        b=b/2;
        answer++;
    }
    return answer;
}&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;/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;h4 data-ke-size=&quot;size20&quot;&gt;내가 한 코드 해석 :&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 기존 대진 번호 값을 1씩 빼준다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. a/2 , b/2 값이 같아질때 까지 반복문을 돌려준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. c++은 int형통해 계산한다면 소숫점이 없이 나오기 때문에 0.5 면 0이 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) 7 , 8 이라면 6과 7이 나오고 둘다 /2를 한다면&lt;br /&gt;3 , 3.5이 나오지만 int형이기떄문에 3 , 3 값은 같아지며 반복문이 마무리된다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;참고 할 수 있는 코드 개선점 :&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;c언어에대한 기본 지식을 좀 더 활용해서 내 코드기준 불필요한 홀,짝 체크를 다르게 변경한 것&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;</description>
      <category>알고리즘/C++</category>
      <author>박형석_</author>
      <guid isPermaLink="true">https://kimbob-world.tistory.com/2</guid>
      <comments>https://kimbob-world.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv2-%EC%98%88%EC%83%81-%EB%8C%80%EC%A7%84%ED%91%9C-C-%EB%AC%B8%EC%A0%9C-%ED%92%80%EC%9D%B4#entry2comment</comments>
      <pubDate>Sun, 28 Sep 2025 16:18:57 +0900</pubDate>
    </item>
  </channel>
</rss>