Algorithm

CJB_ny·2022년 8월 26일
0

C++ 정리

목록 보기
72/95
post-thumbnail

이전시간에 문제 풀었던거

가독성 ㅎㅌㅊ에 범용성 ㅎㅌㅊ인것을

'알고리즘'을 통해 좀더 효율적으로 만들어보도록 하자.

#include < algorithm >

  • 자료구조 : 데이터를 저장하는 구조

    vector, list, deque | map(AVL), set, mulitmap, multiset

  • 알고리즘 : 데이터를 가공해서 활용하는 -> 어떻게 데이터를 사용할 것인가?

-> ㅈㄴ 많다.

원리만 이해하자.

자주 사용하는 알고리즘 (숙지) ❗❗❗

  • find
  • find_if
  • count
  • count_if
  • all_of
  • any_of
  • none_of
  • for_each
  • remove
  • remove_if

애내들은 활용빈도가 높다.

find

begin()부터 end()를 포함하지 않는 전까지.

한줄로 똑같이 됨.

C++11를 자동추론 사용하면

더 줄일 수 있음.

find의 경우 iterator를 기반으로 첫 두인자를 받아주다 보니까

리스트의 경우에도 잘 동작한다.

그래서 STL에서 iterator라는 애로 뭉틍 그려서 해주는게

이런 부분에서 큰 장점이 있는 것이다.

find_if

2번의 경우 find_if를 사용하는데

find와 비슷한데 마지막 인자에 '조건'이 들어가야한다.

F12 ->

이 find_if == 템플릿 함수

_Pr _Pred 함수처럼 동작하는 것이라면 어떠한 것이도 OK.

그런데 잘 보면 if문안에 들어가있으니까

그 어떠한 것(함수) OK인데 그 함수는 boolean내뱉는 함수이여야 하고 인자를 *_UFirst를 받는다.

즉, '함수객체'를 사용한 '콜백 방식' 아니가?

(ㅇㅇ 맞다)

코드

이번에는 struct로 함수 객체 만들어서 find_if의 마지막 인자로 넣어주도록 하자.

함수 객체 ❗❗❗

이렇게 struct를 사용해서 만들어 줄 수도있고

이렇게 class로 만들어도 연산자 오버로딩만 해준다면 문제없이 사용가능하다.

마지막 인자에 Find()가 가능한 것은

객체의 이름을 안 붙이고 임시 객체를 생성하여 바로 operator ()를 호출 한 것이다.

(해당 임시 객체는 컴파일러가 알아서 소멸자를 호출한다)

어쨋든 find_if 어디서 어디까지 하나만 찾아 줄 것이다.

이것이 명확하다.

count_if

first, end, if

all_of, any_of, none_of

자주 사용하는 삼총사

위에있는 함수 객체 그대로 사용가능한데

  • all_of : 모든 데이터가 홀수 입니까?

  • any_of : 홀수인 데이터가 하나라도 있습니까?

  • none_of : 모든 데이터가 홀수가 아닙니까?

굉장히 유용함.

for_each

모든 애들에 대해서 진행한다.

remove 시리즈 ❗

기존의 애들과는 다르게 조금 묘하게 동작한다.

홀수인 데이터 삭제하고싶을 경우

이렇게 해주면되는 하는데 좀 아쉽다.

(참고로 iterator ++하는 부분은 이렇게 if만에다가 넣어주는 게 좋다)

뭐가 아쉽냐면? 벡터에서 중간 삽입(/삭제) 하는 부분이 그다지 효율적이지 않다는 점.

remove, remove_if

두개 다 비슷하게 동작한다는 것은 알 수 있는데.

현재 데이터가 이상하게 바꿔치기 되었다는 것을 알 수 있다.

remove_if코드 ❗❗❗

불필요한 데이터를 일일히 삭제하는 것이 아니라

필요한 데이터를 남겨두는쪽으로 동작하고있다.

그래서 지금 함수 객체로 Odd넘겨주었는데

홀수는 삭제하고 짝수만을 앞으로 당겨오는 식이다.

그래서 4 8 2 5 8 2 가 남는데

4 8 2 [ '5' 8 2 ]

여기에서 반환하는 부분이 '5'를 가르키는 iterator이다.

따라서 우리는 한번더 erase를 해주어야한다.

vector<int>::iterator it = remove_if(v.begin(), v.end(), IsOdd());

v.erase(it, v.end());

이렇게 뱉어주는 받아서 삭제를 해야한다.

근데 이렇게하면 귀찮으니까

v.erase(remove_if(v.begin(), v.end(), IsOdd()), v.end());

이렇게하면 한방에 처리가 가능하다.

profile
https://cjbworld.tistory.com/ <- 이사중

0개의 댓글