이 글에서는 C++의 fdim() 함수에 대해 자세히 알아보겠습니다. fdim() 함수는 두 인수 사이의 양수 차이(positive difference)를 반환하는 수학 함수입니다. 두 인수가 각각 a와 b라고 할 때, a > b이면 a - b를 반환하고, 그렇지 않으면 0을 반환합니다. 이 함수는 <cmath> 헤더 파일에 정의되어 있으며, 결과값이 음수가 되지 않아야 하는 상황에서 유용하게 활용됩니다. 예제 코드 #include <cmath> #include <iostream> using
C++에서는 부동소수점 값을 정수로 변환할 때 단순한 형 변환 외에도, 현재 설정된 반올림 모드를 따르는 전용 함수들을 제공합니다. 이번 글에서는 그중 lrint()와 llrint() 함수의 개념과 사용법을 예제와 함께 자세히 살펴보겠습니다. lrint() 함수란? lrint() 함수는 인자로 전달된 소수점 값을 현재 반올림 모드(current rounding mode)에 따라 정수 값으로 반올림합니다. 반올림 모드는 <cfenv> 헤더의 fesetround() 함수를 통해 설정할 수 있으며, FE_UPWARD(올림)
프로그래밍을 하다 보면 입력받아야 할 값의 개수가 미리 정해져 있지 않은 경우가 종종 있습니다. 이번 글에서는 C++의 cin을 활용하여 개수가 정해지지 않은 입력을 처리하는 방법을 살펴보겠습니다. 가장 단순한 해결책은 반복문을 돌리다가 특정 값이 입력되면 종료하는 것입니다. 하지만 더 깔끔한 방법은 cin >> input의 반환 값을 조건으로 활용하는 것입니다. cin은 숫자가 아닌 값(문자 등)이 입력되면 스트림 상태가 실패(fail)로 설정되어 false로 평가되므로, 이를 이용하면 별도의 종료 신호 없이도 자연스
C와 C++에서는 정수형 데이터를 처리하기 위해 short, int, long, long long 네 가지 데이터 타입을 제공합니다. 각 타입은 서로 다른 크기의 메모리 공간을 차지하며, 그 크기는 CPU 아키텍처와 운영체제, 심지어 컴파일러에 따라서도 달라질 수 있습니다.예를 들어 int 타입은 어떤 시스템에서는 4바이트, 어떤 시스템에서는 2바이트를 차지하기도 합니다. 이러한 차이는 크로스 컴파일러(cross compiler)를 사용할 때 특히 두드러집니다. 크로스 컴파일러란 현재 개발 환경과 다른 플랫폼을 대상으로 코드를 컴파
요즘 배포되는 컴파일러는 대부분 기본적으로 64비트 버전입니다. 하지만 때로는 32비트 시스템에서 코드를 컴파일하고 실행해야 하는 경우가 있습니다. 이럴 때 GCC의 -m32 옵션과 멀티라이브러리(multilib) 기능을 활용하면 됩니다.1. 현재 GCC 타깃 아키텍처 확인하기먼저 현재 사용 중인 GCC 컴파일러의 타깃 아키텍처를 확인해야 합니다. 다음 명령어를 입력하면 확인할 수 있습니다.gcc –v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x8
개요이 글에서는 주어진 정수를 여러 개의 양의 정수 합으로 표현하는 모든 고유한 분할(unique partition)을 구하는 C++ 프로그램을 소개합니다. 예를 들어 4가 주어지면 4, 3+1, 2+2, 2+1+1, 1+1+1+1처럼 순서만 다른 중복 조합은 제외하고 각 분할의 합이 원래 수가 되는 모든 경우를 출력합니다.알고리즘핵심 아이디어는 첫 번째 분할을 숫자 자기 자신으로 초기화한 뒤, 규칙에 따라 다음 분할을 하나씩 생성하며 마지막 분할(모두 1로만 이루어진 경우)에 도달할 때까지 반복하는 것입니다.시작 함수 displa
이 프로그램은 임의의 정점(vertex)과 간선(edge)을 이용해 랜덤 그래프를 생성합니다. 프로그램의 시간 복잡도는 O(v × e)이며, 여기서 v는 정점의 개수, e는 간선의 개수를 의미합니다. 동작 원리 정점·간선 개수 결정: rand() 함수를 사용해 그래프의 정점 개수와 간선 개수를 무작위로 정합니다. 간선 생성: 두 정점 번호를 무작위로 뽑아 간선으로 연결하되, 자기 자신에게 연결되는 셀프 루프(self-loop)와 중복 간선은 제외합니다. 연결 정보 출력: 방향에 관계없이 각 정점에 연결된 다른 정점들을 출력합니다.
이분 그래프(Bipartite Graph)란?이분 그래프는 그래프의 모든 정점을 두 가지 색상만으로 색칠할 수 있으면서, 인접한 정점끼리는 항상 서로 다른 색을 갖도록 구성된 그래프를 의미합니다. 즉, 정점들을 두 개의 집합으로 분할했을 때, 같은 집합에 속한 정점들은 동일한 색으로 칠해지며 서로 직접 연결되지 않습니다.이번 글에서는 C++과 깊이 우선 탐색(DFS)을 활용하여 주어진 그래프가 이분 그래프인지 판별하는 프로그램을 살펴보겠습니다.알고리즘각 노드의 색상을 저장하기 위해 color[] 배열을 사용합니다. 저장되는 값 0과
방향 그래프(directed graph)가 주어졌을 때, 그래프 내 모든 정점 쌍 (i, j)에 대해 정점 j가 정점 i로부터 도달 가능한지(reachable) 판별할 수 있습니다. 여기서 도달 가능하다는 것은 정점 i에서 출발하여 정점 j에 이르는 경로가 하나라도 존재한다는 의미입니다. 이러한 도달 가능 여부를 행렬 형태로 나타낸 것을 그래프의 전이 폐쇄(Transitive Closure)라고 부릅니다. 전이 폐쇄를 구하는 대표적인 방법은 워셜 알고리즘(Warshall Algorithm)입니다. 이 글에서는 워셜 알고리즘의 동작
C++에서 std::string(문자열)을 char 배열로 변환해야 하는 상황은 생각보다 자주 발생합니다. C 스타일 API와 연동하거나 특정 라이브러리 함수에 인자를 전달할 때가 대표적입니다. 이번 글에서는 문자열을 char 배열로 변환하는 여러 가지 방법을 코드 예제와 함께 살펴보겠습니다.방법 1: 반복문으로 한 문자씩 복사하기알고리즘시작 char 배열 변수 m에 문자열 값을 할당한다. string 변수 str을 정의한다. &n
AVL 트리는 자가 균형(self-balancing) 이진 탐색 트리의 한 종류로, 트리 내 모든 노드에서 왼쪽 서브트리와 오른쪽 서브트리의 높이 차이가 1을 초과하지 않는 것이 특징입니다. 이러한 균형 속성 덕분에 AVL 트리는 삽입, 삭제, 탐색 연산을 O(log n)의 시간 복잡도로 보장할 수 있습니다.이 글에서는 주어진 이진 트리가 AVL 트리인지 아닌지를 판별하는 C++ 프로그램을 소개합니다.알고리즘AVL 트리 판별은 재귀적으로 해결할 수 있습니다. 각 노드에 대해 왼쪽과 오른쪽 서브트리의 높이 차이를 계산하고, 그 차이가
가상 메커니즘의 동작 조건C++의 가상(virtual) 메커니즘은 기본 클래스(base class) 포인터가 파생 클래스(derived class) 객체를 가리킬 때에만 작동합니다. 즉, 런타임에 실제 객체의 타입을 판단하여 올바른 함수를 호출하는 방식이므로, 이미 생성된 객체와 그 객체 내부의 가상 테이블(vtable) 정보가 필요합니다.생성자는 왜 가상으로 만들 수 없는가?C++에서 생성자는 가상 함수로 선언할 수 없습니다. 그 이유는 다음과 같습니다.클래스의 생성자가 실행되는 시점에는 아직 메모리에 가상 테이블(virtual
C++의 가상 함수(virtual function)는 기본 클래스 포인터들의 목록을 만들어 두고, 파생 클래스 객체의 실제 타입을 알지 못하더라도 해당 파생 클래스의 메서드를 호출할 수 있도록 해주는 핵심 기능입니다. 가상 함수는 컴파일 시점이 아닌 런타임에 호출 대상이 결정되며, 이러한 방식을 늦은 바인딩(late binding) 또는 동적 바인딩이라고 부릅니다.내부적으로는 virtual 키워드가 붙은 함수마다 클래스 단위의 가상 함수 테이블(vtable)이 생성되고, 각 객체는 자신의 vtable을 가리키는 숨겨진 포인터를 가집
직접 주소 지정 테이블(Direct Addressing Table)은 각 요소가 전체 집합(universal set) S = {0, 1, ..., n−1}에서 추출된 키(key)를 가질 때 사용하는 자료구조입니다. 이때 n은 너무 크지 않아야 하며, 모든 키는 서로 중복되지 않는 고유한 값이어야 합니다. 이 자료구조의 가장 큰 장점은 키 값이 곧 배열의 인덱스라는 점입니다. 해시 함수나 별도의 탐색 과정 없이 키를 인덱스로 바로 사용하기 때문에 삽입(insert), 검색(search), 삭제(delete) 연산을 모두 O(1)의 시
서로소 집합(Disjoint Set)은 어떤 원소도 두 개 이상의 집합에 동시에 속할 수 없는, 서로 겹치지 않는 집합들의 모음입니다. 흔히 유니온-파인드(Union-Find)라고도 불리며, 부분집합에 대해 Union과 Find라는 두 가지 핵심 연산을 지원합니다. 주요 연산 Find(): 특정 원소가 어느 부분집합에 속해 있는지 찾는 연산으로, 해당 집합의 대표 원소(representative)를 반환합니다. Union(): 서로 다른 두 부분집합을 하나의 집합으로 병합하는 연산입니다. 병합이 완료되면 한 집합의 대표 원소가 다른
프라이발츠(Freivalds) 알고리즘이란? 프라이발츠 알고리즘은 세 개의 정방행렬에 대해 matrix1 × matrix2 = matrix3라는 등식이 실제로 성립하는지 판별하는 확률적(randomized) 알고리즘입니다. 행렬 곱셈을 직접 수행해 결과를 비교하는 대신, 무작위로 생성한 벡터를 활용해 검증하기 때문에 매우 효율적입니다. k회 반복했을 때 잘못된 판정을 내릴 확률은 2-k 미만이며, 시간 복잡도는 O(kn²)입니다. 일반적인 행렬 곱셈에는 O(n³)의 시간이 걸린다는 점을 고려하면, 이 알고리즘이 행렬 곱셈 결과 검증
이 글에서는 가우스-조던 소거법을 C++로 구현하는 방법을 소개합니다. 가우스-조던 소거법은 연립 선형 방정식을 풀기 위해 널리 사용되는 알고리즘으로, 행 연산(row operation)을 반복적으로 적용하여 방정식 계수 행렬을 대각행렬 형태로 변환합니다. 이렇게 하면 별도의 후처리 과정 없이 해를 직접 얻을 수 있다는 것이 큰 장점입니다.알고리즘 개요가우스-조던 소거법의 핵심 동작 과정은 다음과 같습니다.시작 n = 입력 행렬의 크기 대각행렬의 원소를 찾는 과정: j = 0부터 n까지, i = 0부터 n까지
가우스-자이델(Gauss-Seidel) 방법은 연립 선형 방정식을 반복법으로 풀 때 널리 사용되는 수치 해석 기법입니다. 이 글에서는 가우스-자이델 방법을 구현한 C++ 프로그램을 알고리즘, 코드, 실행 결과 순으로 살펴봅니다. 가우스-자이델 방법 개요 가우스-자이델 방법은 야코비(Jacobi) 반복법과 비슷하지만 한 가지 중요한 차이가 있습니다. 바로 각 반복 단계에서 새로 계산된 변수 값을 즉시 다음 변수의 계산에 활용한다는 점입니다. 덕분에 일반적으로 야코비 방법보다 더 빠르게 수렴하는 경향이 있습니다. 다만 이 방법이 항상
이 글에서는 선형 연립방정식을 행렬 형태로 나타내는 C++ 프로그램을 다룹니다. 사용자로부터 변수의 개수와 각 변수의 계수를 입력받은 뒤, 이를 계수 행렬과 상수 벡터의 곱 형태인 Ax = d 구조로 출력해 줍니다.알고리즘시작 1) 변수의 개수 n과 각 변수의 계수를 입력받는다. 2) matrix[n][n] 배열과 constant[n][1] 배열을 선언한다. 3) 이중 반복문(i = 0 ~ n-1, j = 0 ~ n-1)을 사용하여 각 변수의 계수를 행렬의 원소로 입력받는다. 4) 중첩된 f
이 프로그램은 C++을 활용해 전기 회로에서 각 부품(컴포넌트)을 연결하는 배선(와이어) 길이를 최소화하는 방법을 다룹니다. 내부적으로는 그래프 이론의 대표적인 최단 경로 알고리즘인 다익스트라(Dijkstra) 알고리즘을 사용하여, 시작 부품으로부터 나머지 모든 부품까지의 최단 거리를 계산합니다.회로는 인접 행렬 형태의 그래프로 표현되며, 행렬의 각 요소 g[u][v]는 부품 u와 v 사이의 배선 길이(가중치)를 의미합니다. 값이 0이면 두 부품이 직접 연결되어 있지 않음을 뜻합니다.알고리즘시작 함수 optimizeLengt