티스토리 뷰

PS/PS_Note

[C/C++] C++ PS Coding Tip (~ing)

Aaron 2020. 2. 24. 12:08
반응형



.입출력



. 입출력 방식 속도

C 표준 입출력 함수 scanf, printf (적은 메모리를 사용하지만 아래 방법보다는 느림)

   단, cin보다 대용량의 데이터를 input 할 수 있음


- std::cin, std::cout 사용 시 아래 코드 적용

1
 ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL
cs

이 코드를 적용하지 않으면 입,출력시 사용하는 버퍼를  동기화하는 것인데,

이럴 경우 C++ 표준 stream버퍼와 C 표준 stream 버퍼가 병행하여 버퍼를 사용하게 된다.

C++, C 로 stream 버퍼를 모두 사용할 수 있지만, 버퍼를 병행하여 사용하기 때문에 속도가 느려지는 현상이 발생하게 된다. 

그래서 이 코드로 동기화를 해제해주면서 C++ 표준 stream만 사용하도록 하여 독립 버퍼만 사용할 수 있게 한다.


- 개행문자 "\n" 사용, cout << num << "\n";


   (함수로 사용 시 편리) 

1
#define init() ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL)
cs


   참고) 입/출력 속도 비교

   https://www.acmicpc.net/blog/view/56

   https://www.acmicpc.net/blog/view/57


. 반복문에 입력과 조건을 동시에

1
2
3
while (scanf("%d %d"&A, &B), A&&B) {
        printf("%d\n", A + B);
}
cs


. 입력이 끝날 때 까지 반복

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 1. scanf()가 입력받은 인자의 갯수를 리턴하는 특성을 활용하는 방법
while (scanf("%d%d"&A, &B) == 2)
 
// +. 틸트(~) 연산자 사용
// 없으면 0을 반환
while (~scanf("%d %d"&A, &B)) {
        printf("%d\n", A + B);
    }
 
// 2. scanf()를 EOF와 직접 비교하는 방법
while (scanf("%d %d"&A, &B) != EOF)
 
// 3. EOF가 상수 -1로 정의되어 있는 특성을 활용하는 방법
while (scanf("%d %d"&A, &B) != -1 || scanf("%d%d"&A, &B)>0printf("%d\n", A + B);
 
/// 4. cin.eof()를 활용하는 방법
// cin으로 입력받은 값이 없으면 cin.eof()는 true를 반환 
while (true) {
    cin >> A >> B;
    if (cin.eof() == true) {
cs

--

1
for (;~scanf("%d"&num); i++)
cs

--


.txt 파일 입력받기 

1
2
3
4
5
freopen("input.txt""rt", stdin);
 
int n;
 
scanf("%d"&n);
cs
--

1
2
3
4
5
6
7
#include <fstream>
 
ifstream cin;
cin.open("input.txt");
 
char a[100];
cin >> a;
cs

--


.문자열


.string 문자열을 char로 받기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
char str[20];
int i;
 
scanf("%s", str); // fread(str, 1, sizeof(str), stdin);
for (i = 0; str[i]; i++)
    putchar(s[i]); // printf("%c", s[i]);
puts(" ");
 
// 문자열 길이까지 탐색
for(i = 0; a[i] != '\0'; i++)
 
// 10자씩 끊어서 입력받기
while (~scanf("%10s", str))
    puts(str);
 
cs
--


.string 대신 char* 사용하기

1
const char *Day[7= { "SUN""MON""TUE""WED""THU""FRI""SAT" };
cs


.공백이 포함된 문자열 입력 받기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// gets
char a[100];
gets(a)
 
// string getline
string str;
getline(cin, str);
int len = str.length();
 
// array getline
char arr[100];
cin.getline(arr,100// while (fgets(arr, sizeof(arr), stdin))
 
// scala
char a;
while(scanf("%c",&a)!=-1)
cs

--

1
2
3
4
5
char str[1000000];
 
str[fread(str, 1sizeof(str), stdin)] = 0;
for (int i = 0; str[i]; ++i)
    ...
cs

--


. 한 글자씩 받기

- 문자열이 붙어있는 경우

- cp+1 부터 저장

1
2
3
int cp[51]; 
 
scanf("%1d", cp+1);
cs

--


.메모리


.레지스터 변수

1
register int i, j;
cs

- 메모리 대신 CPU의 레지스터를 사용 -> 일반 변수보다 빠른 속도 (단, 레지스터는 개수가 한정)

- 레지스터 변수는 변수가 CPU만 사용하므로 메모리에는 생성되지 않음 (&로 메모리 주소 참조 불가)

- 반복 횟수가 매우 많을 때 유용

--


. 메모리 초기화

1
2
3
4
#include <string.h>
 
int cache[2500];
memset(cache, -1sizeof(cache));
cs

--


.벡터 초기화

--

1
2
3
4
5
// 1차원 배열
Board.resize(N, 0)
 
// 2차원 열
Board.resize(N, vector<int>(N, 0));
cs

--


.Stream Buffering 변경 : setvbuf

1
2
3
4
char in[1<<19]; // Buffer stream 객체 생성(fopen 도 사용)
 
setvbuf(stdin, in, _IOFBF, sizeof(in));
setvbuf(stdout, in, _IOFBF, sizeof(in));
cs

--


.변수


. min, mix 표기

1
2
3
4
5
6
7
8
int max = 1e6   // 1000000
int min = -1e6  // -1000000
 
int max2 = 2147000000;
int min2 = -2147000000;
 
double max = 1e-6;  // 0.000001
double min = -1e-6;  // 0.000001
cs


. ASCII Code

1
2
3
4
5
'A' ~ 'Z' = 65 ~ 90
 
'a' ~ 'z' = 97 ~ 122
 
 0 ~ 9 = 48 ~ 57
cs

                 출처 : https://shaeod.tistory.com/228


.동적 vector 생성

1
2
3
4
5
6
7
#include<vector>
 
using namespace std;            
 
scanf("%d"&n);
 
vector<int> a(n);
cs


.동적 배열 생성

1
2
3
int *pArr = new int[n+1];
...
delete[] pArr;
cs


.첫 번째 or 마지막 원소 참조

1
2
start = *(vt.end()-1);
end = *(vt.begin());
cs


.여러 변수에 같은 같을 저장할 경우

1
p2=p3=p5=1;
cs


.구조체 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct Lecture
{
    int money;
    int day;
 
    // 생성자
    Lecture(int a, int b)
    {
        money = a;
        day = b;
    }
 
    // sort()에서 오름차순 정렬을 위해 사용하는 < operator 를 오버라이딩
    bool operator<(const Lecture& b) const
    {
        // 앞에 자료가 크다면 true를 반환하여 < operator 동작 시 내림차순으로 정렬
        return day > b.day;
    }
 
}
 
cs


.연산


.세 수의 최솟값

1
2
3
4
if (n1 < n2) min = n1;
else min = n2;
 
if (n3 < min) min = n3;
cs



.회고


ㅇ문자열 처리

   - 문자열은 개행문자 '\0' 으로 끝남


ㅇ변수

   - 전역변수로 선언하는 이유는, 원소를 0으로 자동 초기화시켜주기 때문(단, 지역변수보다 메모리를 더 차지)

   - PS 코딩 때는 변수명도 짧고 센스있게 지어보기(물론 실무에서는 자세히 지어주는게 좋지만..)

   - 변수 초기값 및 초기화 위치 확인

   - 최대 N의 크기만큼 배열을 생성하는 것 보다 vector의 동적 할당을 이용하는 방법(N이 클 경우 유리)

     ㄴ vector 를 동적으로 생성 시 기본적으로 원소를 0으로 초기화

   - 배열을 사용하지 않고도 pre, now 변수로 문제를 해결해내는 센스

   - for문을 사용하지 않고 증감연산자로 해결할 수 있다면, 최대한 반복문을 사용하지 않는 것이 속도 성능에서 유리!

   - 다수의 원소값을 얻고 싶은게 아니라 소수의 원소값을 얻는 것이 목적이라면 배열을 사용하지 안고 변수만으로 원하는 값을 얻어보자!


ㅇ연산

   - ASCII Code 를 잘 활용해보자

   - 반복문 안에서 입력과 처리를 동시에 

   - "소인수분해"는 합성수를 "소수의 곱"으로 나타낸 방법!

   - if and for collaboration 은 while 문으로 사용해보자

   - 배열 참조와 동시에 증감연산자를 사용하면 코드가 더 깔끔해진다. v[p++];


ㅇ 처리

   - "더 이상 처리할 작업이 없을 경우 '-1' 출력"과 같이 특수 상황의 경우 미리 처리하기

  

ㅇ 알고리즘 구현

   - DFS 문제는 스택을 그려보면서 함수를 만들어나가도록!


ㅇ기타

    - 문제 잘못 이해하고 풀면 끝장이다.. 문제 제대로 이해하고 재정의한 후 풀자.

    - 자료구조의 특성, 장점을 잘 활용해서 풀자!


.기타


. LNK 1168 Error

  - cmd -> taskkill /f /im [projectName].exe


알고리즘 대회에 필요한 수학 ]

- https://algospot.com/wiki/read/알고리즘_대회에_필요한_수학


[ 읽어보면 좋은 PS 공부 방법 ]

https://subinium.github.io/how-to-study-problem-solving/

https://baactree.tistory.com/52

https://koosaga.com/217

반응형
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday