개념 이해

대학 축제 준비는 장소, 공연, 부스, 안전, 물품 관리처럼 여러 문제로 나눌 수 있습니다. 이 가운데 물품 관리를 맡은 운영진은 생수, 간식, 안내책자를 필요한 곳에 배분해야 합니다. 물품의 종류는 다르지만, 전체 수량을 확인하고 배분 대상을 정한 뒤 같은 기준으로 나눈다는 공통점이 있습니다.

축제 운영 자료에는 부스 이름, 운영 위치, 판매 품목, 현수막 색상, 담당자 연락처, 방문객 수, 물품 수량 등 많은 정보가 들어 있습니다. 생수를 배분할 때 이 정보가 모두 필요한 것은 아닙니다. 생수 총량, 배분할 부스, 부스 수, 배분 기준, 남은 생수의 처리 방법이 필요합니다. 현수막 색상이나 판매 품목은 생수 배분량을 정하는 데 사용하지 않으므로 제외할 수 있습니다. 이처럼 해결 목적과 관계없는 세부정보를 노이즈로 보고 덜어 낸 뒤 필요한 정보만 남기는 과정이 추상화입니다.

생수 배분에서 찾은 구조는 간식이나 안내책자를 나눌 때에도 사용할 수 있습니다. 먼저 전체 수량과 배분 대상의 수를 확인합니다. 각 대상에 같은 수량을 나누고, 남은 물품은 정해진 장소에 보관합니다. 물품 이름과 수량은 달라져도 이 처리 구조는 유지됩니다. 여러 사례의 공통 구조를 뽑아 다른 문제에도 사용할 수 있는 규칙으로 만드는 과정이 일반화입니다.

생수 245병을 운영 부스 6곳에 배분하는 상황에 이 규칙을 적용해 보겠습니다. 생수 총량과 부스 수를 확인하고, 245를 6으로 나눈 몫과 나머지를 구합니다. 각 부스에 40병씩 배분한 뒤 남은 5병은 축제 본부에 보관합니다. 해야 할 일을 실행 순서에 따라 분명하게 정리한 것이 알고리즘입니다.

추상화는 문제와 관계없는 세부정보를 덜어 냅니다. 일반화는 여러 사례에서 함께 사용할 수 있는 해결 구조를 만듭니다. 알고리즘은 그 해결 구조를 실제로 수행할 수 있는 순서로 표현합니다. 세 가지 사고는 서로 떨어져 있지 않으며, 복잡한 현실 문제를 실행 가능한 해결 절차로 바꾸는 과정에서 이어집니다.

추상화

추상화(abstraction)는 문제를 해결할 때 지금 중요하지 않은 세부를 덜어 내고 꼭 필요한 요소만 남겨 단순한 모델을 만드는 과정입니다. 이때 덜어 낸 세부는 완전히 사라지는 것이 아니라 문제를 다루는 동안 잠시 고려 대상에서 제외되는 것이며, 필요해지면 언제든 다시 포함할 수 있습니다. 추상화가 잘 된 모델은 원래 문제보다 다루기 쉬우면서도 해결에 필요한 정보는 빠뜨리지 않습니다.

추상화는 내용을 대충 줄이는 일이 아닙니다. 해결 목적에 맞추어 필요한 정보와 필요하지 않은 정보를 구분하는 일입니다. 데이크스트라는 추상화를 통해 복잡한 세부에서 벗어나 더 정확하게 사고할 수 있는 새로운 층위를 만들 수 있다고 설명했습니다(Dijkstra, 1972). 세부가 너무 많으면 중요한 조건을 찾기 어렵습니다. 목적과 직접 관련된 정보만 남기면 무엇을 판단하고 계산해야 하는지가 분명해집니다.

혼잡도 판단에 필요한 정보 고르기

축제 운영진이 출입구 가운데 어느 곳이 가장 혼잡한지 확인하려고 합니다. 현장에서는 출입구 위치, 측정 시각, 대기 인원, 방문객 이름, 옷차림, 방문 목적 등 여러 정보를 관찰할 수 있습니다. 이 가운데 혼잡도를 비교하는 데 필요한 정보는 출입구, 측정 시각, 대기 인원입니다. 방문객의 이름이나 옷차림은 대기 인원을 비교하는 데 사용되지 않습니다.

flowchart LR
    A["현장에서 관찰한 정보<br/>출입구·시각·대기 인원<br/>이름·옷차림·방문 목적"]
    A --> B["목적에 따라 정보 선택"]
    B --> C["남길 정보<br/>출입구·측정 시각·대기 인원"]
    C --> D["출입구별 혼잡도 비교"]

    style A fill:#fee2e2,stroke:#dc2626
    style B fill:#fef3c7,stroke:#d97706,stroke-width:2px
    style C fill:#dbeafe,stroke:#2563eb
    style D fill:#dcfce7,stroke:#16a34a

그림 3-1. 축제 출입구 혼잡도 판단을 위한 추상화

제외한 정보가 언제나 쓸모없는 것은 아닙니다. 분실자를 찾거나 방문객 특성을 조사하는 목적이라면 다른 정보가 필요할 수 있습니다. 현재 목적이 출입구의 혼잡도를 비교하는 것이므로 그 목적에 필요한 정보만 남긴 것입니다. 추상화에서는 정보를 무조건 적게 만드는 것보다, 해결 목적에 맞는 정보를 정확하게 고르는 일이 중요합니다.

목적에 따라 달라지는 표현

같은 대상이라도 목적에 따라 다르게 표현합니다. 캠퍼스를 위에서 촬영한 항공사진과 축제 당일 배부하는 부스 안내도를 비교해 보겠습니다.

비교 항목 캠퍼스 항공사진 축제 부스 안내도
담은 정보 실제 건물 모양, 나무, 도로의 굴곡까지 전부 부스 번호, 통로, 화장실·의무실 위치
강점 실제 지형을 그대로 확인 어디로 가면 되는지 한눈에 파악
약점 정작 부스를 찾기는 더 어려움 실제 거리·방향과는 다름

방문객이 먹거리 부스의 위치를 물을 때 필요한 것은 항공사진이 아니라 안내도입니다. 모든 정보를 한꺼번에 담으면 정작 원하는 정보를 찾기 어려워지고, 목적에 맞는 정보만 남기면 문제가 쉬워집니다. 두 그림의 차이는 정보의 많고 적음이 아니라, 어떤 목적을 위해 무엇을 남기고 무엇을 생략했는가에 있습니다.

추상화는 정보를 빠뜨리는 실수가 아니라 목적에 맞게 남길 것과 생략할 것을 정하는 판단 과정입니다. 따라서 추상화를 시작하기 전에 무엇을 위한 단순화인지를 먼저 정해야 합니다.

일반화

일반화(generalization)는 여러 사례에서 발견한 공통 구조를 하나의 규칙이나 절차로 정리하여 새로운 상황에도 적용할 수 있게 만드는 과정입니다. 부스 신청·공연 신청·자원봉사 신청은 서로 다른 업무이지만 요청 접수 → 조건 확인 → 승인·대기 결정 → 결과 안내라는 처리 구조를 공유합니다. 이러한 공통 구조를 다른 상황에 다시 사용할 수 있도록 정리하는 것이 일반화입니다.

패턴 인식과 일반화는 서로 이어져 있지만 역할이 다릅니다. 패턴 인식이 여러 사례에서 비슷한 부분이 되풀이된다는 사실을 알아차리는 단계라면, 일반화는 그 공통점을 뽑아내어 앞으로 같은 종류의 문제에 그대로 적용할 수 있는 절차로 만드는 단계입니다. 관찰에서 그치지 않고 그 관찰을 재사용할 수 있는 도구로 바꾸는 것이 일반화의 목적입니다.

공통 구조를 일반 절차로 정리하기

세 신청 업무에서 대상에 따라 달라지는 세부를 잠시 걷어 내고 처리 흐름만 남기면, 아래와 같은 하나의 일반 절차가 남습니다.

flowchart TD
    subgraph 개별 사례
      A1["부스 신청 처리"]
      A2["공연 신청 처리"]
      A3["자원봉사 신청 처리"]
    end
    A1 -.공통점 추출.-> G
    A2 -.공통점 추출.-> G
    A3 -.공통점 추출.-> G
    G["일반 절차<br/>요청 접수 → 조건 확인<br/>→ 승인·대기 결정 → 결과 안내"]

    style G fill:#ede9fe,stroke:#7c3aed,stroke-width:2px
    style A1 fill:#dbeafe,stroke:#2563eb
    style A2 fill:#dbeafe,stroke:#2563eb
    style A3 fill:#dbeafe,stroke:#2563eb

그림 3-2. 여러 신청 업무에서 공통 절차 추출하기

이렇게 정리된 절차는 더 이상 특정 신청 하나에 묶여 있지 않습니다. 부스 종류나 공연 길이, 근무 시간처럼 사례마다 다른 세부를 추상화로 걷어 냈기 때문에, 여러 사례를 하나의 절차로 묶는 일이 가능해진 것입니다. 이처럼 추상화와 일반화는 별개의 작업이 아니라 함께 작동합니다. 세부를 걷어 내는 추상화가 앞서야 여러 사례를 아우르는 일반화가 성립합니다.

일반 절차를 새로운 상황에 적용하기

일반화한 절차는 새로운 문제를 해결할 때 사용할 수 있습니다. 축제에 처음 참여하는 푸드트럭의 신청 절차도 처음부터 다시 설계할 필요가 없습니다. 일반 절차의 각 단계에 푸드트럭 상황에 해당하는 세부 조건을 채워 넣으면 됩니다.

일반 절차 푸드트럭 신청으로 구체화
요청 접수 상호, 판매 음식, 전기 사용량 신청서를 받는다
조건 확인 위생 서류가 있는지, 전기 사용량이 허용치 안인지 확인한다
승인·대기 결정 배정 가능한 자리 수를 기준으로 참가와 대기를 나눈다
결과 안내 배정 위치와 준비 사항을 안내한다

표의 왼쪽은 어떤 신청에도 공통으로 적용되는 뼈대이고, 오른쪽은 이번 상황에만 해당하는 구체적인 내용입니다. 이처럼 일반적인 규칙을 특정 상황에 맞게 다시 적용하는 과정을 구체화라고 합니다. 잘 만들어진 일반 절차는 뼈대를 그대로 유지한 채 상황에 따라 세부만 바꾸어 쓸 수 있어야 합니다.

일반화는 지나치면 오히려 문제가 됩니다. 예를 들어 모든 신청을 선착순으로 승인한다는 규칙은 심사나 추첨이 필요한 신청에는 맞지 않습니다. 접수·확인·결정·안내라는 공통 뼈대는 유지하되, 승인 기준처럼 사례마다 달라지는 부분까지 하나의 규칙으로 고정하지는 않아야 합니다.

알고리즘

알고리즘(algorithm)은 주어진 문제를 해결하기 위해 수행해야 할 일을 순서와 조건에 맞게 정리한 유한한 절차입니다. 요리 조리법, 가구 조립 설명서, 목적지까지의 길 안내도 정해진 절차를 따른다는 점에서 알고리즘으로 볼 수 있습니다. 일반화를 통해 얻은 공통 해결 방법도 알고리즘으로 나타낼 수 있습니다.

알고리즘과 프로그램은 종종 같은 것으로 여겨지지만 구분할 필요가 있습니다. 알고리즘은 문제를 해결하는 절차 그 자체이고, 프로그램은 그 절차를 파이썬과 같은 특정 언어의 문법으로 옮겨 컴퓨터가 실행할 수 있게 만든 것입니다. 하나의 알고리즘은 파이썬으로도 다른 언어로도 구현할 수 있습니다. 그런 까닭에 프로그래밍을 익힐 때에는 언어의 문법을 외우기에 앞서 해결 절차를 분명하게 세우는 연습이 먼저 이루어져야 합니다.

알고리즘이 갖추어야 할 조건

모든 절차가 알고리즘이 되는 것은 아닙니다. 알고리즘은 적어도 다음 세 가지 조건을 갖추어야 합니다(Cormen et al., 2022).

조건 축제 사례에서 어긴 예
명확성 각 단계가 한 가지 뜻으로만 읽혀야 한다 “생수를 부스마다 적당히 나눠 준다” — 몇 병인지 알 수 없다
유한성 정해진 단계를 거치면 반드시 끝나야 한다 “줄이 사라질 때까지 안내방송을 반복한다” — 줄이 안 줄면 끝나지 않는다
실행 가능성 각 단계가 실제로 수행될 수 있어야 한다 “3층 창고에서 여분 생수를 가져온다” — 창고가 2층까지밖에 없다

여기에 더해 알고리즘은 무엇을 입력으로 받고 무엇을 출력하는지가 분명해야 합니다. 위의 세 예는 각각 수량이 정해지지 않았다는 점, 언제 끝나는지 알 수 없다는 점, 실제로 수행할 수 없는 동작을 포함한다는 점에서 조건을 어깁니다. 처음 온 봉사자가 “적당히 나눈다”는 지시만으로 일을 시작하지 못하는 것도 명확성이 지켜지지 않았기 때문입니다.

모호한 지시를 명확하게 다듬기

일상의 언어는 편리하지만 여러 가지로 해석될 여지가 있습니다. 같은 지시를 알고리즘으로 옮기려면 기준과 수치를 넣어 한 가지 의미로 좁혀야 합니다.

모호한 지시 다듬은 지시
생수를 골고루 나눠 준다 총량을 부스 수로 나눈 몫만큼 각 부스에 배분한다
사람이 많으면 창구를 늘린다 대기 인원이 30명을 넘으면 창구를 하나 더 연다
늦게 온 팀은 나중에 배정한다 신청 접수 시각이 빠른 순서대로 배정한다

일상과 수학 속의 알고리즘

알고리즘은 프로그래밍에만 있는 것이 아니라 일상과 수학에서도 흔히 사용됩니다. 축제 부스의 정산은 순서가 정해진 일상적인 알고리즘의 예입니다. 먼저 부스별 매출을 모으고, 이를 모두 더해 총매출을 구한 다음, 총매출에서 지출을 빼고, 남은 금액을 순이익으로 보고합니다. 이 절차는 순서를 지켜야 하며, 지출을 빼기 전에 순이익을 보고하면 잘못된 결과가 나옵니다.

수학에서 사용하는 알고리즘의 예로 앞에서 언급한 생수 나누기를 살펴보겠습니다. 생수 245병을 부스 6곳에 똑같이 나눌 때 부스당 몇 병이 배분되고 몇 병이 남는지를 구하는 문제입니다. 나눗셈의 몫이 부스당 배분량이고 나머지가 남는 병 수이므로, 245를 6으로 나누면 몫이 40, 나머지가 5가 됩니다. 몫과 나머지를 구하는 절차는 생수뿐 아니라 의자나 간식을 똑같이 나누는 문제에도 적용할 수 있습니다.

flowchart LR
    subgraph DAILY["일상 알고리즘: 부스 정산"]
        direction TB
        D1["부스별 매출 수집"] --> D2["총매출 계산"]
        D2 --> D3["지출 차감"]
        D3 --> D4["순이익 보고"]
    end

    subgraph MATH["수학 알고리즘: 생수 배분"]
        direction TB
        M1["생수 총량·부스 수 확인"] --> M2["몫과 나머지 계산"]
        M2 --> M3["부스당 40병 배분"]
        M3 --> M4["남은 5병 보관"]
    end

    D4 -."정해진 순서로 결과 생성".-> M4

    style DAILY fill:#eff6ff,stroke:#3b82f6
    style MATH fill:#f0fdf4,stroke:#22c55e
    style D4 fill:#dbeafe,stroke:#2563eb
    style M4 fill:#dcfce7,stroke:#16a34a

그림 3-3. 대학 축제에서 찾은 일상 알고리즘과 수학 알고리즘

두 사례에서 다루는 대상은 다르지만 공통점이 있습니다. 필요한 값을 먼저 확인하고, 정해진 순서로 처리한 뒤, 그 결과를 얻습니다. 알고리즘은 컴퓨터 안에서만 사용되는 특별한 기술이 아니라 일상에서 이미 사용하고 있는 절차를 정확하게 정리한 것입니다.

같은 문제를 해결하는 여러 방법

하나의 문제에 해결 방법이 하나만 있는 것은 아닙니다. 생수 245병을 6개 부스에 나누는 방법도 여러 가지입니다.

첫 번째 방법은 나눗셈의 몫과 나머지를 이용하는 것입니다. 245를 6으로 나누어 몫 40과 나머지 5를 한 번에 구합니다. 계산이 짧고 정확하므로 컴퓨터 프로그램으로 옮기기에도 알맞습니다.

두 번째 방법은 각 부스에 생수를 한 병씩 차례로 배분하는 것입니다. 모든 부스가 한 병씩 받으면 같은 과정을 다시 반복합니다. 실제 현장에서 눈으로 확인하며 나눌 수 있다는 장점이 있지만, 생수의 수가 많아지면 시간이 오래 걸립니다.

세 번째 방법은 먼저 부스당 40병씩 나누어 240병을 배분한 뒤, 남은 5병을 따로 보관하는 것입니다. 사람이 직접 작업할 때 이해하기 쉬운 방법입니다. 다만 처음 정한 40병이 올바른지 확인하려면 결국 나눗셈이나 반복 확인이 필요합니다.

해결 방법 필요한 작업 장점 주의할 점
몫과 나머지 계산 나눗셈 한 번 계산이 짧고 결과가 분명함 몫과 나머지의 뜻을 알아야 함
한 병씩 반복 배분 부스를 돌며 계속 배분 현장에서 확인하기 쉬움 수량이 많으면 오래 걸림
일정 수량을 먼저 묶어 배분 40병씩 묶은 뒤 남은 수 확인 사람이 작업하기 쉬움 묶음 수량을 정할 근거가 필요함

좋은 알고리즘은 답만 맞는 절차를 뜻하지 않습니다. 문제의 크기, 사용하는 사람, 실행 환경을 함께 고려해야 합니다. 컴퓨터로 수천 건을 처리한다면 계산 횟수가 적은 방법이 유리합니다. 사람이 창고에서 물품을 나눈다면 작업 중 실수를 쉽게 확인할 수 있는 방법도 중요합니다.

알고리즘의 표현

같은 알고리즘이라도 상황에 따라 여러 방식으로 표현할 수 있습니다. 가장 널리 쓰이는 표현 방식은 자연어, 의사코드, 순서도입니다.

표현 방법 장점 한계 잘 맞는 상황
자연어 누구나 바로 읽는다 문장이 모호해질 수 있다 처음 아이디어를 적을 때
의사코드 언어 문법에 매이지 않고 논리에 집중 표준이 없어 사람마다 조금씩 다름 절차를 팀과 검토할 때
순서도 흐름과 분기가 눈에 보인다 길어지면 그림이 복잡해짐 흐름을 설명·교육할 때

순서도의 기본 기호

순서도(flowchart)는 정해진 도형으로 절차의 흐름을 나타내는 표현 방식입니다. 각 도형은 아래와 같이 역할이 정해져 있습니다.

기호 모양 도형 역할
단말 둥근 사각형 시작과 종료
입출력 평행사변형 값을 입력받거나 결과를 출력
처리 직사각형 계산, 값 저장
서브루틴 이중 선 직사각형 미리 정의된 처리(함수·서브루틴)를 호출
판단 마름모 조건의 참·거짓에 따라 흐름을 나눔
흐름선 화살표 실행 순서

순차·선택·반복

구조화된 프로그램의 제어 흐름은 순차, 선택, 반복을 조합하여 표현할 수 있습니다. 이와 관련된 이론적 근거는 뵘과 자코피니의 연구에서 확인할 수 있습니다(Böhm & Jacopini, 1966).

flowchart TD
    subgraph S1["순차 — 위에서 아래로"]
        direction TB
        A1["명령 A"] --> A2["명령 B"] --> A3["명령 C"]
    end
    subgraph S2["선택 — 조건에 따라 갈라짐"]
        direction TB
        C1{"조건?"}
        C1 -- 참 --> T1["명령 T"]
        C1 -- 거짓 --> F1["명령 F"]
    end
    subgraph S3["반복 — 조건이 맞는 동안 되풀이"]
        direction TB
        L1{"조건?"}
        L1 -- 예 --> B1["반복 실행"]
        B1 --> L1
        L1 -- 아니오 --> X1["빠져나옴"]
    end

    style S1 fill:#eff6ff,stroke:#3b82f6
    style S2 fill:#fef3c7,stroke:#d97706
    style S3 fill:#f0fdf4,stroke:#22c55e

그림 3-4. 순차·선택·반복의 제어 흐름

여기서는 세 구조가 어떤 흐름을 나타내는지 구분합니다. 순차는 정해진 명령을 차례로 수행합니다. 선택은 조건에 따라 수행할 명령을 고릅니다. 반복은 같은 명령을 정해진 횟수만큼 또는 조건이 성립하는 동안 되풀이합니다.

하나의 알고리즘을 세 가지로 표현하기

앞에서 다룬 생수 나누기 문제를 자연어, 의사코드, 순서도로 각각 표현해 보겠습니다. 조건이나 반복이 없이 위에서 아래로 한 번에 흐르는 순차 알고리즘입니다.

자연어

① 생수 총량과 부스 수를 입력받는다. ② 총량을 부스 수로 나눈 몫을 부스당 배분량으로 정한다. ③ 그 나머지를 남는 병 수로 정한다. ④ 배분량과 남는 병 수를 출력한다.

의사코드

입력: total(생수 총량), booths(부스 수)
per_booth ← total 을 booths 로 나눈 몫
leftover  ← total 을 booths 로 나눈 나머지
출력: per_booth, leftover

순서도

flowchart TD
    S(["시작"]) --> I[/"total, booths 입력"/]
    I --> P1["per_booth ← total 을 booths 로 나눈 몫"]
    P1 --> P2["leftover ← total 을 booths 로 나눈 나머지"]
    P2 --> O[/"per_booth, leftover 출력"/]
    O --> E(["종료"])

    style S fill:#dcfce7,stroke:#16a34a
    style E fill:#f1f5f9,stroke:#475569
    style I fill:#eff6ff,stroke:#3b82f6
    style O fill:#eff6ff,stroke:#3b82f6

그림 3-5. 생수 배분 알고리즘의 순서도

세 가지 표현은 같은 해결 절차를 서로 다른 방식으로 나타냅니다. 자연어는 처음 문제를 설명할 때 편리합니다. 의사코드는 계산과 처리 순서를 확인하기 좋고, 순서도는 흐름을 눈으로 확인하기 좋습니다. 설계한 절차를 컴퓨터에서 실행하는 과정은 코딩실습에서 다룹니다.

알고리즘 점검하기

코드를 작성했다고 해서 작업이 끝난 것은 아닙니다. 실행하기 전에 절차가 의도한 대로 흐르는지 직접 따라가 보고, 여러 종류의 입력에 대해서도 올바르게 동작하는지 확인해야 합니다.

추적표로 실행 따라가기

추적표(trace table)는 알고리즘을 한 단계씩 수행하면서 값이 어떻게 변하는지 손으로 적어 보는 표입니다. 생수 245병을 6개 부스에 나누는 과정을 따라가 보겠습니다.

실행 순서 수행한 일 생수 총량 부스 수 부스당 배분량 남는 수량
1 생수 총량 확인 245
2 운영 부스 수 확인 245 6
3 나눗셈의 몫 계산 245 6 40
4 나눗셈의 나머지 계산 245 6 40 5

표의 마지막 줄에 남은 값이 출력 결과와 일치하면 절차가 올바르게 흐른 것입니다. 추적표는 특히 오류를 찾을 때 유용합니다. 어느 줄에서 변수의 값이 예상과 달라지는지를 눈으로 확인할 수 있기 때문입니다.

정상값·경계값·예외값

프로그램이 한 번 올바르게 동작했다고 해서 언제나 올바른 것은 아닙니다. 여러 종류의 입력을 넣어 시험해 보아야 합니다.

구분 입력 예 결과 확인할 점
정상값 240, 6 40, 0 흔히 들어오는 평범한 값
경계값 5, 6 0, 5 총량이 부스 수보다 작으면 몫이 0
예외값 240, 0 오류 발생 부스 수가 0이면 0으로 나눔(ZeroDivisionError)

정상값만으로 시험하면 부스 수가 0인 경우처럼 드물게 발생하지만 프로그램을 멈추게 하는 입력을 놓치게 됩니다. 경계값과 예외값을 미리 넣어 확인하는 습관이 안정적인 프로그램을 만드는 바탕이 됩니다. 예외 입력에 맞는 안내를 제공하려면 조건에 따라 실행 경로를 나누는 구조가 필요합니다.

절차의 오류

생수 245병을 6개 부스에 나누면서 일반 나눗셈을 사용하면 부스당 배분량이 약 40.83병으로 계산됩니다. 계산 자체는 가능하지만 실제 생수병을 소수 단위로 나눌 수는 없습니다. 이 문제에서는 몫 40병과 나머지 5병을 따로 구해야 합니다.

계산은 끝났지만 문제의 조건에 맞지 않는 답이 나온 경우를 논리 오류라고 합니다. 논리 오류는 절차가 중간에 멈추지 않을 수도 있으므로 최종 결과를 사람이 확인해야 합니다. 입력값, 계산 방법, 출력 결과를 차례로 살펴보면 잘못된 단계를 찾을 수 있습니다.

문제 분해에서 알고리즘까지

대학 축제 준비는 여러 종류의 업무가 한꺼번에 진행되는 복잡한 문제입니다. 이 문제를 컴퓨터로 처리하려면 곧바로 프로그램부터 작성해서는 안 됩니다. 먼저 해결할 문제의 범위와 필요한 결과를 정하고, 문제의 구조를 차례로 정리해야 합니다.

축제 부스 신청 관리를 예로 들어 전체 과정을 연결해 보겠습니다. 운영진의 목표는 신청 정보를 빠짐없이 받고, 참가 조건을 확인하여, 정해진 수의 부스를 배정하고, 그 결과를 신청자에게 알리는 것입니다.

문제 분해

큰 문제를 신청 접수, 정보 확인, 참가·대기 결정, 결과 안내, 취소 처리로 나눕니다. 각 부분에서 만들어진 결과는 다음 부분의 입력으로 사용됩니다. 신청 접수에서 만든 신청 기록이 정보 확인에 전달되고, 확인을 마친 유효 신청 목록이 참가·대기 결정에 사용됩니다.

문제 분해를 하면 담당할 일을 나누기 쉬워집니다. 오류가 발생한 위치도 찾기 쉬워집니다. 결과 안내에 문제가 생겼다면 신청 접수 전체를 다시 만들 필요 없이 안내 단계의 자료와 절차부터 확인할 수 있습니다.

패턴 인식

부스 신청, 공연 신청, 자원봉사 신청을 비교하면 되풀이되는 흐름이 보입니다. 세 업무 모두 요청을 받고, 필요한 조건을 확인하고, 승인 여부를 정하고, 결과를 기록하여 안내합니다. 업무 이름과 확인 조건은 다르지만 처리 순서는 비슷합니다.

패턴 인식에서는 공통점과 차이점을 함께 보아야 합니다. 부스 신청은 남은 부스 수를 확인하고, 공연 신청은 사용 가능한 시간을 확인합니다. 자원봉사 신청은 근무 가능한 시간과 필요한 인원을 확인합니다. 이 차이를 무시하고 모든 신청에 같은 조건을 적용하면 잘못된 결과가 나옵니다.

추상화

공통 처리 흐름을 설명하는 데 필요하지 않은 세부는 잠시 제외합니다. 동아리 이름, 공연 곡명, 봉사자의 학과는 각 신청을 실제로 처리할 때 필요할 수 있지만 공통 절차를 찾는 단계에서는 핵심 정보가 아닙니다. 요청, 조건, 결정, 결과라는 요소를 남기면 세 업무를 같은 틀에서 살펴볼 수 있습니다.

추상화의 기준은 해결 목적입니다. 공연장 배치를 결정할 때에는 공연 시간과 장비 정보가 중요합니다. 신청 절차의 공통점을 찾을 때에는 요청 접수와 조건 확인의 순서가 중요합니다. 같은 정보도 목적에 따라 남기거나 제외할 수 있습니다.

일반화

추상화한 공통 요소를 요청 접수 → 조건 확인 → 승인·대기 결정 → 결과 기록 → 안내라는 절차로 정리합니다. 이 절차는 푸드트럭 신청처럼 새로운 업무를 설계할 때 다시 사용할 수 있습니다. 다만 위생 서류, 전기 사용량, 자리 수와 같은 세부 조건은 새 상황에 맞게 채워 넣어야 합니다.

일반화는 모든 업무를 똑같이 처리한다는 뜻이 아닙니다. 여러 문제에서 함께 사용할 수 있는 뼈대를 만들고, 달라지는 조건을 구분해 두는 일입니다. 공통 부분은 재사용하고 세부 조건은 상황에 맞게 바꾸면 새로운 업무를 처음부터 다시 설계하는 수고를 줄일 수 있습니다.

알고리즘 표현과 점검

일반화한 절차를 실제로 실행하려면 각 단계를 더 분명하게 적어야 합니다. “조건을 확인한다”라고만 쓰면 어떤 조건인지 알 수 없습니다. 푸드트럭 신청에서는 “위생 서류 제출 여부와 전기 사용량이 허용 범위 안에 있는지 확인한다”처럼 판단 기준을 밝혀야 합니다.

완성한 알고리즘은 자연어, 의사코드, 순서도로 나타낼 수 있습니다. 프로그램으로 구현할 때에는 각 단계를 입력, 처리, 출력과 연결합니다. 마지막으로 정상값, 경계값, 예외값을 사용하여 결과를 확인합니다. 이 과정에서 잘못된 단계가 발견되면 앞 단계로 돌아가 문제의 분해나 조건을 다시 고칩니다.

flowchart LR
    A["문제 분해<br/>작은 문제로 나눔"] --> B["패턴 인식<br/>공통 흐름을 찾음"]
    B --> C["추상화<br/>핵심 요소를 남김"]
    C --> D["일반화<br/>공통 절차를 만듦"]
    D --> E["알고리즘<br/>명확한 순서로 표현"]
    E --> F["점검<br/>여러 입력으로 확인"]
    F -.수정이 필요함.-> A

    style A fill:#dbeafe,stroke:#2563eb
    style B fill:#ede9fe,stroke:#7c3aed
    style C fill:#fef3c7,stroke:#d97706
    style D fill:#ffedd5,stroke:#ea580c
    style E fill:#dcfce7,stroke:#16a34a
    style F fill:#fee2e2,stroke:#dc2626

그림 3-6. 문제 분해에서 알고리즘 점검까지의 흐름

이 흐름은 반드시 한 번씩만 거치는 직선 과정이 아닙니다. 점검 과정에서 조건이 빠졌다면 문제를 다시 나누어야 할 수 있습니다. 새로운 신청 유형이 생기면 기존 패턴과 비교하고 일반 절차를 고쳐야 할 수도 있습니다. 컴퓨팅 사고는 문제를 한 번에 정답으로 만드는 방법보다, 해결 과정을 확인하고 고쳐 나가는 방법에 가깝습니다.

오개념 바로잡기

흔한 오해 더 정확한 이해
추상화는 정보를 대충 뭉뚱그리는 것이다 목적에 맞게 남길 것과 감출 것을 고르는 판단이다
패턴을 찾았으면 일반화도 끝난 것이다 공통 구조를 재사용 가능한 절차로 만들어야 일반화다
알고리즘은 곧 프로그램(코드)이다 알고리즘은 절차 자체, 프로그램은 그 절차를 언어로 옮긴 것
실행되기만 하면 맞는 알고리즘이다 명확·유한·실행 가능해야 하고 결과가 옳아야 한다
절차가 끝까지 실행되면 답도 맞다 실행은 끝나더라도 계산 방법이 잘못되면 결과가 틀릴 수 있다

정리

  • 추상화는 목적에 필요한 것만 남기고 나머지를 감추어 문제를 단순하게 만드는 과정입니다.
  • 일반화는 여러 사례의 공통 구조를 뽑아 재사용 가능한 절차로 만들고, 새로운 상황에 구체화하는 과정입니다.
  • 알고리즘은 그 절차를 명확·유한·실행 가능하게 적은 것이며, 자연어·의사코드·순서도·코드로 표현할 수 있습니다.
  • 순차 알고리즘은 필요한 값을 확인하고, 정해진 순서로 처리하여 결과를 만드는 구조입니다.
  • 작성한 알고리즘은 추적표와 여러 종류의 입력값으로 점검해야 하며, 절차가 끝까지 실행되어도 논리 오류가 남아 있을 수 있습니다.
  • 문제 분해, 패턴 인식, 추상화, 일반화, 알고리즘은 서로 떨어진 단계가 아니라 문제를 이해하고 해결 절차를 다듬는 과정에서 함께 사용됩니다.