일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- c#
- 표준 라이브러리 함수
- 추천
- 충남 천안
- 실습
- 산책하기 좋은 곳
- 무료 동영상 강의
- 캡슐화
- 파이썬
- 실습으로 다지는 c#
- 알고리즘
- C++
- 네트워크 프로그래밍
- 강의
- 소켓 통신
- 졸업 작품 소재
- 프로젝트
- 클래스 다이어그램
- 언제나휴일
- 동영상
- 졸업 작품
- 안드로이드 앱 개발
- 표준 입출력
- Windows Forms
- 언제나 휴일
- 원격 제어 프로그램
- c언어
- 소스 코드
- 유튜브 동영상 강의
- 동영상 강의
Archives
- Today
- Total
프로그래밍 언어 및 기술 [언제나휴일]
[C++] 73. 최종 실습 – 확장 가능한 순차 배열 본문
EhNara 프로그램에서는 EhNara 클래스, 학생 공장에서 학생 개체를 보관합니다. 그리고 장소에서는 사람 개체를 보관합니다. 여기에서는 순차적으로 보관할 수 있는 확장 가능한 배열을 템플릿으로 정의합시다.
확장 가능한 배열은 저장소가 꽉 차면 내부에서 저장소의 크기를 늘려 주어 사용하는 개발자가 저장소의 크기에 신경을 쓰지 않고 사용할 수 있는 동적 배열입니다.
여기에서는 순차 보관하는 기능과, 특정 인덱스의 요소를 제거, 특정 알고리즘이 참인 인덱스를 구하는 등의 기능을 제공하는 확장 가능한 배열을 만듭시다.
template <typename data>
class SeqArray
{
먼저 저장소와 저장소의 크기, 보관 개수를 기억하고 있어야 합니다.
data *base; //저장소
size_t capacity; //저장소 크기
size_t size; //보관 개수
public:
생성자에서는 멤버 필드의 값을 0으로 초기화합시다.
SeqArray()
{
base = 0;
capacity = 0;
size = 0;
}
소멸자에서는 저장소를 할당하였을 때 저장소를 해제하는 구문이 필요하겠죠.
~SeqArray(void)
{
if(base)//저장소가 있을 때
{
delete[] base;//저장소 해제
}
}
순차 보관하는 메서드를 구현합시다.
void PushBack(data value)//순차 보관
{
꽉 차면 저장소를 늘려주어야 합니다.
if(IsFull())//꽉차면
{
현재 저장소의 크기가 0이 아니면 두 배로 늘리고 0이면 1로 늘리기로 합시다.
if(capacity)//저장소의 개수가 참일 때
{
Reserve(capacity *2);//두 배로 확장
}
else//아닐 때(0일 때)
{
Reserve(1);//1로 확장
}
}
입력 인자로 받은 값을 순차 보관하고 보관 개수를 1 증가하세요.
base[size] = value;//보관
size++;//보관 개수 1 증가
}
특정 인덱스 요소를 삭제하는 메서드를 구현합시다.
void RemoveAt(size_t index)//특정 인덱스 요소 삭제
{
인덱스가 유효하지 않으면 메서드를 종료합니다.
if(IsAvailIndex(index)==false)//인덱스가 유효하지 않을 때
{
return;
}
인덱스가 유효하면 보관 개수를 1 감소합니다. 그리고 인덱스 뒤의 값들을 한 칸씩 앞으로 이동합니다.
size--;//보관 개수 1 감소
for( ;index<size;index++)
{
base[index] = base[index+1];//한 칸씩 앞으로 이동
}
}
특정 알고리즘이 처음으로 참인 위치를 찾는 메서드를 제공합시다. 특정 알고리즘은 find_if로 가정합시다.
template <typename find_if>
int FindIf(find_if fun)//특정 알고리즘이 처음으로 참인 위치 찾기
{
순차적으로 입력 알고리즘에 보관한 값을 적용합니다.
for(size_t i = 0; i<size; ++i)
{
if(fun(base[i]))//알고리즘에 적용하였을 때 참이면
{
만약 참인 부분을 만나며 인덱스를 반환합니다.
return i; //인덱스 반환
}
}
끝까지 반복해도 참인 부분을 만나지 못하면 -1을 반환합시다.
return -1;//-1 반환
}
인덱스 연산자를 중복 정의합시다.
data &operator[](size_t index)//인덱서
{
인덱스가 유효하지 않으면 예외를 던져줍니다.
if(IsAvailIndex(index)==false)//유효하지 않은 인덱스일 때
{
throw "유효하지 않은 인덱스를 사용하였습니다.";//예외 던짐
}
인덱스가 유효하면 해당 인덱스의 원소를 반환합니다.
return base[index];//인덱스의 원소 반환
}
유효한 인덱스인지 판별하는 메서드와 보관한 원소 개수를 반환하는 메서드를 제공합시다.
bool IsAvailIndex(size_t index)const//유효한 인덱스인지 판별
{
return (index>=0)&&(index<size);
}
size_t GetSize()const
{
return size;
}
private:
꽉 찼는지 판별하는 메서드도 구현하세요.
bool IsFull()const//꽉 찼는지 판별
{
return size == capacity;
}
저장소를 확장하는 메서드를 구현합시다.
void Reserve(int ncapacity)//저장소 확장
{
저장소의 위치를 임시 변수에 설정합니다.
data *tbuf = base;//저장소 위치를 tbuf로 설정
새로운 저장소를 동적 할당합니다.
base = new data[ncapacity];//저장소 동적 할당
저장소의 크기를 설정합니다.
capacity = ncapacity;//저장소 크기 설정
if(tbuf)//이전 저장소가 참이면
{
이전 저장소가 있었다면 원래 보관한 값을 새로운 저장소에 보관합니다.
for(size_t i=0; i<size;++i)
{
base[i] = tbuf[i];//이전 저장소에 보관한 값을 새로운 저장소로 이동
}
이전 저장소의 메모리는 해제합니다.
delete[] tbuf;//이전 저장소 메모리 해제
}
}
};
다음은 이를 테스트 하기 위한 코드를 포함한 전체 코드입니다.
//SeqArray.h
#pragma once
template <typename data>
class SeqArray
{
data *base; //저장소
size_t capacity; //저장소 크기
size_t size; //보관 개수
public:
SeqArray()
{
base = 0;
capacity = 0;
size = 0;
}
~SeqArray(void)
{
if(base)//저장소가 있을 때
{
delete[] base;//저장소 해제
}
}
void PushBack(data value)//순차 보관
{
if(IsFull())//꽉차면
{
if(capacity)//저장소의 개수가 참일 때
{
Reserve(capacity *2);//두 배로 확장
}
else//아닐 때(0일 때)
{
Reserve(1);//1로 확장
}
}
base[size] = value;//보관
size++;//보관 개수 1 증가
}
void RemoveAt(size_t index)//특정 인덱스 요소 삭제
{
if(IsAvailIndex(index)==false)//인덱스가 유효하지 않을 때
{
return;
}
size--;//보관 개수 1 감소
for( ;index<size;index++)
{
base[index] = base[index+1];//한 칸씩 앞으로 이동
}
}
template <typename find_if>
int FindIf(find_if fun)//특정 알고리즘이 처음으로 참인 위치 찾기
{
for(size_t i = 0; i<size; ++i)
{
if(fun(base[i]))//알고리즘에 적용하였을 때 참이면
{
return i; //인덱스 반환
}
}
return -1;//-1 반환
}
data &operator[](size_t index)//인덱서
{
if(IsAvailIndex(index)==false)//유효하지 않은 인덱스일 때
{
throw "유효하지 않은 인덱스를 사용하였습니다.";//예외 던짐
}
return base[index];//인덱스의 원소 반환
}
bool IsAvailIndex(size_t index)const//유효한 인덱스인지 판별
{
return (index>=0)&&(index<size);
}
size_t GetSize()const
{
return size;
}
private:
bool IsFull()const//꽉 찼는지 판별
{
return size == capacity;
}
void Reserve(int ncapacity)//저장소 확장
{
data *tbuf = base;//저장소 위치를 tbuf로 설정
base = new data[ncapacity];//저장소 동적 할당
capacity = ncapacity;//저장소 크기 설정
if(tbuf)//이전 저장소가 참이면
{
for(size_t i=0; i<size;++i)
{
base[i] = tbuf[i];//이전 저장소에 보관한 값을 새로운 저장소로 이동
}
delete[] tbuf;//이전 저장소 메모리 해제
}
}
};
//Program.cpp
#include <iostream>
using namespace std;
#include "SeqArray.h"
class FindFun
{
int value;
public:
FindFun(int value)
{
this->value = value;
}
bool operator()(int data)
{
return value == data;
}
};
int main()
{
SeqArray<int> sa;
sa.PushBack(3);
sa.PushBack(9);
sa.PushBack(2);
sa.PushBack(4);
size_t size = sa.GetSize();
for(size_t i = 0; i<size; i++)
{
cout<<sa[i]<<" ";//3 9 2 4
}
cout<<endl;
sa.RemoveAt(2);
size = sa.GetSize();
for(size_t i = 0; i<size; i++)
{
cout<<sa[i]<<" ";//3 9 4
}
cout<<endl;
FindFun ff(3);
size_t index = sa.FindIf(ff);
if(index!=-1)
{
cout<<3<<" is located at index "<<index<<endl;
cout<<"sa["<<index<<"]:"<<sa[index]<<endl;
}
return 0;
}
▷ 실행 결과
3 9 2 4
3 9 4
3 is located at index 0
sa[0]:3
'C & C++ > 디딤돌 C++' 카테고리의 다른 글
[C++] 74. 최종 실습 – 클래스 추가하기 (1) | 2024.04.19 |
---|---|
[C++] 72. 최종 실습 – 프로토 타이핑 (0) | 2024.04.16 |
[C++] 71. 최종 실습 – EHNARA 뼈대 (0) | 2024.04.16 |
[C++] 70. 최종 실습 – 설계1(클래스 다이어그램) (0) | 2024.04.16 |
[C++] 69. 최종 실습 – 요구 분석 및 정의 (0) | 2024.04.16 |
[C++] 68. 최종 실습 – 개발 공정 및 시나리오 (0) | 2024.04.16 |
[C++] 67. 실현(REALIZATION) 관계 (0) | 2024.04.13 |
[C++] 66. 의존(DEPENDENCY) 관계 (0) | 2024.04.13 |