ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 게시판 페이징 알고리즘
    컴퓨터/개발 2008. 3. 6. 14:21

    많은 초급 phper들이 게시판을 이용해서 공부하면서 가장 힘들어하고 어려워 하는 페이징의 원리를 말씀드릴까 합니다.

    페이징...
     
    통상 이렇게 말하는데요 저는 네비게이터 라고 자주 말합니다. 게시판의 목록에 페이지를 넘겨줄 수 있는 번호 링크를 두고 하는 말이죠.. 그럼 시작해 볼까요~ 제가 수업시간에 네비게이터를 수업하게 되면 자주 써먹는 과제 중에 하나가 주어진 수의 범위가 있을 때 x라는 수를 입력 받으면 어느 범위에 속하는지 알아 내는 문제를 냅니다.

     ex ) 0~9, 10~19, 20~29  

    ※ 정확히 말하자면 범위의 첫 수를 구해내는 문제입니다. (0 ,10, 20) 자! 시간 5분 드립니다 풀어보세요!

    1초
    2초
    3초
    5분 끝!

    다 푸셨나요 -0-?
    왜 저 문제가 페이징 (네비게이터)와 관련있을까? 우리가 통상 php를 이용하여 프로그램을 제작하면 효율성등등 감안해서 많은 부분을 생각하게 됩니다. 하지만 이런건 숙련자들의 몫이죠 초급자는 아무리 강조해도 이런거 생각 못합니다. 그럼 무엇을 가지고 초급자들이 프로그램을 제작 해야할 까요? 무엇을 보여주고 어떻게 보여줄것인가!! 이게 관건입니다. 같이 문제를 풀어보죠.

    가령 5라는 수가 입력 되었다고 가정하면 (어이 거기 눈돌리지말고~ 잘봐!! 계산하고있지?) 계산하지마세요 계산은 여러분들이 하는게 아니죠? 서버(컴퓨터)가 해주는거에요 우리는 컴퓨터가 계산할 일정한 규칙성(계산식)을 만들어 주면 됩니다. 그럼 젤 먼저 해야될 일! 바로 변수의 선언입니다. 모든 프로그램에 공통적으로 시작할 때 일단 사용할 변수를 선언해 주는게 프로그램을 작성하면서 변수가 꼬인다거나 잘못된 값을 계산한다거나 하는 일 (버그)를 줄여줍니다.

    $psize = 10; //수의 범위 크기 입니다.
    $x = 5; //입력받은 수입니다.

    5가 어느 범위에 들어갈지 우리 머리속에는 이미 인지하고 있지만 논리적으로 계산식을 만드는 것은 꾀 어렵습니다. 그런데요 잘 생각해 보면 문제안에 항상 답이 있다는 거죠~ 범위의 첫수 0, 10, 20 을 구하는 식을 만들자면 5, 15, 25라는 수가 있을 때 일반적인 수학을 생각하면 절대 답 없습니다.

    5를 주어진 수의 범위로 일단 나누고 봅시다 0보다는 5가 크니 빼버리면 되겠지만 15가 입력된다면 15를 또 빼줘도 0이 되지 10이되지는 않겠죠?

    5-5=0
    15-15=0
    절대 자기 자신을 빼버려서는 답이 없다!!

    그래서 일단 나눠봅시다

    5/10 = ? 0.5
    15/10 = ? 1.5
    25/10 = ? 2.5

    음.. 뭔가 비슷한 모양이 나올거 같군요
    왜 나누냐고요? 더하거나 곱하면 수거 더 커지지 작아 지지는 않겠죠? 그래서 나누어 봤습니다. 그럼 저렇게 구해진 값을 이제 변수로 지정해 봅시다.

    $start_num = $x / $psize;

    일단 이런식이 만들어 지겠네요

    0.5 , 1.5, 2.5 이렇게 나온 값을 이제 php 내장 객체인 floor를 이용해서 소수점을 버려 봅시다!

    $start_num = floor($x / $psize);

    하니까 x의 값이 달라질 때 마다 0, 1, 2 라는 수를 start_num이 가지게 되겠죠? 그런데~ 여기서 끝난게 아닙니다. 0, 10, 20 이렇게 되도록 하고 싶은데요. 저런 수에다가 주어진 범위의 크기만큼 곱셈을 하면 어떻게 될까요?

    그렇습니다~

    $start_num = floor($x / $psize) * $psize;

    0은 아무리 큰수를 곱해도 0이고 1곱하기 10은 10, 2곱하기 10은 20이니

    우리가 원하는 범위의 첫번째 수를 구하는 것을 해결했습니다.

    그럼 저 공식이 왜 필요한가?

    보여주는 숫자를 보니 1부터 시작하는데... 페이지 번호는 0번부터라니.. 이상하자나요~ 하고 질문하는 학생 꼭 있습니다!! 그건 바로 배열과 관련된 부분과 물질수의 10진수와 수학의 10진수는 항상 1의 갭이 있다는걸 생각해야 합니다. 우리가 통상 사용하는 물질수의 10진수는 1,2,3,~10 이 겠지만 수학에서의 10진수는 0~9까지의 수를 말합니다.

    그럼 배열은? 배열에서 자동으로 부여되는 (php를 포함한 특정 언어만) 인덱스 key는 0부터 시작합니다. 물론 10진수고요.

    자 이제 1단계 과제가 해결되었습니다.

    ※ 2단계 과제
    주어진 글의 개수가 534개다 페이지당 10개씩 보여준다면
    페이지는 총 몇개의 페이지가 되는가?

    음.. 어렵나요? 쉽죠?

    10개씩 보여준다면야 당연히 10으로 나누면 총 페이지의 갯수가 나오는데요. 여기서 놓치기 쉬운 부분이 마지막에 남는 글의 갯수랍니다.

    534/10=? 53.4

    그럼 페이지 수가 53.4개라는건데 소수점은 어떻게 해주는게 좋을까요? 그렇습니다~ 바로 소수점 무조건 올림인 ceil 함수를 이용하여 올림수인 54페이지를 만들어 줘야 마지막에 남는 0.4페이지분량의 글을 모두 보여줄 수 있다는거죠

    그럼 총 페이지의 개수도 구했습니다.
    이제 해야할 마지막 관문!!!

    ※ 문제3 그럼 한 화면에 10개씩 페이지 번호를 보여준다면 이런 단위블럭이 몇개가 나오나요?

    위 문제와 유사하죠? 그렇습니다 3번문제가 요구하는 것은 네비게이터의 이전 , 다음 링크를 만들기 위한 조건으로 사용될 일정한 값을 구하기 위한 문제 입니다.

    그럼 실질적 아래 예제 코드를 이용해서 확인해 복습해 봅시다.

    <?
    $start = $_GET[start];
    $total = 534;//총 레코드수
    $scale = 10;//페이지당 출력 레코드수
    $page_scale = 10; // 화면당 출력할 페이지 수
    if(!$start) $start = 0;//시작 페이지 번호가 없을경우 0

    $total_page = ceil($total/$scale);//총 페이지수
    $page = floor($total_page/$page_scale);//단위블럭페이지수
    $n_page = floor($start/$page_scale);//현재 단위블럭 페이지번호

    if($n_page > 0){
    //이전 링크 출력 조건 현재단위블럭 페이지 번호가 0보다 클경우
        $p_start = ($n_page-1)*$page_scale;
    //현재 단위블럭 페이지 -1 * 단위블럭 페이지 출력수(page_scale)
        $link = "<a href='".$_SERVER[PHP_SELF]."?start=${p_start}'>";
        $link .= "이전";
        $link .= "</a>";
        echo $link." ";
    }
    $is = $n_page*$page_scale;//단위블럭 페이지 시작번호 구하기 현재 페이지 번호를 이용하여 현재 단위블럭 페이지 번호를 구하고 그 값을 이용하여 단위블럭 페이지 출력수를 곱한 값
    for($i=$is; $i < $is+$page_scale; $i++){
    //i는 현재 단위블럭 페이지 번호*단위블럭 페이지 출력수 부터 시작하고 i는 단위블럭 페이지 출력수를 더한 값만큼만 반복하도록 지정
        if($i < $total_page){//i가 총 페이지수 보다 작을 동안만 출력하기 위한조건
            $link = "<a href='".$_SERVER[PHP_SELF]."?start=${i}'>";
            $link .= $i+1;//start값이 i로 지정됨으로 화면상 출력기준을 1부터 시작하는 10진수로 맞추기 위해 +1을 연산
            $link .= "</a>";
            echo $link." ";
        }
    }

    if($n_page < $page){//현재 단위블럭 페이지번호 보다 총 단위블럭 페이지 수가 작을 경우에만 다음 링크 출력
        $link = "<a href='".$_SERVER[PHP_SELF]."?start=${i}'>";//i는 상단 for문에서 이미 마지막 페이지 start번호보다 +1한 값을 가지고 있기 때문에 i를 그냥 출력함
        $link .= "다음";
        $link .= "</a>";
        echo $link;
    }

    ?>

    어떠셨나요?
    선행 학습내용을 잘 읽어 보신분이라면 쉽게 이해가 되었을 것입니다. 선행 학습내용만 잘 이해한다면 어떠한 언어로로 페이징은 만들어 낼 수 있습니다. 코드가 중요한게 아니라 바로 로직 or 알고리즘이 중요하다는거 잊지맙시다

Designed by Tistory.