[11098] Pointer and Dynamic Array

윤상면·2024년 7월 9일
0

백준 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개의 댓글