정의와 성질
배열 : 메모리 상에 원소를 연속하게 배치한 자료구조
- O(1)에 k번째 원소 확인 가능
- 오버헤드 거의 없음
- hit rate 높음 -> CS 확실히 중요하네..
- 연속된 자료구조이기 때문에 할당에 제약이 있다 -> 메모리상에도 연속적
기능과 구현
#include <bits/stdc++.h>
using namespace std;
void insert(int idx, int num, int arr[], int& len){
for(int i=len;i>idx;i--) // i가 길이부터 시작이니까
arr[i]=arr[i-1]; //i-1이 맞는 위치(?) 맞는 배열의 인덱스, 1번째 원소 인덱스 번호는 0
arr[idx]=num; //그리고 넣어준다.
len++; //len도 하나 늘어난다.
}
void erase(int idx, int arr[], int& len){
len--; //길이를 먼저 한 번 지워야
for(int i=idx+1;i<len;i++) //여기서 줄인 idx에 맞는
arr[i-1]=arr[i];
}
void printArr(int arr[], int& len){
for(int i = 0; i < len; i++) cout << arr[i] << ' ';
cout << "\n\n";
}
void insert_test(){
cout << "***** insert_test *****\n";
int arr[10] = {10, 20, 30};
int len = 3;
insert(3, 40, arr, len); // 10 20 30 40
printArr(arr, len);
insert(1, 50, arr, len); // 10 50 20 30 40
printArr(arr, len);
insert(0, 15, arr, len); // 15 10 50 20 30 40
printArr(arr, len);
}
void erase_test(){
cout << "***** erase_test *****\n";
int arr[10] = {10, 50, 40, 30, 70, 20};
int len = 6;
erase(4, arr, len); // 10 50 40 30 20
printArr(arr, len);
erase(1, arr, len); // 10 40 30 20
printArr(arr, len);
erase(3, arr, len); // 10 40 30
printArr(arr, len);
}
int main(void) {
insert_test();
erase_test();
}
STL vector
배열과 거의 동일한 기능을 수행하는 자료구조이다. 배열과 마찬가지로 메모리에 연속적으로 원소를 저장하기 때문에 O(1)의 시간복잡도로 접근 가능하다. 배열은 고정 자료구조인 반면, vector는 동적으로 크기를 조절할 수 있다는 장점이 있다.
#include <bits/stdc.h++>
using namespace std;
int main(void){
vector<int> v1(3,5); // {5,5,5} 크기 3으로 초기화값 5인 벡터 생성
cout<<v1.size()<<'\n';
v1.push_back(7); //꼬리에 7 삽입 push
vector<int> v2(5); //{0,0,0,0,0}
v2.insert(v2.begin()+1,3); //{0,3,0,0,0,0}
vector<int> v3 ={1,2,3,4};
v3.erase(v3.begin()+2); //{1,2,4}
insert, erase는 O(n) push_back, pop_back은 순회가 필요 없으므로 O(1)
vector<int> v1={1,2,3,4,5,6}; //list, map, set 등에서도 모두 사용 가능
for(int e:v1) //int& e:v1이라고 쓰면 for문 내에서 e를 바꿨을 때, 원본 v1도 같이 바뀜
cout<<e<<' ';
for(int i=0;i<v1.size();i++)
cout<<v1[i]<<' ';
for(int i=0;i<=v1.size()-1;i++)
cout<<v1[i]<<' ';
마지막 3번째 예시는 32비트 컴퓨터 기준 런타임에러가 생길 수 있다. vector.size()는 unsigned int 혹은 unsigned long long을 반환한다. 빈 vector일 때 v1.size()-1이 unsigned int 0에서 int 1을 빼는 식이 되고, 이렇게 되면 unsigned int로 자동 형변환이 된다. 때문에 0-1=-1이 아니라 4294967295가 된다(unsigned int의 자료형 범위)
연습 문제
문제 2
#include <bits/stdc++.h>
using namespace std;
int func2(int arr[],int N){
for(int i=0;i<len(arr);i++){
int occur[101]={};
for(int i=0;i<N;i++){
if(occur[100-arr[i]]==1)
return 1;
occur[arr[i]]=1;
}
return 0;
}
}