본문 바로가기
Developer/TIL

[TIL] 250326수 (자바스크립트 BFS, BFS가 필요한 문제 패턴, PGM 음양마스터, selectbox 데이터 null값 뜨는 문제 수정)

by 청량리 물냉면 2025. 3. 26.
반응형

2025-03-26


1. JavaScript로 BFS(너비 우선 탐색) 구현 및 설명
🔍 BFS란?
BFS (Breadth-First Search, 너비 우선 탐색): 그래프나 트리에서 가까운 노드부터 탐색하는 알고리즘

  • 큐(Queue) 자료구조를 이용해서 방문할 노드를 저장하면서 진행
  • 모든 인접 노드를 먼저 방문한 후, 다음 레벨(깊이)로 이동
  • 최단 경로 문제에 자주 사용됨 (예: 미로 탐색, 최단 거리, 친구 추천 시스템)

 

🌟 BFS 구현 (JavaScript)

function bfs(graph, start) {
    let queue = [start];  // BFS 탐색을 위한 큐 (FIFO)
    let visited = new Set(); // 방문한 노드 저장 (중복 방지)

    visited.add(start);  // 시작 노드를 방문 처리

    while (queue.length > 0) {
        let node = queue.shift();  // 큐에서 첫 번째 원소(노드) 꺼내기
        console.log(node); // 현재 노드 출력

        // 현재 노드의 모든 인접 노드 탐색
        for (let neighbor of graph[node]) {
            if (!visited.has(neighbor)) { // 방문하지 않은 노드라면
                visited.add(neighbor);  // 방문 처리
                queue.push(neighbor);  // 큐에 추가
            }
        }
    }
}

// 그래프 예제 (인접 리스트 방식)
const graph = {
    1: [2, 3],
    2: [4, 5],
    3: [6, 7],
    4: [],
    5: [8],
    6: [],
    7: [],
    8: []
};

// BFS 실행 (시작 노드: 1)
bfs(graph, 1);

 

그림으로 이해하는 BFS
예제 그래프
(숫자는 노드, 선은 간선)

      1
     / \
    2   3
   / \   \
  4   5   6
     /
    8

 

📌 BFS 탐색 과정

단계 큐(Queue)  방문 노드
초기화 [1] {1}
1단계 [2, 3] {1, 2, 3}
2단계 [3, 4, 5] {1, 2, 3, 4, 5}
3단계 [4, 5, 6] {1, 2, 3, 4, 5, 6}
4단계 [5, 6] {1, 2, 3, 4, 5, 6}
5단계 [6, 8] {1, 2, 3, 4, 5, 6, 8}
6단계 [8] {1, 2, 3, 4, 5, 6, 8}
7단계 [] (큐 비어있음) {1, 2, 3, 4, 5, 6, 8}

 

📌 BFS 원리 상세 설명
🔹 1. 큐(Queue) 사용

  • `queue.shift()` → FIFO(First In First Out) 방식으로 노드 탐색
  • 방문한 노드는 visited에 저장해서 중복 탐색 방지

🔹 2. 탐색 순서

  • queue에서 꺼낸 노드의 모든 이웃 노드를 큐에 추가
  • 가장 가까운 노드를 먼저 방문하고, 다음 레벨로 이동
  • 깊이 우선 탐색(DFS)와 달리 한쪽으로 쭉 탐색하지 않고, 동심원처럼 퍼져나감

 

📌 BFS vs DFS 비교

알고리즘 자료구조  탐색 방식 사용 예시
BFS 큐(Queue) 가까운 노드부터 탐색 최단 경로 문제, 네트워크 탐색
DFS 스택(Stack) (재귀) 한 경로 끝까지 탐색 후 백트래킹 미로 탐색, 백트래킹

BFS는 최단 경로 탐색에 유리
DFS는 모든 경우의 수 탐색에 유리

 

📌 시간 복잡도

  • BFS의 시간 복잡도는 O(V + E)
    • V : 노드(정점, Vertex)의 개수
    • E : 간선(Edge)의 개수
  • 모든 노드를 한 번씩 방문하며, 인접 리스트에서 모든 간선을 확인하기 때문!

 

🎯 정리
BFS는 가까운 노드부터 탐색하는 알고리즘
큐(Queue) 사용 & 방문 체크를 위한 Set 활용
최단 경로 찾을 때 유리
시간 복잡도는 `O(V + E)`
DFS와 비교하면 BFS는 한 번에 넓게 탐색

 

 

2. BFS가 필요한 문제 패턴

BFS를 사용해야 하는 특징 설명
최소 횟수(최단 거리) 문제 가장 적은 이동 횟수로 도달하는 문제
동시에 퍼지는 문제 여러 지점에서 동시에 전파되는 구조
2차원 격자에서의 이동 미로 탐색, 지도 탐색, 감염 확산 등

🚀 "이 문제 BFS로 풀어야겠네!" 판단하는 공식

  1. 최단 거리(최소 횟수)를 구하는가?
  2. 여러 개의 시작점에서 동시에 퍼지는가?
  3. 격자(2D 배열)에서 상하좌우 이동하는가?

3가지 중 하나라도 해당하면 BFS 고려
2개 이상 해당하면 BFS가 거의 정답!


 
3. 프로그래머스 음양마스터

function solution(absolutes, signs) {
    var answer = 0;
    for(let i = 0; i < absolutes.length; i++){
        if(signs[i]){
            answer += absolutes[i]; 
        } else {
            answer -= absolutes[i];
        }
    }
    return answer;
}

뭔가 `reduce`를 쓸 수 있을 것 같은데 두 가지 조건 분기처리를 어떻게 해야할지 가늠이 안 돼서 for문으로 풀었다.

모범답안을 살펴보니 `reduce`만 사용하면 되는 게 아니라, 삼항연산자를 함께 사용해야 했다.

function solution(absolutes, signs) {
    return absolutes.reduce((answer, num, i) => answer + num * (signs[i] ? 1 : -1), 0)
}

 

 

4) 거래소 수수료 집계 - 타입 selectbox 오류 수정
✅ 에러

- 1. 기존에 저장된 코드값을 지우면, 해당 코드값을 기반으로 생성된 selectbox 항목에 null 뜨는 오류 (원래대로라면, null 값이 뜨는 대신 그냥 항목이 추가되지 않아야 함)

- 2. 이전에 pinia store에서 기본값 강제 세팅했던 부분에서 오류가 남 👉 배열이 5개씩 그냥 화면에 띄워지고 있었음. 

✅ 원인 & 해결

- 1. selecbox 항목으로 nll 뜨는 이유는 기존에 존재하던 데이터를 전부 삭제하고 저장 버튼을 누르면 `{ko: null}` 👉 이런 식으로 데이터가 서버로 넘어갔고, 이로 인해서 서버에서도 null 값을 보내주어 항목명이 변경된 것. 이를 방지하기 위해 (데이터가 1개 있는 경우 && code, ko(필수값) 입력되지 않은 경우) 빈 배열로 대체해서 값을 서버로 보내줌

- 2. 빈 input field가 여러 개 띄워지는 문제의 원인: 항목이 비어있을 때 강제로 들어가게 세팅했던 기본값과, 값을 selectbox에 넣기 위해 변환하는 함수의 input 값의 포맷이 달랐다... 값은 제대로 함수에 넘어가는데, 포맷이 다르다 보니 값을 제대로 변환할 수 없어서 null이 떴던 것. 강제로 세팅했던 기본값을 삭제해줌으로써 문제가 해결되었다.

 

 

5) 코드 타입에 따라 우클릭 메유(이벤트 리스너) 내부 항목 노출여부 결정

grid 컴포넌트에서 `headerId` 받아와서 현재 클릭한 컬럼의 타입을 계산했다.

이후에 이벤트 리스너에 v-if 붙여 타입별로 렌더링해주었다.

반응형