백준 11098번
문제를 읽어 보니 배열의 사이즈를 cin으로 받고 싶어지는 상황이다..
입력의 사이즈가 정해지지 않은 상황이기 때문에 동적 배열을 선언할 필요가 있다고 생각했다. 예전에 배웠던 포인터와 동적 배열의 개념을 복습하면서, 이 문제를 풀어보기로 하였다.
2021-봄학기 정교민 교수님의 프로그래밍 방법론 수업 자료를 참고하였다.
Pointer definition: Memory address of a variable.
Memory location은 RAM에 수치화 되어 저장되어 있고, Address는 변수의 이름으로 사용된다. 이러한 개념은 이미
Call by Value VS Call by Reference를 배우면서 학습한 바가 있다. 간단하게 짚고 넘어가면..
CBV: 변수의 값을 참조한다(pass the value of a variable).
CBR: 변수의 주소를 참조한다(pass the address of a variable).
전자는 값만을 가져오는 shallow copy와 관련이 있고 후자는 값의 주소를 가져오는 deep copy와 관련이 있다. 값만 가져오는 방법은 actual variable을 변화시킬 수 없지만 주소를 가져오는 방법의 경우 actual variable을 변화시킬 수 있다.
포인터 개념은 Address에 관한 것이기 때문에 Call by Reference을 배운적이 있다면 이미 알고 있는 것이다.
변수명 앞에 "*"를 붙이면 포인터 변수를 선언할 수 있다.
포인터 변수가 아닌 ordinary 변수의 앞에 "&"를 붙이면 변수의 값이 아닌 주소를 가리키게 된다.
"*"는 주소가 가리키는 값을, "&"는 값이 저장된 주소를 나타낸다. 즉 서로가 서로의 inverse function이라고 생각할 수 있다.
int *p1;
int v1;
p1 = &v1;
일반적으로 변수가 선언되면 자동으로 메모리가 할당된다. 그러나 프로그래머가 직접 Heap(memory freespace)에 메모리를 할당시키는 방법이 있는데 이를 Dynamic Memory Allocation이라고 부른다. 자유롭게 메모리를 할당하고 해제할 수 있는 장점이 있으나 제거하지 못하면 memory leak이 발생한다.
c++에서 "new", "delete" operator가 각각 메모리 할당과 해제를 도와준다.
고정된 Size의 Standard array와 다르게 Dynamic Array는 코드를 짤 때 Size가 결정될 필요가 없고 runtime에서 결정된다. cin >> n
으로 배열 사이즈를 받아야 하는 우리는 Dynamic Array를 떠올릴 수 있어야 한다.
그리고 Array Variable은 pointer Variable이다.
아래의 두 변수 모두 pointer variable이다.
int v[10];
int *p;
배열 변수는 첫번째 indexed variable의 주소를 가리킨다. 이는 항상 상수이다. 즉 const int*
에 더 가깝다.
Standard Array가 Size를 먼저 명시해야 했다면 Dynamic Array는 필요에 따라 Size가 늘어나거나 줄어들 수 있다!
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main() {
int n = 0;
cin >> n;
string *answer = new string[n];
for (int i = 0; i < n; ++i) {
int best_price = 0;
string best_athlete;
int size = 0;
cin >> size;
string line;
getline(cin, line);
for (int j = 0; j < size; ++j) {
int price;
string name;
if (getline(cin, line)) {
istringstream iss(line);
iss >> price;
getline(iss >> ws, name);
if (price > best_price) {
best_price = price;
best_athlete = name;
}
}
answer[i] = best_athlete;
}
}
for (int k = 0; k < n; k++) {
cout << answer[k] << endl;
}
return 0; }
+) 5635번 문제
거의 똑같은 문제이다. 그런데 string 라이브러리의 getline
함수를 사용할 때, 첫 번째 getline 함수는 값을 받아오지 않는 것 처럼 보여서 위 solution에서는 단순히 2번 쓰는 것으로 문제를 덮어 뒀는데, 알고보니 cin의 표준 입력 버퍼에 \n
이 남아있어 이를 인식하는 것이라고 한다.
cin.ignore();
를 추가해 주면 깔끔해진다.
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
struct Birthday {
string name;
int day;
int month;
int year;
};
int main() {
int size = 0;
cin >> size;
string line;
Birthday *answer = new Birthday[size];
cin.ignore();
for (int i = 0; i < size; i++) {
if(getline(cin, line)){
istringstream iss(line);
Birthday birthday;
iss >> birthday.name >> birthday.day >> birthday.month >> birthday.year;
answer[i] = birthday;
}
}
int least_idx = 0;
int great_idx = 0;
for (int i = 0; i < size; i++){
if (answer[i].year < answer[least_idx].year) {
least_idx = i;
} else if (answer[i].year == answer[least_idx].year &&
answer[i].month < answer[least_idx].month) {
least_idx = i;
} else if (answer[i].year == answer[least_idx].year &&
answer[i].month == answer[least_idx].month &&
answer[i].day < answer[least_idx].day)
least_idx = i;
if (answer[i].year > answer[great_idx].year) {
great_idx = i;
} else if (answer[i].year == answer[great_idx].year &&
answer[i].month > answer[great_idx].month) {
great_idx = i;
} else if (answer[i].year == answer[great_idx].year &&
answer[i].month == answer[great_idx].month &&
answer[i].day > answer[great_idx].day)
great_idx = i;
}
cout << answer[great_idx].name << endl << answer[least_idx].name << endl;
return 0;
}