C++ 알고리즘 기초8 -빠른 입출력을 위한 cin,cout과 scanf & printf 배우기-

1. 문제

 

https://www.acmicpc.net/problem/15552

 

15552번: 빠른 A+B

첫 줄에 테스트케이스의 개수 T가 주어진다. T는 최대 1,000,000이다. 다음 T줄에는 각각 두 정수 A와 B가 주어진다. A와 B는 1 이상, 1,000 이하이다.

www.acmicpc.net

 

2. 버퍼(buffer)

 

데이터가 전송될때 일시적으로 데이터를 보관하는 메모리 영역

 

 

3. cin & cout의 입출력 속도를 향상시키기

 

cin과 cout을 이용해 입출력을 하고자 한다면, int main() 함수 안에 

 

cin.tie(NULL);

ios_base::sync_with_stdio(false);를 적용하고

 

endl 대신에 개행문자 "\n"을 사용해 입출력을 수행한다.

 

이렇게 세팅하면 scanf, printf 등 C의 입출력 방식을 사용하지 말아야한다.

 

#include <iostream>
using namespace std;

int main() {
    
    cin.tie(NULL);
    ios_base::sync_with_stdio(false);
    
    int T;
    
    cin >> T;
    
    for(int i = 0; i < T; i++){
        int a,b;
        
        cin >> a >> b;
        
        cout << a+b << "\n";
    }
    
    return 0;
}

 

1) endl이 개행문자를 출력하면서, 출력 버퍼를 비우는 역할을 하는데, 이 버퍼를 비우는 작업이 매우 느리다고 함

 

그래서 '\n'으로 바꾸는것 만해도 엄청난 시간향상이 난다고 한다

 

실제로 endl로 바꾸면 시간초과남;;

 

2) cin.tie(NULL)은 cin과 cout의 묶음을 해제함

 

원래는 cin과 cout이 연결되어 있어서, cin을 쓰면 출력 버퍼를 먼저 비우고 입력이 발생하는데,

 

출력 버퍼를 비우는 작업이 시간이 든다고함

 

cin.tie(NULL)로 연결을 끊으면,

 

프로그램이 유저에게 입력을 요구하기 전에, 출력 버퍼를 먼저 비우고 입력을 받는다고 함

 

출력 버퍼는 꽉 차야 출력이 되는데, 꽉 차지 않아도 즉시 출력해 비워준다고 함

 

3) ios_base::sync_with_stdio(false)은, 기본적으로 cin,cout이 C의 입출력인 stdio.h와 동기화되어있는데,

 

이런 동기화 작업이 필요하다보니 cin,cout이 상대적으로 속도가 느리다고함

 

ios_base::sync_with_stdio(false)을 수행하면 C의 stdio.h와 C++의 iostream의 동기화를 해제한다.

 

그러면서 속도를 향상시킨다

 

근데 이렇게 하면, C와 동기화를 해제해서, C와 C++의 버퍼가 독립이 되어

 

C의 입출력방식인 printf, scanf를 사용할 수 없다고함

 

그리고 single thread에만 사용할 수 있는 입출력 향상을 위한 일종의 편법이라고 함

 

https://www.acmicpc.net/board/view/22716

 

글 읽기 - 추가 설명 및 다른 언어 빠른 입출력 방법

댓글을 작성하려면 로그인해야 합니다.

www.acmicpc.net

 

https://daeuungcode.tistory.com/10

 

백준 15552 빠른입출력

https://www.acmicpc.net/problem/15552 15552번: 빠른 A+B 첫 줄에 테스트케이스의 개수 T가 주어진다. T는 최대 1,000,000이다. 다음 T줄에는 각각 두 정수 A와 B가 주어진다. A와 B는 1 이상, 1,000 이하이다. www.acmic

daeuungcode.tistory.com

 

 

https://velog.io/@matcha_/%EB%B0%B1%EC%A4%80-C-cin-cout-%EC%9E%85%EC%B6%9C%EB%A0%A5-%EC%86%8D%EB%8F%84-%EB%B9%A0%EB%A5%B4%EA%B2%8C-%ED%95%98%EB%8A%94-%EB%B2%95

 

[백준] C++ cin, cout 입출력 속도 빠르게 하는 법

나는 C++을 이용해서 백준 문제를 풀고있다. 그런데 풀다가 이상한 광경을 목격했다. 다른 사람의 코드를 봤는데, 분명 나와 코드 구조는 같은데 실행 시간이 훨씬 빨랐다. 뭐가 다른걸까 비교해

velog.io

 

 

4. scanf, printf

 

편법을 쓰지 않고 정상적인 방법?을 쓰겠다면.. scanf와 printf를 배워보자

 

scanf와 printf는 그 자체로 속도가 충분히 빠르다.

 

먼저 헤더로 #include <cstdio>나 #include <stdio.h>를 사용한다

 

cstdio는 C++ 방식이라하고 stdio.h는 C방식이라고 함.. 취향이라고 하는데?

 

scanf의 경우 입력을 받는데, 예를 들어 다음과 같다

 

#include <cstdio>

int main() {
    
    int T;
    
    scanf("%d", &T);
}

 

formatting 지정자 %d를 이용해서, 정수를 입력받을건데, 이를 T라는 변수에 저장한다는 의미

 

&T의 &는 변수의 메모리 주소라는 의미라고 함.

 

scanf("%d", &T)는 T의 메모리 주소에 접근하여, 입력받은 정수값을 데이터로 저장하라는 의미

 

만약 공백을 가진 2개의 입력을 받고 싶다면..?

 

scanf("%d %d", &a, &b);로 하면 첫번째 값은 a에 두번째 값은 b에 저장

 

#include <cstdio>

int main() {
    
    int T;
    scanf("%d", &T);
    
    for(int i = 0; i < T; i++){
        
        int a,b;
        
        scanf("%d %d", &a, &b);
    
    }
}

 

printf도 formatting을 이용해 출력하는데.. 얘는 앞에 &를 붙이지 않는다.

 

a+b를 출력하고 싶다면.. printf("%d",a+b);

 

한줄 띄워야한다면.. \n을 붙여줘야겠지

 

#include <cstdio>

int main() {
    
    int T;
    
    scanf("%d", &T);
    
    for(int i = 0; i < T; i++){
        
        int a,b;
        
        scanf("%d %d", &a, &b);
        
        printf("%d\n",a+b);
    }
}

 

 

https://where-i-am.tistory.com/entry/C-%EA%B8%B0%EB%B3%B8-%EC%9E%85%EC%B6%9C%EB%A0%A5-cin-cout-scanf-printf

 

[C++] 기본 입출력 ( cin | cout | scanf | printf )

기본 입출력 함수 헤더 파일 #include 위의 헤더파일을 반드시 추가해야 사용 가능합니다. cin,cout 모두 std 네임스페이스 내에 존재합니다. 참고로 아래의 코드를 추가하면 std:: 를 붙이지 않고도 사

where-i-am.tistory.com

 

 

TAGS.

Comments