Algorithm/PS 알고리즘 정리

코딩테스트 효과적인 C++ 코드 작성 팁

샤아이인 2022. 1. 19.

해당 본문의 원문의 출처는 Geeks for Geeks 입니다. 이과생이 공부겸 번역한 딱딱한 어투의 글 입니다. 문제가 될시 삭제하겠습니다.

가끔 해외 유튜버들이 compatitive한 대회에서 C++코드를 작성할때 macro를 사용해서 반복문 사용을 효과적으로 하거나, auto를 사용하는 방식등... 알면 좋을수 있는 코딩 tip들이 궁금하여 찾아보았다. 역시 Geeks for Geeks는 진리다!

 

1. Using Range based for loop

이 방식은 C++11에서 매우 멋진 방식이며, 만약 너가 처음부터 끝까지 반복문을 돌고싶다면 효과적인 방법이 될 것 이다.

다음 코드는 어떤 방식으로 array나 vector에서 반복을 돌기위해 loop의 범위를 사용하는지 보여준다.

// C++ program to demonstrate range based for
// loops for accessing vector and array elements
#include<iostream>
#include <vector>
using namespace std;

int main()
{
	// 원소가 5개인 vector를 만든다.
	vector<int> vec = {0, 1, 2, 3, 4};

	// 타입은 auto를 사용한 참조형이다.
	// 범위기반의 loop는 값을 수정할 필요가 없는경우에 선호됩니다. 따라서 const 사용
	for (const auto &value : vec)
		cout << value << ' ';

	cout << '\n';

	// 정수 배열에서의 원소 5개
	int array[]= {1, 2, 3, 4, 5};
	for (const auto &value: array)
		cout << value << " ";

	return 0;
}
 

결과값은 다음과 같다.

 

2. Initializer List

this type은 C++의 초기화 리스트를 통해 해당 객체의 값에 접근할 때 사용됩니다.

여기서 this type의 객체는 컴파일러에 의해 초기화리스트에 의해서 자동적으로 초기화 됩니다. 참고로 { } 물결괄호 안이 초기화 리스트 입니다.

#include<iostream>

template<typename T>
void printList(std::initializer_list<T> text)
{
	for (const auto & value: text)
		std::cout << value << " ";
}

// Driver program
int main()
{
	// Initialization list
	printList( {"One", "Two", "Three"} );
	return 0;
}
 

결과값은 다음과 같다.

One Two Three
 

 

3. Assigning Maximum or Minimum value

이 방식은 추가적인 max() 나 min() 함수를 사용해야하는 번거로움으로부터 피할수있게 해준다.

#include<iostream>

// x는 참조형 변수
template<typename T, typename U>
static inline void amin(T &x, U y)
{
	if (y < x)
		x = y;
}

// x는 참조형 변수
template<typename T, typename U>
static inline void amax(T &x, U y)
{
	if (x < y)
		x = y;
}

// Driver program to find the Maximum and Minimum value
int main()
{
	int max_val = 0, min_val = 1e5;
	int array[]= {4, -5, 6, -9, 2, 11};

	for (auto const &val: array)

		// Same as max_val = max (max_val, val)
		// Same as min_val = min (min_val,val)
		amax(max_val, val), amin (min_val, val);


	std::cout << "Max value = " << max_val << "\n"
			<< "Min value = " << min_val;
	return 0;
}
 

결과는 다음과 같다.

Max value = 11
Min value = -9
 

 

4. Fast Input/Output in C/C++

경쟁적인 프로그래밍 대회에서의 경우 input과 output을 가능한 빠르게 읽어들여 시간을 절약해야 한다.

#include <bits/stdc++.h>

template<typename T> void scan(T &x)
{
	x = 0;
	bool neg = 0;
	register T c = getchar();

	if (c == '-')
		neg = 1, c = getchar();

	while ((c < 48) || (c > 57))
		c = getchar();

	for ( ; c < 48||c > 57 ; c = getchar());

	for ( ; c > 47 && c < 58; c = getchar() )
		x= (x << 3) + ( x << 1 ) + ( c & 15 );

	if (neg) x *= -1;
}

template<typename T> void print(T n)
{
	bool neg = 0;

	if (n < 0)
		n *= -1, neg = 1;

	char snum[65];
	int i = 0;
	do
	{
		snum[i++] = n % 10 + '0';
		n /= 10;
	}

	while (n);
	--i;

	if (neg)
		putchar('-');

	while (i >= 0)
		putchar(snum[i--]);

	putchar('\n');
}

// Driver Program
int main()
{
	int value;

	// Taking input
	scan(value);

	// Printing output
	print(value);
	return 0;
}
 

실행 결과는 당음과 같다.

Input:  756
Output: 756
 

블로그 주인장 생각 : 내가 아직 쪼랩이라 잘 몰라서 그럴수도 있는데 위의 방식은 숙련됬다처도 코테중에 다 작성하긴 좀 시간걸릴것 같은데? 이건 안쓸거 같다 란 생각이 든다...

 

5. Using Macros as for Loop

아마도 코드의 가독성을 감소시킬 수 있는 매크로를 사용하는 것은 좋지 않을 수 있지만, 빠른 코드를 작성하기 위해서 이정도는 감수할만합니다.

#include <bits/stdc++.h>
using namespace std;

#define rep(i,n) for (i = 0; i < n; ++i)
#define REP(i,k,n) for (i = k; i <= n; ++i)
#define REPR(i,k,n) for (i = k; i >= n; --i)

// Driver program to test above Macros
int main()
{
	int i;
	int array[] = {4, 5, 6, 9, 22, 11};
	int size= sizeof(array)/sizeof(array[0]);
	
	// Default 0 index based loop
	rep(i, size)	
		cout << array[i] << " ";
	cout<<"\n";
	
	// Starting index based loop
	REP(i, 1, size-1)	
		cout << array[i] << " ";
	cout<<"\n";
	
	// Reverse for loop
	REPR(i, size-1,0)	
		cout << array[i] << " ";
	return 0;
}
 

실행 결과는 다음과 같다.

4 5 6 9 22 11
5 6 9 22 11
11 22 9 6 5 4
 

 

6. Using "bits/stdc++.h"

코드 상단에 여러줄에 걸처가며 #include를 덕지덕지 사용할 바에는 그냥 #include<bits/stdc++.h> 하나로 끝냅시다.

이 파일에는 사용자가 코딩테스트를 하면서 사용할 header들이 모두 포함되 있습니다.

 

7. Containers

다양한 컨테이너들, 예를들어 vector, list, map 등등 가능한 미리 정의된 함수를 사용하여 코드의 양을 줄입시다.

 

8. Fast cin and cout:

만약 사용자가 I/O를 위해서 cin과 cout을 사용한다면, main함수 안에 다음 코드를 추가하길 권장합니다.

std::ios_base::sync_with_stdio(false);
 

9. auto

auto를 사용하면 프로그래밍 대회에서 많은 시간을 절약할 수 있습니다. auto로 선언된 변수는 컴파일러가 compile-time때 타입을 결정합니다.

 

10. Libraries and pre-defined functions

__gcd(A,B), swap, _builtin_popcount(R), _builtin_clz(R) 과 같은 builtin함수를 사용하면 어디서든 적용가능합니다.

C++의 algorithm 라이브러리 또한 배워보길 권장합니다. 여기에는 수많은 유용한 것들이 가득합니다.

댓글