벡터의 임의 접근은 시간 복잡도가 O(1)이다.

벡터의 크기를 확장할 때, 복사(이동)가 일어나므로 선형 시간이 소요된다. 만약 사용하려는 벡터의 사이즈를 어느정도 알고 있다면 크기를 미리 정해주는 것이 좋다.

 

벡터의 구현

  • 멤버 변수 : 힙메모리의 위치를 가리키는 포인터, current size(size), max size(capacity)
  • 함수 : front, back, size, capacity, push_back, pop_back
  • 생성자, 소멸자
더보기
#pragma once

#include <iostream>

template<typename T>
class MyVector {
public:
	MyVector(const int& _maxCapacity = 10) {
		currentSize_ = 0;
		maxCapacity_ = _maxCapacity;
		data_ = new T[maxCapacity_];
	}

	~MyVector() {
		if (nullptr != data_) {
			delete[] data_;
			data_ = nullptr;
		}
	}

	void push_back(const T& _data);
	void pop_back();
	T& front() const;
	T& back() const;
	T& at(const int& _index) const;
	bool empty() const;
	int size() const;
	int capacity() const;

	T& operator[](const int& _index) const;

private:
	void realloc();

private:
	T* data_;

	int currentSize_;
	int maxCapacity_;
};

template<typename T>
inline void MyVector<T>::push_back(const T& _data)
{
	if (currentSize_ == maxCapacity_)
		realloc();

	data_[currentSize_++] = _data;
}

template<typename T>
inline void MyVector<T>::pop_back()
{
	if (currentSize_ > 0)
		--currentSize_;
}

template<typename T>
inline T& MyVector<T>::front() const
{
	if (currentSize_ > 0)
		return data_[0];

	throw std::out_of_range("vector out of range");
}

template<typename T>
inline T& MyVector<T>::back() const
{
	if (currentSize_ > 0)
		return data_[currentSize_ - 1];

	throw std::out_of_range("vector out of range");
}

template<typename T>
inline T& MyVector<T>::at(const int& _index) const
{
	if (_index < currentSize_)
		return data_[_index];

	throw std::out_of_range("vector out of range");
}

template<typename T>
inline bool MyVector<T>::empty() const
{
	return currentSize_ == 0;
}

template<typename T>
inline int MyVector<T>::size() const
{
	return currentSize_;
}

template<typename T>
inline int MyVector<T>::capacity() const
{
	return maxCapacity_;
}

template<typename T>
inline T& MyVector<T>::operator[](const int& _index) const
{
	return at(_index);
}

template<typename T>
inline void MyVector<T>::realloc()
{
	T* newData = new T[maxCapacity_ * 2];

	for (int i = 0; i < currentSize_; ++i)
		newData[i] = std::move(data_[i]);

	delete[] data_;
	data_ = newData;

	maxCapacity_ *= 2;
}

 

Ver.2

더보기
#include "GlobalDefine.h"

template<typename _Ty>
class MyVector {
public:
	MyVector() :
		currentSize_(0),
		maxCapacity_(0),
		data_(nullptr)
	{}

	explicit MyVector(const int& _maxCapacity, const _Ty& _ty = _Ty()) :
		currentSize_(0),
		maxCapacity_(_maxCapacity),
		data_(nullptr)
	{
		data_ = new _Ty[_maxCapacity];

		for (int i = 0; i < _maxCapacity; ++i)
			push_back(_ty);
	}

	explicit MyVector(const MyVector& _vec) :
		currentSize_(0),
		maxCapacity_(_vec.maxCapacity_),
		data_(nullptr)
	{
		this->operator=(_vec);
	}

	//explicit MyVector(MyVector&& _vec) noexcept :
	//	currentSize_(_vec.currentSize_),
	//	maxCapacity_(_vec.maxCapacity_),
	//	data_(_vec.data_)
	//{
	//	this->operator=(std::forward<_Ty>(_vec));
	//}

	~MyVector()
	{
		if (nullptr != data_) {
			delete[] data_;
			data_ = nullptr;
		}
	}

public:
	MyVector& operator=(const MyVector& _vec)
	{
		maxCapacity_ = _vec.maxCapacity_;
		data_ = new _Ty[_vec.maxCapacity_];

		for (int i = 0; i < _vec.maxCapacity_; ++i)
			push_back(_vec[i]);
	}

	//MyVector& operator=(MyVector&& _vec) noexcept
	//{
	//	/* 수정해야됨. 주소만 들고오는게 아니라 전체 요소를 move? */
	//	currentSize_ = _vec.currentSize_;
	//	maxCapacity_ = _vec.maxCapacity_;
	//	data_ = _vec.data_;

	//	_vec.currentSize_ = 0;
	//	_vec.maxCapacity_ = 0;
	//	_vec.data_ = nullptr;
	//}

	_Ty& operator[](const int& _idx) const
	{
		return this->at(_idx);
	}

public:
	void push_back(const _Ty& _data)
	{
		if (currentSize_ >= maxCapacity_) {
			if (maxCapacity_ < 2)
				++maxCapacity_;
			else
				maxCapacity_ += maxCapacity_ / 2;

			_Ty* newData = new _Ty[maxCapacity_];
			for (int i = 0; i < currentSize_; ++i) {
				newData[i] = data_[i];
			}
			if (data_)
				delete[] data_;

			data_ = newData;
		}
		data_[currentSize_] = _data;
		++currentSize_;
	}

	void emplace_back(const _Ty& _data)
	{
		push_back(_data);
	}

	void emplace_back(_Ty&& _data) noexcept
	{
		if (currentSize_ < maxCapacity_) {
			data_[currentSize_] = std::move(_data);
			++currentSize_;
		}
		else
			push_back(_data);
	}

	void pop_back()
	{
		if (!empty()) --currentSize_;
	}

	_Ty& front() const
	{
		if (currentSize_ <= 0) abort();
		return at(0);
	}

	_Ty& back() const
	{
		if (currentSize_ <= 0) abort();
		return at(currentSize_ - 1);
	}

	_Ty& at(const int& _index) const
	{
		if (_index > currentSize_) abort();
		return *(data_ + _index);
	}

	bool empty() const
	{
		return currentSize_ <= 0;
	}

	int size() const
	{
		return currentSize_;
	}

	int capacity() const
	{
		return maxCapacity_;
	}

private:
	_Ty* data_;

	int currentSize_;
	int maxCapacity_;
};

 

algorithm 헤더가 제공하는 find 함수는 선형 탐색이다.

search 함수는 두 컨테이너 또는 배열을 비교하여 연속된 데이터가 존재하는 첫 번째 위치를 반환한다.

'이론 > 자료구조&알고리즘' 카테고리의 다른 글

Recursion Basics  (0) 2023.02.09
Bit Manipulation  (0) 2023.02.09
Pointers & Dynamic Memory  (0) 2023.02.07
2D Arrays  (0) 2023.02.07
Character Arrays/Strings  (0) 2023.02.03

스택 메모리는 컴파일러에 의해 할당된다.

포인터 변수 자체는 스택 메모리에 할당되지만 동적 할당은 힙 메모리에 할당된다.

 

그 외 특별한 내용 없이 아는 것들이라 넘어간다.

'이론 > 자료구조&알고리즘' 카테고리의 다른 글

Bit Manipulation  (0) 2023.02.09
Vector Data Structure  (0) 2023.02.08
2D Arrays  (0) 2023.02.07
Character Arrays/Strings  (0) 2023.02.03
Basic Sorting Algorithms  (0) 2023.02.03

Spiral Print

 

더보기
void print(int arr[][10],int n,int m){
    //4 variables
    int startRow = 0;
    int endRow = n - 1;
    int startCol = 0;
    int endCol = m - 1;

    //Outer Loop (Traverse array boundary)
    while(startCol<= endCol and startRow <=endRow){

        //Start Row
        for(int col = startCol ; col<=endCol; col++){
            cout << arr[startRow][col]<<" ";
        }

        //End Col
        for(int row=startRow + 1;row<=endRow;row++){
            cout << arr[row][endCol]<<" ";
        }

        //End Row
        for(int col=endCol - 1; col>=startCol;col--){
            if(startRow==endRow){
                break;
            }
            cout<< arr[endRow][col]<<" ";
        }   

        //Start Col
        for(int row = endRow-1; row >=startRow + 1;row--){
            //Avoid Duplicate Printing of elements
            if(startCol==endCol){
                break;
            }
            cout<< arr[row][startCol] <<" ";
        }

        //update the variables to point to inner spiral
        startRow++;
        endRow--;
        startCol++;
        endCol--;
    }
}

행렬을 순회할 포인터 4개를 정해서 출력한다.

이 방법 말고도 좌표를 미리 설정해두고 출력하는 방법도 가능할 것 같다.

 

 

Ramu's Mango Trees

문제 링크 : https://www.iarcs.org.in/inoi/online-study-material/topics/prefix-sums-ramus-mango-trees.php

2차원 배열을 보조 배열로 나누어 생각한다.

2차원 배열 arr(x,y)가 주어지고 M(x,y)가 arr(x,y)까지의 누적합 배열이라고 할 때,

M(x,y) = M(x-1,y) + M(x,y-1) - M(x-1,y-1) + arr(x,y) 이 성립된다.

 

각 구역을 구하는 식은 다음과 같다

S1 = M(x,y)

S2 = M(N,y) - M(x,y)

S3 = M(x,N) - M(x,y)

S4 = M(N,N) - (S1 + S2 + S3)

'이론 > 자료구조&알고리즘' 카테고리의 다른 글

Vector Data Structure  (0) 2023.02.08
Pointers & Dynamic Memory  (0) 2023.02.07
Character Arrays/Strings  (0) 2023.02.03
Basic Sorting Algorithms  (0) 2023.02.03
Arrays  (0) 2023.02.02

입력 : cin

cin.get()은 입력 버퍼에서 한글자씩 받아올 수 있기 때문에 공백을 포함한 문자(열)도 입력할 수 있다.

 

char ch;
ch = cin.get();

int alpha = 0;
int digit = 0;
int space = 0;

while (ch != '\n') {
    if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
        ++alpha;
    else if (ch >= '0' && ch <= '9')
        ++digit;
    else if (ch == ' ' || ch == '\t')
        ++space;
}

이런식으로 입력받은 문자열에서 숫자, 문자, 공백의 입력 개수를 셀 수 있다.

 

 

cin.getline()은 줄 단위로 입력받는다.

 

char sentense[1000];
cin.getline(sentense, 1000);
cout << sentense;

개행 문자를 입력받거나 지정한 사이즈를 초과하기 전까지 입력 버퍼의 데이터를 가져온다.

cin.get에 비해 훨씬 더 간결해졌다.

만약 세번째 인수로 특정 문자를 넘겨주면 개행 문자가 아닌 해당 문자가 입력 종료의 조건이 된다.

 

 

string : 문자열 압축하기

string compressString(const string& str) {
    const int n = str.length();
    string output;
    
    for (int i = 0; i < n; ++i) {
        int count = 1;
        
        while (i < n-1 && str[i] == str[i+1]) {
            ++count;
            ++i;
        }
        output += str[i];
        output += to_string(count);
    }
    
    if (output.length() > str.length())
        return str;
    return output;
}

문자열 aabbbccc를 a2b3c3으로 압축한다.

count가 1인 경우 count를 추가해주지 않으면 단일 문자만 존재하는 경우의 문제도 처리가 가능하다.

'이론 > 자료구조&알고리즘' 카테고리의 다른 글

Vector Data Structure  (0) 2023.02.08
Pointers & Dynamic Memory  (0) 2023.02.07
2D Arrays  (0) 2023.02.07
Basic Sorting Algorithms  (0) 2023.02.03
Arrays  (0) 2023.02.02

버블 정렬(Bubble Sort)

더보기
void optimizedBubbleSort(int a[], int n){
    for (int i = 0; i < n-1; ++i) {
        for (int j = 0; j < n-1-i; ++j)
            if (n[j] > n[j+1]) swap(n[j], n[j+1]);
    }
}

크거나 작은 수를 배열의 뒤쪽으로 밀면서 정렬한다. 시간 복잡도는 O(N^2)이다.

 

 

삽입 정렬(Insertion Sort)

더보기
void insertionSort(int a[], int n) {
    for (int i = 1; i < n; ++i) {
        int current = a[i];
        int prev = i - 1;
        
        while (0 <= prev && a[prev] > current) {
            a[prev + 1] = a[prev];
            --prev;
        }
        a[prev + 1] = current;
    }
}

배열을 정렬된 값들, 정렬되지 않은 값들의 영역으로 분리하여 앞으로 끌고오며 값을 당겨온다.

시간 복잡도는 O(N^2)이다. 또한 stable sort이다.

 

 

선택 정렬(Selection Sort)

더보기
void selectionSort(int a[], int n) {
    for (int i = 0; i < n-1; ++i) {
        for (int j = i + 1; j < n; ++j)
            if (a[i] > a[j]) swap(a[i], a[j]);
    }
}

버블 정렬과 더불어 가장 기본적인 정렬이고 버블 정렬과 다르게 정렬된 값을 앞에서부터 채워나간다.

시간 복잡도는 O(N^2)이다.

 

 

계수 정렬(Counting Sort)

더보기
void countingSort(int a[], int n) {
    int largest = -1; // 오름차순, 내림차순과 값의 범위에 따라 결정
    
    for (int i = 0; i < n; ++i)
        largest = max(largest, a[i]);
    
    vector<int> freq(largest+1, 0);
    
    for (int i = 0; i < n; ++i) {
        freq[a[i]]++;
    }
        
    int j = 0;
    for (int i = 0; i <= largest; ++i) {
        while (freq[i]-- > 0) {
            a[j] = i;
            ++j;
        }
    }
}

정렬될 값의 범위(Range)가 넓지 않고 범위를 알고 있을 때 유용하게 사용할 수 있다.

범위를 정확히 알지 못하더라도 최대값을 구해서 벡터를 사용하면 된다.

시간 복잡도는 O(Range + N)이다.

'이론 > 자료구조&알고리즘' 카테고리의 다른 글

Vector Data Structure  (0) 2023.02.08
Pointers & Dynamic Memory  (0) 2023.02.07
2D Arrays  (0) 2023.02.07
Character Arrays/Strings  (0) 2023.02.03
Arrays  (0) 2023.02.02

+ Recent posts