[Algorithm/Divide&Conquer] 10. 거듭 제곱 계산법

2024. 7. 2. 04:17·Computer Science/Algorithm

거듭 제곱 계산법

  • C^2을 계산하기 위해서는 다음과 같이 C 자신을 두 번 곱해야 한다
    • C^2 = C X C
  • C^n을 계산하려면 C 자신을 n번 곱해야 한다.
  • 이를 코드로 바꾸면 다음과 같다
int Power( int Base, int Exponent )
{
	int i=0;
	int Result = 1; // C^0은 1이므로
	for ( i=0; i<Exponent; i++ )
		Result *= Base;
	return Result;
}

 

  • 지수 크기만큼 곱셈을 수행하므로 O(n) 수행 시간을 소요한다는 사실을 알 수 있다.
  • 이보다 더 빠른 방법은 없을까?

접근

  • C^8은 C x C x C x C x C x C x C x C 로 정의되지만
  • 다음과 같이 표현할 수도 있다.

 

  • C^2을 구한 뒤 제곱을 두 번 더 반복하여 결국 세 번의 곱셈만 수행함으로써 같은 결과를 얻을 수 있다.
  • 하지만 이 방법을 모든 제곱 연산에 적용할 수는 없다.
    • 제곱 수가 홀수인 경우도 있기 때문
  • 제곱수가 홀수인 경우 다음 정리를 이용할 수 있다.

 

  • 이를 이용하여 재귀 방정식을 만들면 다음과 같다

 

구현

거듭 제곱은 기하 급수적으로 늘어나므로 unsigned long 타입에 저장하기로 하자

typedef unsigned long ULONG; // 64bit
ULONG Power(int Base, int Exponent) {
    if (Exponent == 1)
        return Base;
    else if (Base == 0)
        return 1;
    if (Exponent % 2 == 0) {
        ULONG NewBase = Power(Base, Exponent / 2);
        return NewBase * NewBase;
    } else {
        ULONG NewBase = Power(Base, (Exponent - 1) / 2);
        return (NewBase * NewBase) * Base;
    }
}

 

예제 프로그램

#include <stdio.h>

typedef unsigned long ULONG;

ULONG Power( int Base, int Exponent )
{
    if ( Exponent == 1 )
        return Base;
    else if ( Base == 0 )
        return 1;

    if ( Exponent % 2 == 0 )
    {
        ULONG NewBase = Power( Base, Exponent/2 );
        return NewBase * NewBase;        
    }
    else
    {
        ULONG NewBase = Power( Base, (Exponent-1)/2 );
        return (NewBase * NewBase) * Base;
    }
}

int main( void )
{
    int Base     = 2;
    int Exponent = 30;
    printf("%d^%d = %lu\n", Base, Exponent, Power( Base, Exponent ));

    return 0;
}

 

참조) 박상현, 『이것이 자료구조+알고리즘이다 with C언어』, 한빛미디어(2022) 

'Computer Science > Algorithm' 카테고리의 다른 글

[Algorithm/Greedy] 최단 작업 우선 스케줄링(shortest-job-first scheduling)  (0) 2024.07.03
[Algorithm/Greedy] About 그리디 알고리즘  (0) 2024.07.03
[Algorithm/Divide&Conquer] 09. 분할 정복을 적용하는데 있어서 주의할 점  (0) 2024.07.02
[Algorithm/Divide&Conquer] 08. L-트로미노 타일링  (0) 2024.07.02
[Algorithm/Divide&Conquer] 07. 최근접 점의 쌍(Closest Pair) 문제  (0) 2024.07.02
'Computer Science/Algorithm' 카테고리의 다른 글
  • [Algorithm/Greedy] 최단 작업 우선 스케줄링(shortest-job-first scheduling)
  • [Algorithm/Greedy] About 그리디 알고리즘
  • [Algorithm/Divide&Conquer] 09. 분할 정복을 적용하는데 있어서 주의할 점
  • [Algorithm/Divide&Conquer] 08. L-트로미노 타일링
lumana
lumana
배움을 나누는 공간 https://github.com/bebeis
  • lumana
    Brute force Study
    lumana
  • 전체
    오늘
    어제
    • 분류 전체보기 N
      • Software Development
        • Performance
        • TroubleShooting
        • Refactoring
        • Test
        • Code Style, Convetion
        • DDD
        • Software Engineering
      • Java N
        • Basic
        • Core
        • Collection
        • 멀티스레드&동시성
        • IO, Network
        • Reflection, Annotation
        • Modern Java(8~) N
        • JVM
      • Spring
        • Framework
        • MVC
        • Transaction
        • AOP
        • Boot
        • AI
      • DB Access
        • Jdbc
        • JdbcTemplate
        • JPA
        • Spring Data JPA
        • QueryDSL
      • Computer Science
        • Data Structure
        • OS
        • Database
        • Network
        • 컴퓨터구조
        • 시스템 프로그래밍
        • Algorithm
      • HTTP
      • 프로그래밍언어론
      • Programming Language(Sub)
        • Python
        • C++
        • JavaScript
      • FE
        • HTML
        • CSS
        • React
        • Application
      • Unix_Linux
        • Common
      • PS
        • BOJ
        • Tip
        • 프로그래머스
        • CodeForce
      • Book Review
        • Clean Code
      • Math
        • Linear Algebra
      • AI
        • DL
        • ML
        • DA
        • Concepts
      • 프리코스
      • Project Review
      • LegacyPosts
      • 모니터
      • Diary
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
lumana
[Algorithm/Divide&Conquer] 10. 거듭 제곱 계산법
상단으로

티스토리툴바