※ 이번 문제에서 알게된 점

§  재귀함수로 구현하는 gcd, lcm 함수

// 최대공약수
auto gcd(long long A, long long B){
    if (B == 0)
        return A;
    else
        return gcd(B, A%B);
}

 

// 최소공배수
auto lcm (long long A, long long B){
    return A*B/gcd(A,B);
}

 

 

 

 

§ my solution

#include <iostream>
#include <algorithm>
using namespace std;

// 최대공약수
auto gcd(long long A, long long B){
    if (B == 0)
        return A;
    else
        return gcd(B, A%B);
}

// 최소공배수
auto lcm (long long A, long long B){
    return A*B/gcd(A,B);
}

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);

    long long A, B;   cin >> A >> B;
    cout << lcm(A,B);
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

백만자리라는 문제를 안읽고 풀어서 틀렸다. lon long을 써줘야 함.

 

 

 

 

 

 

 

 

 

§ my solution

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

auto gcd(long long a, long long b){
    if (b == 0)
        return a;
    else
        return gcd(b, a%b);
}

auto lcm(long long a, long long b){
    return a*b / gcd(a, b);
}

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);

    int num;    cin >> num;
    vector<long long> v1;
    vector<long long> v2;

    for (int i = 0; i < num; i++) {
        int a, b;   cin >> a >> b;
        v1.push_back((a));
        v2.push_back((b));
    }

    for (int i = 0; i < num; i++) {
        cout << lcm(v1.at(i), v2.at(i)) << '\n';
    }
}


※ Bayesian Classifier (2-class-Classification)

Ex. 연어와 배스에 대해 구별하는 문제상황에 대해 생각해보자.

- 옵션1: 사람의 경험에 의해 어느 바다에서 어떤 물고기가 더 잘 잡히는지에 대한 연평균 데이터
- 옵션2: 자동적인 system [전처리-특징추출-classification]


class
X1 (Lightness) X2 (Width) Y (target)
Fish 1
Fish 2
.
.
.
Fish n
.
.



.
.
.



.
Sea Bass
Salmon



Salmon


위의 class에 대해 우리는 분류를 해야하며 이때, Bayesian Classifier를 사용할 수 있는데,
다른 model들과 Bayesian이 가장 확연히 다른 점이 하나 있다. 아래 수식을 살펴보자.
먼저 Bayesian의 공식은 조건부확률로 이루어져 있다.

Bayes' Formula


여기서 가장 중요한 것은 Prior이다.

다른 머신러닝 모델들과 확연히 다른 Bayesian 만이 갖는 특징으로 사용자 주관이 개입될 수 있다는 점이다.


예를 들어 어떤 바다에서 물고기를 잡았을 때, 70%정도가 salmon이라 판별된다면,
이런 자연적인 분포비율을 model에 집어넣을 수 있다는 뜻이다.
예를 들어, 모델이 fish5에 대해 salmon일 확률을 0.3이라 예측했다면, 70%의 주관의 개입으로 모델의 분류효과를 달리할 수 있다는 점이다.

Likelihood만으로 측정한 결과값이 왼쪽이라면, 이 값에&amp;nbsp; prior를 추가해 오른쪽과 같은 값을 만들 수 있으며 좀 더 세밀한 분류도 가능해진다.







※ Generative vs Discriminative // Parametric vs Non-parametric

§ Generative vs Discriminative

Generative
- modeling의 결과로부터 data를 만들 수 있다.
- Output: 확률 분포 (Probability distribution)

Discriminative
- data를 모아 판별함수를 찾을뿐, 생성하지는 못하는 함수 (Just looking for a discriminant function)

§ Parametric vs Non-parametric

Parametric
- 미리 지정된 모델의 파라미터를 최적화함 (optimize pre-defined parameters in a model)

Non-parametric
- 모델에 파라미터자체가 없음 (no parameters in a model)







※ Parameter Estimation_ Discriminant Function for Decision Boundary

§ Decision Boundary


단항함수와 다항함수 Gaussian (Univariate and multivariate Gaussian)
- 단항함수 Gaussian (Univariate Gaussian)

뮤와 시그마 만 알면 값을 구할 수 있음

- 다항함수 Gaussian (Multivariate Gaussian)

d/2, 시그마, 뮤만 알면 값을 구할 수 있음




※ Maximum Likelihood Estimation

빨간색 점이 data를 뜻함

위 그래프에서 data 밀집이 평균과 가까워질수록 값이 커진다.
최댓값은 미분했을 때, 0일 때! (접선의 기울기 = 0)

§ 뮤(평균) 추정값








※ Naive Bayesian classifier

위와 같이 고차원 공간의 세타값 추정 방법

이 방법은 너무 복잡하고 시간소비가 심하다.


§ Naive Bayesian classifier => 매우 강한 추정방식 (모든 특징 변수들이 독립적이어서)

장점: 모든 변수가 다 독립이며 매우 string한 assumption이 가능하다.
따라서 각 클래스 별로 변수끼리 따로따로 계산해서 추정한다.

아래를 보면 Bayesian과 Naive간의 차이점을 볼 수 있다.





다중변수 추정을 나이브하게 만들어 단변수 추정으로 만들 수 있다.
(Multivariate distribution estimation => Univariate distribution estimation)





- 수학적 연산 및 다차원 배열연산을 가능하게 해주는 라이브러리

.where() – 조건에 맞는 데이터의 위치(index)를 알려줌

.array()  || .ndarray() – 배열을 생성하는 함수 (append 됨)

.shape - 데이터의 전체적인 차원을 볼 수 있게 해줌

.transpose() – 데이터를 전치시킴

.reshape() – 데이터의 차원을 다시 조정할 수 있음

.concatenate() – 데이터를 붙일 수 있음

 

 

 

 

 

 

 

 

 

 

 

- 데이터 분석에 사용되는 tool,  정형데이터 처리의 대표적인 tool

.loc(), iloc() –위치에 맞는 데이터의 부분만을 보여줌, 데이터 전처리과정에서 많이 활용

.head(), .tail() – 데이터의 맨 앞, 맨 뒤의 부분만을 잘라서 보여줌

.describe(), .info() – 데이터의 전체적인 정보를 보여줌

.drop() – 원하는 row나 column의 데이터를 삭제함

.concat() - 데이터를 붙일 수 있음

.read_csv() – 경로에 있는 .csv 파일을 읽어옴

.to_csv() – 데이터를 원하는 파일 경로에 .csv 파일로 저장함

 

 

 

특히나 iloc은 정말 많이 사용되니 사용법을 작 익혀놔야 한다.

 

 

 

 

 

 

 

 

 

 

 

 

 

scikit learn에 저장된 preprocessing의 LabelEncoder로도 가능함.

 

 

 

 

 

 

 

 

 

 

 

 

 

※ 설치방법[command 창]

$ pip3 install numpy pandas tqdm sklearn matplotlib

!pip3 install numpy pandas tqdm sklearn matplotlib

 

 

 

 

 

※<cstdlib>

 abort() : 프로그램을 "비정상적으로 종료"

 exit(n) : 값을 n으로 프로그램을 종료 (n==0이면 성공적인 종료)

 d=rand() : d는 [0 : RAND_MAX] 범위에 있는 의사 난수다.

 

 

 

※<cmath>

 

§ x의 y승을 구하려면 원래는 다음과 같이 구현해야한다.

#include <iostream>
using namespace std;

int main(){
    int x, y;   cin >> x >> y;
    int result = 1;
    for (int i = 0; i < y; i++) 
        result *= x;
    cout << result;
}

 

§ 하지만 <cmath>의 내장함수인 exp2나 pow함수를 이용하면 매우 짧은 코드로 답을 낼 수 있어 유용하다.

#include <iostream>
#include <cmath>
using namespace std;

int main(){
    int x, y;   cin >> x >> y;
    cout << pow(x,y);
}

 

#include <iostream>
#include <cmath>
using namespace std;

int main(){  // x값 2 한정
    int y;   cin >> y;
    cout << exp2(y);
}

 

 

※ 이번 문제에서 알게된 점

§  sort(v.begin(), v.end(), custom_func) 함수

 

1. 먼저 vector에 include 되어 있는 pair를 선언해 입력을 받으면 다음과 같다.

vector< pair<int, int> > p;

for (int i = 0; i < num; i++) {
    int n1, n2; cin >> n1 >> n2;
    p.push_back(make_pair(n1, n2));
}

 

 

2. 그 후 sort를 해줘야 하는데, 이때 문제는 sort를 해주면 p.first를 기준으로 정렬 된다는 것.

그래서 사용자가 만든 함수로 sort(v.begin(), v.end(), custom_func) 의 custom_func에 넣어서

p.second 기준으로 정렬되도록 해야한다. 이때, custom_func의 결과값은 0, 1이 나와야 하며 보통 bool type이다.

bool compare(pair<int, int> a, pair<int, int> b) {
    if (a.second == b.second)
        return a.first < b.first;  // a.first가 작으면 true. 즉 작은게 앞에 배치가 된다.
    return a.second < b.second;       // a.second가 더 작으면 true. 즉 작은게 앞에 배치가 된다.
}
sort(p.begin(), p.end(), compare);

 

\

 

 

 

 

 

 

 

§ my solution 

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

bool compare(pair<int, int> a, pair<int, int> b) {
    if (a.second == b.second)
        return a.first < b.first;  // a.first가 작으면 true. 즉 작은게 앞에 배치가 된다.
    return a.second < b.second;       // a.second가 더 작으면 true. 즉 작은게 앞에 배치가 된다.
}

int main() {
    ios_base::sync_with_stdio(0);
    int num; cin >> num;

    vector< pair<int, int> > p;

    for (int i = 0; i < num; i++) {
        int n1, n2; cin >> n1 >> n2;
        p.push_back(make_pair(n1, n2));
    }
    sort(p.begin(), p.end(), compare);

    for (auto x:p) {
        cout << x.first << " " << x.second << '\n';
    }
}

 

 

 

 

 

 

§ my solution 

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    ios_base::sync_with_stdio(0);
    int N, A;   cin >> N >> A;
    vector<int> v;
    for (int i = 0; i < N; i++) {
        int num;    cin >> num;
        v.push_back(num);
    }
    sort(v.begin(), v.end());
    cout << v[A-1];
}

 

 

 

 

 

 

 

 

 

§ my solution 

- endl 대신 '\n'을 애용하자!

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int N;  cin >> N;
    vector<int> v;
    for (int i = 0; i < N; i++) {
        int num;    cin >> num;
        v.push_back(num);
    }
    sort(v.begin(), v.end());
    for(auto x:v)
        cout << x << '\n';
}

 

 

 

 

 

§ my solution 

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);

    int N; cin >> N;
    vector<int> v;
    for (int i = 0; i < N; i++) {
        int num;    cin >> num;
        v.push_back(num);
    }
    sort(v.begin(), v.end(), greater<int>());
    for(auto x:v)
        cout << x << '\n';
}

 

 

 

 

 

※ 이번 문제에서 알게된 점

§  unique() 함수

https://chan4im.tistory.com/51

 

this.algorithm(2). 중복된 원소제거, unique()

 

chan4im.tistory.com

 

 

 

 

 

 

 

§ my solution 

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    ios_base::sync_with_stdio(0);

    int N;  cin >> N;
    vector<int> v;
    for(int i = 0; i < N; i++){
        int num;    cin >> num;
        v.push_back(num);
    }

    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());

    for(auto x:v)
        cout << x << " ";
}

※ unique 함수

- 벡터에서 중복원소를 제거할 때, sort, erase, unique 기능을 적절히 활용하여 제거할 수 있기에

 unique 함수의 사용은 익혀야 할 필요성이 두드러진다 생각한다. 

- 또한 int가 아닌 char형도 가능하다는 점에서 대단히 유용하다.

 

cf. 만약, sort하지말고 중복원소를 제거하라면 set + assign함수를 사용한다.

(set은 중복 원소를 허용하지 않는 컨테이너기 때문이다.)

https://scarlettb.tistory.com/70

[백준 13915번: https://www.acmicpc.net/problem/13915]

 

13915번: 현수의 열기구 교실

현수는 열기구 여름특강의 강사다. 현수는 매우 성실해서 모든 수강생들의 열기구 비행을 기록하고있다. 매 비행 이후, 현수는 그 비행에 참석한 수강생들의 기록을 리스트에 추가한다. 리스트

www.acmicpc.net

 

 

§ unique의 원리

- "정렬된" 원소에 대해 vector의 제일 뒷부분으로 쓰레기값으로 보내버린다.

- 따라서 "정렬"되어야 하므로 sort를 사용해야한다.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    int N;  cin >> N;
    vector<int> v;
    for(int i = 0; i < N; i++){
        int num;    cin >> num;
        v.push_back(num);
    }

    sort(v.begin(), v.end());

    unique(v.begin(), v.end());

    for(auto x:v)
        cout << x << " ";
}

 

input >>  1 4 3 2 2 3 1 5 3 5 4
output << 1 2 3 4 5 3 3 4 5 5

앞에 1 2 3 4 5가 정렬된 이후 뒤 숫자는 아무렇게나 쓰레기값이 들어간 것을 알 수 있다.

 

 

 

 

§  중복원소제거 정렬

따라서 정렬 후 erase와 unique로 삭제할 수 있다.

다음과 같이 작성하면 된다.

sort(v.begin(), v.end());
v.erase( unique(v.begin(), v.end()), v.end() );

 

 

 

 

 

 

 

 

 

 

※ 중복된 원소 제거 => sort, erase(unique())

 

[백준 10867번: https://www.acmicpc.net/problem/10867]

 

10867번: 중복 빼고 정렬하기

첫째 줄에 수의 개수 N (1 ≤ N ≤ 100,000)이 주어진다. 둘째에는 숫자가 주어진다. 이 수는 절댓값이 1,000보다 작거나 같은 정수이다.

www.acmicpc.net

 

[숫자벡터에 대한 중복 원소 제거]

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    int N;  cin >> N;
    vector<int> v;
    for(int i = 0; i < N; i++){
        int num;    cin >> num;
        v.push_back(num);
    }

    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());

    for(auto x:v)
        cout << x << " ";
}

 

 

 

[문자벡터에 대한 중복 원소 제거]

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<char> s;
    for (int i = 0; i < 10; i++) {
        char c;     cin >> c;
        s.push_back(c);
    }
    sort(s.begin(), s.end());
    s.erase(unique(s.begin(), s.end()), s.end());

    for(auto x:s)
        cout << x << " ";
}

 

※ ios_base::sync_with_stdio(bool sync);

bool sync == false: C 의 stdio.h와 C++의 iostream의 동기화를 끊는다.

bool sync == true: 함수 호출하기 전 이전의 동기화 상태

 

[sync : true]

- 모든 stream들은 동기화가 되어있으며 동기화된 stream들이 자신의 buffer대신 C stream buffer를 사용

stream buffer: data를 보내거나 받기 전, 임시로 저장되는 곳으로

바로 사용하지 않고 버퍼에서 보관, 어느정도 모이면 출력하는 방식으로 작업함.

 

- 동기화된 C++ stream들은 thread-safe, 안정성을 보장한다.

- 따라서 입출력 순서가 정해져있어서 race condition이 발생하지 않는다. (race condition: https://chan4im.tistory.com/36)

 

this->OS.code(5)

다수의 thread가 concurrent하게 실행 => thread 충돌문제 발생이 가능하다. cf. single thread의 경우, process 충돌이라고도 부른다. - race condition: 2개 이상의 process가 같은 메모리를 거의 동시에 접근(access)할

chan4im.tistory.com

 

[sync : false]

- 동기화를 끊게되면 C++ stream은 자신들의 독립적인 buffer를 갖게된다.

- 따라서 입출력 객체를 섞어 사용하면 출력순서를 보장할 수 없어 오답, race condition 발생 가능성이 있다.

- multi-thread의 경우, Thread-unsafe해져서 예상하지 못한 값이 나올 수도 있다.

 

※ 입출력 속도비교

[scanf, printf, \n]  >>>>>>>> [cin, cout, endl]

 

 

 

 

§  ios_base::sync_with_stdio() 함수

먼저 C++의 <iostream>은 C의 <stdio.h>와 다르다. 

C++의 입출력 작업 시, C의 입출력과 동기화 되도록 설계되어 상당히 느린 입출력과정을 겪는다.

추가적으로 endl도 출력문자 출력+출력buffer를 함께 비워 시간이 많이 걸려 \n사용을 권장한다.

이때 말하는 "동기화"를 뜻하는 코드가 ios_base::sync_with_stdio이고, 이 동기화를 풀어주는 코드이다.

따라서 동기화가 풀어진다면?  => 당연히 속도를 올릴 수 있다!

ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);

 

큰 힘에는 큰 책임이 따른다고, 이런 ios_base::sync_with_stdio에도 치명적인 단점이 있다.

 

1. 그건 바로 싱글 쓰레드 (single thread) 환경은 괜찮지만, 멀티 쓰레드 (Multi Thread)환경에서는 출력순서가 어그러진다.

즉, 멀티쓰레드 환경에서의 출력순서가 보장될 수 없다는 것이다! (race condition 발생 가능)

cf-1) 코딩테스트에서는 싱글쓰레드만 사용하기에 사용해도 무방하다.

cf-2) 다만 실무에서는 ios_base::sync_with_stdio를 쓰기보단, 속도를 올리기 위해 C입출력 방식을 권장한다.

 

 

2. 버퍼가 분리되었기에 cin과 scanf, gets, getchar 등의 C문법 (당연히 출력코드도 동일)을 같이 사용할 수 없다!

 

cf-2) 싱글, 멀티쓰레드란? https://chan4im.tistory.com/35

 

this->OS.code(4)

exit() system call, 처리불가능한 signal, CPU err, 부모 process의 명령과 같은 상황에서 process termination이 발생하며 아직 process 상태에 존재한다. (process에 존재하지만 실행에 필요한 컴퓨터 자원들을 proces

chan4im.tistory.com

 

 

 

§  cin.tie(NULL)  /  cout.tie(NULL) 함수

[정의]: istream, ostream 즉, stream을 untie 하여 자동으로 입출력 버퍼를 비우지 않게 함

cin과 cout간의 tie를 끊어주는, 즉 다른 입출력이 온다면 기존의 입출력을 비워주도록 하는 것이다.

이 tie를 끊어줌으로써 시간을 많이 절감할 수 있다. (cin을 cout으로부터 풀어줌.)

기본적으로 cout의 출력은 buffer가 가득차거나 수동적으로 flush되기 전까진 출력되지 않는다.

 

[flush]: 현재 buffer에 저장되있는 내용클라이언트로 전송buffer를 비우는 것을 말함.

 

- stream을 tie하면 다른 stream에서 입출력 요청이 오기 전stream을 먼저 flush 시킨다.

 

- stream을 untie하면 output이 flush되지 않은 채로 user에게 input을 요구한다.

- untie를 해주었다면, cin으로 입력받기 전, 출력하고 싶다면 수동적으로 cout을 flush 해줘야 한다.

 

[예시]

왼쪽그림에서 ios_base::sync_with_stdio(0);을 지워도 console창은 하게 뜬다.

왼쪽을 보면 cout으로 "입력"이란 문구가 출력된 후 cin이 나오는 것을 알 수 있고, 이는 익숙한 방식이다.

하지만 우측은 입력 후 출력이 모두 동시에 되는 것을 알 수 있다.

우리가 tie를 끊어서 입력 전에 출력관련 문구가 아무리 입력보다 먼저 적혀있었더라도 출력이 되지 않는다.

만약 입력전에 출력되게 하고 싶다면 cout의  buffer를 수동으로 비워줘야 한다.

 

이번 문제는 문제 난이도 자체는 평이, 아니 쉬운 수준이었다.

그냥 배열을 합치고 algorithm 헤더의 sort만 해주면 끝나는 문제였다.

문제는 다름이 아니라 시간초과 발생 때문에 대략 2시간을 잡아먹은 것이다.

코드의 길이를 정말 최대로 줄일 수 있을만큼 줄이고 vector도 사용해보고 배열도 사용해 보았다.

하지만 그렇게 짜본 코드가 모두 시간초과가 떠버렸다.

 

결과적으로 위에 내가 짰던 코드가 틀린 것은 아니지만,

키워드 3줄만 적어주었더니 시간초과가 뜨지 않았다.

 

 

 

 

※ 이번 문제에서 알게된 점

§  ios_base::sync_with_stdio() 함수

먼저 C++의 <iostream>은 C의 <stdio.h>와 다르다. 

C++의 입출력 작업 시, C의 입출력과 동기화 되도록 설계되어 상당히 느린 입출력과정을 겪는다.

추가적으로 endl도 출력문자 출력+출력buffer를 함께 비워 시간이 많이 걸려 \n사용을 권장한다.

이때 말하는 "동기화"를 뜻하는 코드가 ios_base::sync_with_stdio이고, 이 동기화를 풀어주는 코드이다.

따라서 동기화가 풀어진다면?  => 당연히 속도를 올릴 수 있다!

ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);

 

큰 힘에는 큰 책임이 따른다고, 이런 ios_base::sync_with_stdio에도 치명적인 단점이 있다.

 

1. 그건 바로 싱글 쓰레드 (single thread) 환경은 괜찮지만, 멀티 쓰레드 (Multi Thread)환경에서는 출력순서가 어그러진다.

즉, 멀티쓰레드 환경에서의 출력순서가 보장될 수 없다는 것이다!

cf-1) 코딩테스트에서는 싱글쓰레드만 사용하기에 사용해도 무방하다.

cf-2) 다만 실무에서는 ios_base::sync_with_stdio를 쓰기보단, 속도를 올리기 위해 C입출력 방식을 권장한다.

 

 

2. 버퍼가 분리되었기에 cin과 scanf, gets, getchar 등의 C문법 (당연히 출력코드도 동일)을 같이 사용할 수 없다!

 

cf-2) 싱글, 멀티쓰레드란? https://chan4im.tistory.com/35

 

this->OS.code(4)

exit() system call, 처리불가능한 signal, CPU err, 부모 process의 명령과 같은 상황에서 process termination이 발생하며 아직 process 상태에 존재한다. (process에 존재하지만 실행에 필요한 컴퓨터 자원들을 proces

chan4im.tistory.com

 

 

 

§  cin.tie(NULL)  /  cout.tie(NULL) 함수

[정의]: istream, ostream 즉, stream을 untie 하여 자동으로 입출력 버퍼를 비우지 않게 함

cin과 cout간의 tie를 끊어주는, 즉 다른 입출력이 온다면 기존의 입출력을 비워주도록 하는 것이다.

이 tie를 끊어줌으로써 시간을 많이 절감할 수 있다.

 

[예시]

왼쪽그림에서 ios_base::sync_with_stdio(0);을 지워도 console창은 하게 뜬다.

왼쪽을 보면 cout으로 "입력"이란 문구가 출력된 후 cin이 나오는 것을 알 수 있고, 이는 익숙한 방식이다.

하지만 우측은 입력 후 출력이 모두 동시에 되는 것을 알 수 있다.

우리가 tie를 끊어서 입력 전에 출력관련 문구가 아무리 입력보다 먼저 적혀있었더라도 출력이 되지 않는다.

만약 입력전에 출력되게 하고 싶다면 cout buffer를 수동적으로 비워줘야 한다.

 

https://hegosumluxmundij.tistory.com/54

 

 

 

 

 

 

 

§ reserve() 와 resize() 의 차이

가장 고생했던 부분이 있는데 다음과 같다.

https://hoondev.tistory.com/7

§ reserve() 와 resize() 의 차이

capacity: 미리 할당해놓은 배열공간

size: 배열에 들어있는 원소의 수

 

대부분의 컨테이너 STL 자료구조들은 일정 크기를 할당(capacity)한 후 

size가 capacity를 넘으면 2배정도의 크기를 늘려 이동하는 방식으로 구현되어 있다.

 

§ reserve(N)

- vector의 capacity를 N으로 설정하는 것.

- N이 현재 capacity보다 클 때만 작동, 작으면 아무 일도 발생X

- N이 현재 capacity보다 크다면 모든 원소 reference와 iterator가 전부 무효화(invalidate)된다.

 

§ resize(N)   /   resize(N, value)

- size > N인 경우, 원소의 개수를 줄인다.

- size < N인 경우, 입력된 value가 없으면 default값인 0으로 할당한다. 있다면 value로 할당.

  그 후, size가 N이 되도록 늘린다.

 

 

 

 

 

 

§ my solution 

총 3가지 방식으로 해결하였다.

1. 배열과 배열의 포인터(주소값)로 sort 후 해결 (메모리 9708KB  /  시간 636ms)

#include <iostream>
#include <algorithm>
using namespace std;

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int N, M;   cin >> N >> M;
    int arr[N+M];

    for (int i = 0; i < N+M; i++) {
        cin >> arr[i];
    }
    sort(arr, arr+N+M);

    for (const auto& x:arr) {
        cout << x << " ";
    }
}

 

2. 배열을 벡터로만 바꿈 (메모리 9836KB  /  시간 688ms)

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int N, M;   cin >> N >> M;
    vector<int> v(N+M);
    for (int i = 0; i < N+M; i++)
        cin >> v[i];

    sort(v.begin(), v.end());

    for (int i = 0; i < N+M; i++) {
        cout << v[i] << " ";
    }
}

 

3. 정말 벡터 2개를 생성, 합친 후 정렬! (메모리 17656KB  /  시간 644ms)

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int N, M;   cin >> N >> M;
    vector<int> v1(N);
    vector<int> v2(M);

    for (int i = 0; i < v1.size(); i++){
        cin >> v1[i];
    }
    for (int i = 0; i < v2.size(); i++){
        cin >> v2[i];
    }

    vector<int> v3;

    v3.reserve(v1.size() + v2.size());
    v3.insert(v3.end(), v1.begin(), v1.end());
    v3.insert(v3.end(), v2.begin(), v2.end());

    sort(v3.begin(), v3.end());

    for (const auto& x:v3) {
        cout << x << " ";
    }
}

 

4. 2개의 vector를 merge와 sort를 이용해 정렬(메모리 24684KB  /  시간 544ms)

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0); 
    cout.tie(0);

    vector<int> v1;
    vector<int> v2;

    int N, M;   cin >> N >> M;

    for (int i = 0; i < N; i++) {
        int num;    cin >> num;
        v1.push_back(num);
    }
    for (int i = 0; i < M; i++) {
        int num;    cin >> num;
        v2.push_back(num);
    }
    vector<int> v3;

    merge(v1.begin(), v1.end(), v2.begin(), v2.end(), back_inserter(v3));

    sort(v3.begin(), v3.end());

    for (const auto& x:v3) {
        cout << x << " ";
    }
}

+ Recent posts