[11098] Pointer and Dynamic Array

윤상면·2024년 7월 9일

백준 11098번
문제를 읽어 보니 배열의 사이즈를 cin으로 받고 싶어지는 상황이다..
입력의 사이즈가 정해지지 않은 상황이기 때문에 동적 배열을 선언할 필요가 있다고 생각했다. 예전에 배웠던 포인터와 동적 배열의 개념을 복습하면서, 이 문제를 풀어보기로 하였다.
2021-봄학기 정교민 교수님의 프로그래밍 방법론 수업 자료를 참고하였다.

1. Pointers

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가 각각 메모리 할당과 해제를 도와준다.

2. Dynamic Arrays

고정된 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가 늘어나거나 줄어들 수 있다!

3. Solution

#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();

를 추가해 주면 깔끔해진다.

5635. solution

#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;
    }

0개의 댓글