[Algorithm] Off-by-one error

JAsmine_log·2024년 6월 10일

Off-by-one error

Off-by-one error는 logic error로, 컴퓨터 프로그래밍에서 경계 조건을 확인할 때 종종 발생하는 문제이다. off-by-one은 1차이 오류라고 해석한다.

example

n개의 secton(구간)과 n+1 post(기둥)을 갖는 직선 울타리(fence)가 있다.
이 때, post error(telegraph pole or lamp-post error)는 특정 유형의 off-bye-one error이다.

만약에 100m의 긴 직선 울타리를 10미터짜리 기둥을 세워 만든다면 몇개의 공간을 만들 수 있을까? 직관적인 대답인 10은 틀리다. 울리리 구간은 10개이지만, 11개의 기둥이 필요하다.

If you build a straight fence 100 meters long with posts 10 meters apart, how many posts do you need?

Reverse error는 기둥의 숫자가 이미 알려져있고, 구간의 숫자가 같다고 가정할 때 발생한다. 실제 구간의 수는 기둥의 수보다 1개 적다. 정답은 조건에 따라서 n-1, n, n+1 이다. 정확한 문제 정의를 주의깊게 고려 해야한다. 초기 상황 설정이 문제의 다른 문제에 오답을 줄 수 있다.

If you have nn telegraph poles, how many gaps are there between them?

Fencepost errors는 기둥을 세는 대신 그 사이의 공간을 세거나, 그 반대로 공간을 세는 대신 기둥을 세거나, 또는 한 줄의 양 끝을 세어야 할지 말아야 할지를 고려하지 않아서 발생한다.

Computer Programming

Off-by-one-errors는 종종 루프(while, for loop)에서 발생한다. 배열에 많은 필드가 있고, 배열을 반복할 때 반복 회수가 하나 적거나 하나 많을 때 발생한다.

  • 반복 횟수가 적을 때 : 감지하기 어려운 논리 오류(logic errors)
  • 반복 횟수가 많을 때 : 런타임 오류(run-time errors)

반복 회수가 적을 때는 배열의 한 요소가 누락되는 때이다. 이는 보통 잘 감지되지 않고, 나타낼 수 있는 모든 단서는 하나의 요소(variable)가 초기화되지 않았거나 예상된 값을 갖지 않아서 이다.

이와 반대로 반복회수가 많을 때는 배열의 인덱스가 배열의 범위(dimension)를 벗어나는 것이다. 이는 런타임 오류를 초래하여 프로그램이 데이터 구조(data structure)의 크기를 검사하여 반복을 위한 요소가 부족하다는 것을 인식하고 발생한다.

Code (C++)

아래에서 string인 str="Hello, jasmine!"을 출력하는 것을 살펴보자. string lengnth는 15이지만, idx는 항상 size-1이기 떄문에, 0~14까지를 출력해야한다. idx 15는 null문자이다.

Idx0123456789101112131415
strHello,jasmine!\0

#include <iostream>
#include <string>
using namespace std;

int main()
{
    string str = "Hello, jasmine!";

    int n;
    n = str.length() - 1;

    for (int i = 0; i < n; i++)
    {
        cout << str[i];
    }
    cout << "\n";
>>
Hello, jasmine
    for (int i = 0; i < n; ++i)
    {
        cout << str[i];
    }
    cout << "\n";
>>
Hello, jasmine
    for (int i = 1; i < n; i++)
    {
        cout << str[i];
    }
    cout << "\n";
>>
ello, jasmine
    for (int i = 1; i < n; ++i)
    {
        cout << str[i];
    }
    cout << "\n";

>>
ello, jasmine
    for (int i = 0; i <= n; i++)
    {
        cout << str[i];
    }
    cout << "\n";
 >>
Hello, jasmine!
	for (int i = 0; i <= n; ++i)
    {
        cout << str[i];
    }
    cout << "\n";
>>
Hello, jasmine!
    for (int i = 1; i <= n; i++)
    {
        cout << str[i];
    }
    cout << "\n";
>>
ello, jasmine!
    for (int i = 1; i <= n; ++i)
    {
        cout << str[i];
    }
    cout << "\n";
>>
ello, jasmine!

	return 0;
}

그리고 만약에 복사되는 string보다 복사하는 string이 더 클 경우에는 runtime error 가 발생한다.


Reference
[1] https://simple.wikipedia.org/wiki/Off-by-one_error

profile
Everyday Research & Development

0개의 댓글