도구스개발

줄바꿈 최적화(그리디 vs 최적) 계산기

낱말 목록과 줄 너비를 넣으면 한 줄씩 채우는 그리디 줄바꿈과 남는 칸의 제곱합을 최소로 하는 최적 줄바꿈을 나란히 보여 줍니다. 줄 수는 같아도 오른쪽 끝의 고르기가 어떻게 달라지는지 확인할 수 있습니다.

공백으로 나눈 낱말을 200개까지 받습니다

글자

글자 수로 잽니다. 비례폭 글꼴의 픽셀 폭과는 다릅니다

그리디가 최적보다 나쁩니다

그리디 17 · 최적 11

같은 문단인데 벌점이 6만큼 큽니다. 너비를 한두 칸 바꿔 보면 차이가 커지기도 사라지기도 합니다.

그리디 (브라우저 방식) — 벌점 17 · 6

··················| 너비 18
줄바꿈은 한 줄씩 채우면 빠르지만| 0칸 남음 → 벌점 0
문단을 통째로 보아야 오른쪽 끝이| 0칸 남음 → 벌점 0
고르게 맞는다 크누스가 만든 조판| 0칸 남음 → 벌점 0
프로그램 텍은 문단 전체를····| 4칸 남음 → 벌점 16
한꺼번에 살펴 가장 고른 배치를·| 1칸 남음 → 벌점 1
고른다···············| 15칸 남음 → 벌점 0

최적 (동적 계획법) — 벌점 11 · 6

··················| 너비 18
줄바꿈은 한 줄씩 채우면 빠르지만| 0칸 남음 → 벌점 0
문단을 통째로 보아야 오른쪽···| 3칸 남음 → 벌점 9
끝이 고르게 맞는다 크누스가 만든| 0칸 남음 → 벌점 0
조판 프로그램 텍은 문단 전체를·| 1칸 남음 → 벌점 1
한꺼번에 살펴 가장 고른 배치를·| 1칸 남음 → 벌점 1
고른다···············| 15칸 남음 → 벌점 0
그리디의 벌점 (남는 칸의 제곱합)17
최적의 벌점11
줄 수그리디 6줄 · 최적 6
전수 탐색으로 얻은 최소낱말이 18개를 넘어 접었음
계산 근거한 줄의 벌점 = (너비 − 그 줄이 쓴 칸)² · 문단의 벌점 = 줄마다의 합dp[i] = min_j ( 벌점(i..j) + dp[j+1] ) — 낱말 i부터 끝까지의 최소 벌점남는 칸을 그냥 더하면 어떻게 나눠도 합이 거의 같아 구별이 안 갑니다. 제곱으로 매기면 한 줄이 크게 비는 것을 여러 줄이 조금씩 비는 것보다 훨씬 나쁘게 보므로, 오른쪽 끝이 고르게 맞는 배치가 이깁니다.
한 줄씩 채우는 방식이 최적이 아닌 것이 이 도구의 요점입니다. 브라우저와 대부분의 편집기는 그리디로 줄을 바꿉니다. 빠르고 대개 괜찮지만, 앞 줄을 꽉 채우려는 판단이 뒤 줄을 크게 비게 만드는 일이 잦습니다. 교과서의 반례(너비 11에 aaa bb cc dddd)를 눌러 보면 그리디는 벌점 53, 최적은 41입니다. 줄 수는 둘 다 2줄로 같은데 균형만 다릅니다.
마지막 줄은 벌점에서 빼는 것이 관행입니다. 문단의 마지막 줄은 원래 짧습니다. 그것까지 벌점에 넣으면 마지막 줄을 채우려고 앞 줄들을 억지로 늘리게 되어 오히려 어색해집니다. TeX도 마지막 줄에는 벌점을 매기지 않습니다. 위 선택을 바꿔 가며 배치가 어떻게 달라지는지 볼 수 있습니다.
글자 수로 재는 것과 픽셀로 재는 것은 다릅니다. 이 계산기는 글자 수로 폭을 잽니다. 실제 화면에서는 글꼴마다 글자 폭이 달라(비례폭 글꼴) 같은 글자 수라도 폭이 다릅니다. 폭을 무엇으로 재느냐만 바뀔 뿐 여기 쓴 알고리즘은 그대로 쓰이므로, 픽셀 폭이 필요하면 텍스트 폭 계산기로 재어 그 값을 넣으면 됩니다.
실제 TeX은 여기서 한 걸음 더 갑니다. 크누스–플라스 알고리즘은 낱말 사이 공백을 늘였다 줄였다 할 수 있는 «고무줄»로 보고, 하이픈 넣기·연속된 줄의 하이픈 벌점·문단을 넘기는 벌점까지 함께 최소화합니다. 이 계산기는 그 뼈대인 «문단을 통째로 보는 동적 계획법»만 다룹니다.

사용 방법

  1. 1문단을 넣습니다. 공백으로 나눈 것이 낱말 하나가 됩니다.
  2. 2한 줄 너비를 글자 수로 정합니다.
  3. 3그리디와 최적 배치를 나란히 놓고 줄 끝에 남는 칸을 견줍니다.
  4. 4너비를 한두 칸씩 바꿔 보면 차이가 커지기도 사라지기도 합니다.

자주 묻는 질문

아닙니다. 브라우저와 대부분의 편집기가 쓰는 그리디는 한 줄에 들어갈 만큼 넣고 안 들어가면 넘기는 방식이라, 앞 줄을 꽉 채우려는 판단이 뒤 줄을 크게 비게 만드는 일이 잦습니다. 너비 11에 aaa bb cc dddd를 넣으면 그리디는 벌점 53, 최적은 41입니다. 줄 수는 둘 다 2줄로 같고 균형만 다릅니다.

줄마다 남는 칸의 제곱을 더한 값(벌점)이 작을수록 좋다고 봅니다. 그냥 더하면 어떻게 나눠도 합이 거의 같아 구별이 안 갑니다. 제곱으로 매기면 한 줄이 크게 비는 것을 여러 줄이 조금씩 비는 것보다 훨씬 나쁘게 보므로, 오른쪽 끝이 고르게 맞는 배치가 이깁니다.

동적 계획법입니다. dp[i]를 «낱말 i부터 끝까지의 최소 벌점»으로 두면 dp[i] = min_j (벌점(i..j) + dp[j+1])입니다. 첫 줄에 어디까지 넣을지를 모두 시도하고 나머지는 이미 구한 답을 씁니다. 이 계산기는 낱말이 18개 이하일 때 모든 줄바꿈 조합(2^(n−1)가지)을 전수로 세어 같은 값이 나오는지 함께 확인합니다.

문단의 마지막 줄은 원래 짧기 때문입니다. 그것까지 벌점에 넣으면 마지막 줄을 채우려고 앞 줄들을 억지로 늘리게 되어 오히려 어색해집니다. TeX도 마지막 줄에는 벌점을 매기지 않습니다. 이 계산기는 두 방식을 모두 골라 볼 수 있게 해 두었습니다.

뼈대만 같습니다. 크누스–플라스 알고리즘은 낱말 사이 공백을 늘였다 줄였다 할 수 있는 «고무줄»로 보고, 하이픈 넣기·연속된 줄의 하이픈 벌점·문단을 넘기는 벌점까지 함께 최소화합니다. 이 계산기는 «문단을 통째로 보는 동적 계획법»이라는 핵심만 다룹니다.

어디에 두어도 줄을 넘치므로 혼자 한 줄을 쓰게 하고 벌점을 매기지 않습니다. 실제 조판에서는 이 자리에서 하이픈을 넣거나 글자를 잘라 넣습니다. 이 계산기는 그 줄을 «넘침»으로 표시합니다.

푸는 문제가 다릅니다. 텍스트 폭 계산기는 «이 글자열이 이 글꼴에서 몇 픽셀인가»를 잽니다. 이 계산기는 폭이 이미 정해졌다고 보고 «어디서 줄을 바꿀 것인가»를 정합니다. 폭을 무엇으로 재든 알고리즘은 그대로이므로, 픽셀 폭이 필요하면 그쪽에서 재어 여기에 넣으면 됩니다.

전송되지 않습니다. 계산은 모두 브라우저 안에서 이루어지고 넣은 값은 이 기기에만 남습니다.

알아두면 좋은 점

  • 폭은 글자 수(코드 포인트)로 잽니다. 비례폭 글꼴의 픽셀 폭과는 다릅니다.
  • 한글과 라틴 문자를 같은 한 칸으로 셉니다. 실제 화면에서는 한글이 대체로 두 배 넓습니다.
  • 낱말은 200개까지 받습니다. 전수 탐색 대조는 18개까지만 돌립니다.
  • 하이픈 넣기와 공백 늘이기는 다루지 않습니다. 크누스–플라스의 뼈대만 옮긴 것입니다.
  • 너비보다 긴 낱말은 혼자 한 줄을 쓰고 벌점을 매기지 않습니다.

함께 보면 좋은 도구

마지막 검증: 2026년 9월 2일 · 결과는 참고용 추정치입니다.