Posts [알고리즘 트레이닝] 2장 - 프로그래밍 기법 : 언어적 특성
Post
Cancel

[알고리즘 트레이닝] 2장 - 프로그래밍 기법 : 언어적 특성


https://chanhuiseok.github.io/posts/algo-38/

위의 포스트에서 알고리즘 해결 시 부족한 점을 채우기 위해 샀던 책을 소개한 적이 있습니다.

그 책을 공부하면서 정리한 내용들을 앞으로 이 카테고리에 연재하고자 합니다.

C++을 공부하시는 많은 분들이 도움이 되었으면 좋겠습니다!


2-1-1. 입력과 출력


(1) cin, cout의 효율성 높이기

  • cin, cout (입력과 출력) 은 프로그램의 병목이 될 때가 있습니다. (scanf, print에 비해) 코드 시작 부분에 다음과 같은 코드를 추가 시 입출력을 좀 더 효율적으로 할 수 있습니다.
1
2
ios::sync_with_stdio(0);
cin.tie(0);
  • 한 번 C++ 입출력 함수인 cin, cout을 사용했다면, C 언어 입출력 함수인 scanf나 printf는 같은 코드 내에서 사용할 수 없습니다.
  • 그 반대도 마찬가지입니다.

(2) 개행문자 “\n”이 endl보다 빠르다

  • 개행 문자 “\n”이 endl 보다 빠릅니다. 그 이유는 endl을 사용 시 명시적으로 flush(출력 버퍼 비우기)가 일어나기 때문입니다.

(3) C++에서 공백을 포함한 입력 한 줄을 통째로 읽으려면?

1
2
string s;
getline(cin, s);

(4) C++에서 파일 입출력을 해야 할 경우 편리한 방법

  • C에서는 fscanf, fprintf 등 입출력 함수에도 파일 입출력을 위한 것이 존재했습니다.
  • 하지만 c++에서는 평소처럼 표준 스트림을 사용하는 코드 그대로 사용하되, 코드 맨 위에 freopen 만 추가해 주면 되서 더 편리합니다.
1
2
3
4
5
6
7
8
9
...
int main(){
	freopen("input.txt","r",stdin); // 파일에서 입력받아야 할 때
    freopen("output.txt","r",stdout); // 파일로 출력해야 할 때
	...
	
	cin << s;
	cout >> s; // cin, cout 등 그대로 자유롭게 사용. 파일로 입/출력이 이루어진다.
}

2-1-2. 숫자 처리하기


(1) 정수 : int와 long long의 범위 비교


int-2^31 ~ 2^31-1 (대략 -2 x 10^9 ~ 2 x 10^9, 즉 20억 정도)
long long-2^63 ~ 2^63-1 (대략 -9 x 10^18 ~ 9 x 10^18)
  • 자주 사용되는 정수 자료형은 int이지만, 알고리즘 문제에 따라 매우 큰 정수를 받아야 할 때도 있습니다.
  • 그럴 때는 int 형의 범위와는 비교도 되지 않을 정도로 큰 long long을 사용하면 됩니다.

  • 각 자료형이 얼만큼의 크기를 가지는지 대략 알아두는 것도 큰 도움이 될 것 같습니다.

(2) 부동 소수점 실수


  • 가장 유용한 실수 자료형은 double 이고, 더 정밀도가 높은 것은 long double 입니다. 각각 64bit, 80bit 자료형 입니다.

  • 답을 소수점 아래 몇자리까지 출력해야 한다면 다음과 같이 사용합니다.

1
printf("%.9f",x); // 소수점 아래 9자리까지 출력
  • 실수 비교를 == 연산자를 이용하여 비교하면 때로는 위험한 측면이 있습니다. 비교하는 값이 실제로는 일치하더라도, 정밀도 오류로 다르다는 결과를 낼 수 있기 때문입니다.
  • 그래서 좀 더 나은 방법으로 다음과 같이 비교할 수 있습니다.
  • 1e-9 표현은 10^-9 로, 두 값의 차이가 아주 작은 수치보다도 더 작으면 같다고 보는 것입니다.
1
2
3
if (abs(a-b) < 1e-9 ){
	// a와 b가 일치
}
  • 하지만 double은 부정확하긴 하더라도, 절댓값이 2^53 이하인 모든 정수는 정확히 표현 가능하므로 위의 정보들은 저런 비교법도 있구나 하고 참고로 알아두시면 될 것 같습니다.

2-1-3. 코드 짧게 만들기


(1) typedef 로 간단하게 표현하기


  • typedef 명령어로, 자료형의 이름을 짧게 만들 수 있습니다.
1
2
3
typedef long long ll;
...
//이후 long long 대신 ll 로 표현 가능!
  • 복잡한 형태의 자료형, 예를 들면 int형 vector나, pair 등에 이름을 붙입니다.
1
2
3
typedef vector<int> vi;
typedef pair<int, int> pi;
// 알고리즘에서 많이 쓰이는 자료형들의 별칭을 지어준다면, 훨씬 깔끔한 코드가 될 것 같습니다.

(2) 매크로 사용하기 - #define 키워드


매크로는 코드 컴파일 전, 코드에 포함된 특정한 문자열을 다른 문자열로 치환하는 규칙을 말합니다.

1
2
3
4
5
6
7
8
9
10
11
12
#define F first
#define S second
#define PB push_back
#define MP make_pair
...
// 이후, 벡터에 푸쉬하거나 pair를 만들 때, 접근 할 때 다음과 같이 가능
    
// v.push_back(make_pair(y, x));
v.PB(MP(y,x));

// int d = v[i].first+v[i].second;
int d = v[i].F + v[i].S;

[백준] 11559번 - Puyo Puyo

[알고리즘 트레이닝] 2장 - 프로그래밍 기법 : 재귀적 알고리즘