[알고리즘] 2강 기초 코드 작성 요령 2

mmmYoung·2022년 6월 11일
0

알고리즘

목록 보기
2/13

STL과 함수인자

함수인자

함수의 인자가 int / int형 배열 / 구조체일때 원본의 값이 변경되는가?

다음 세 가지 경우에서, 출력을 예측해보자.

첫번째 경우, 출력 값 0

함수 인자로 보내면 값이 복사되어 넘어가므로, main의 원본 t에는 변화 없음

두번째 경우, 출력 값 10

함수 인자로 arr의 주소값을 넘겨주기 때문에 자연스럽게 원본 arr값이 변경된다.

세번째 경우, 출력 값 0

구조체도 int와 마찬가지로 값이 복사되어 넘어감 !! 꼭 기억하기

참조자(Reference)

익숙한 swap함수 만들기! 첫번째 swap1의 경우 위에서 보듯 복사된 값만 바뀌기 때문에 스왑기능이 제대로 이루어지지 않는다.
C++에는 원본 값을 변경하는 함수를 만드는 두 가지 방법이 있다.
swap2처럼 함수인자를 포인터로 받는 방법,
swap3는 참조자를 이용하여 int가 아닌, int& 로 받는 방법이 있다. 이 경우 함수 내부에서는 그냥 int형 인자처럼 사용하면 댐

STL을 함수인자로 넘길 때


STL 중 하나인 vector의 경우이다.(STL관련 정리는 따로 글 파서 하기,,)
메인 함수에서 출력되는 값은? 구조체처럼 복사본을 만들어 보내기 때문에,
원본에 영향을 주지 않으므로 0이 출력됨.

함수인자에 STL을 그대로 넣으면 항상 복사가 이루어진다

아래 두 함수의 시간복잡도는 ?

두 함수는 두 벡터를 함수인자로 받아 idx번째 원소의 크기를 비교하는 함수이다.
cmp1의 경우 O(N)이고, cmp2의 경우 O(1)이다.

연산을 한 번만 하는데 cmp1은 시간복잡도가 왜 N번이나 나올까 ?

-> idx번째 원소를 비교하는 일은 O(1)이지만, 그 전에 모든 벡터를 복사하는 일이 매번 수행되기 때문 !! 의도한대로 함수를 짜기 위해서는 cmp2처럼 참조자를 이용하여 함수인자를 받아야 한다.

표준 입출력

공백을 포함한 문자열 입력받기

scanf/cin 을 사용할 때 공백이 포함되면 공백 앞까지의 문자열만 입력받아진다.
이를 방지하기 위한 세가지 방법이 있지만 가장 권장하는 방법은

getline(cin,string str, char delimiter)

getline(입력스트림 오브젝트, 문자열을 저장할 string객체, 종결 문자)
종결 문자 생략 시 줄바꿈전까지 입력받음

문자열 입력 관련 참고 https://kyu9341.github.io/C-C/2020/01/17/C++getline()/

ios::sync_with_stdio(0)와 cin.tie(0)

scanf/printf에서는 상관없지만 cin/cout를 사용할때 주의해야 할 점이 하나 더 있당
입출력 양이 많을 때 시간초과를 방지하기 위한 두 명령어이다.
ios::sync_with_stdio(0)의 경우, c++과 c의 스트림 동기화를 끊어버리는 (인자가 bool 타입이라 0이 false를 의미함) 명령어임. 대신 얘를 사용하면 scanf/printf 사용이 불가능하다. 안그럼 출력순서 꼬임


cin.tie(0)의 경우 버퍼와 관련된 명령어.
간단히 말해 출력될때 바로바로 출력되는 게 아니라 출력버퍼에 임시로 들어가 있다가 콘솔창에 띄워지며 버퍼가 비워짐.
이때 입출력이 번갈아 나오면 아래처럼 버퍼때문에 순서가 이상해진다.

온라인 저지 사이트에서는 출력 최종결과만 확인하기 때문에 입력 명령을 수행하기 전에 굳이 출력 버퍼를 비울 필요가 없음..
즉 cin.tie(0)은 cin 명령을 수행하기 전에 cout 버퍼를 비우지 않도록 하는 명령어이다.


넹.. 쓰지 맙시다
endl은 개행문자("\n")를 출력하고 출력 버퍼를 비워라는 명령어이므로, 위에서 말했듯 최종 출력결과만 필요한 코테에서는 중간 중간 버퍼를 비우라고 명령을 줄 필요가 전혀 없슴~

줄바꿈이 필요하면 endl 말고 그냥 \n 출력하기 !

코드 작성 팁

BOJ 10871번 : X보다 작은 수 를 풀어보자.

왼쪽은 정교한 코드 예시, 오른쪽은 코테용 짧고 간단한 코드 예시
코딩 테스트는 어차피 내가 편한대로 하면 되니까 깔끔하고 정갈하게 쓸 필요 없음.
그냥 내가 보기 편한대로 짧게 짧게 쓰자

내 코드

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    int value,N,X;
    vector<int> ans;
    cin >> N >> X;
    for(int i=0; i<N; i++){
        cin >> value;
        if(value < X) cout << value << "";
    }
    
    for(auto itr=ans.begin(); itr!=ans.end(); itr++) cout << *itr << " ";
    return 0;
}

출력 맨 뒤에는 줄바꿈이나 공백이 있어도 정답 인정 됨

디버거는 굳이 필요없음. 차라리 중간 값 출력을 하자

profile
안냐세여

0개의 댓글