본문 바로가기
Programming/Tips(C++,C#)

Algorithm : Modifying sequence operations

by 곰네Zip 2011. 10. 11.
참고자료
c++.com : http://cplusplus.com/reference/
일반적프로그래밍과 STL책.

저도 잘 모르는 내용이지만 제 임의대로 제가 기억하려고 올리는 것이므로 태클 환영합니다.

Copy : 일정 요소를 복사 (InputIterator ->OutputIterator)

OutputIterator copy( InputIterator first, InputIterator last, OutputIterator result)

{

While( first != last) *result++ = *first++;

Return result;

}

 

Copy_backward : 역순으로 복사. (InputIterator->OutputIterator이나 Input의 끝부터 복사시작)

BidirectionalIterator2 copy_backward( BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 result)

{

   While(last != first) *(--result) = *(--last);

   Return result;

}

 

Swap : a값과 b값을 바꿈

template <class T> void swap ( T& a, T& b )

{

  T c(a); a=b; b=c;

}

 


 

Swap_ranges : 같은 크기의 두 구간의 내용을 교환함

template<class ForwardIterator1, class ForwardIterator2>

  ForwardIterator2 swap_ranges ( ForwardIterator1 first1, ForwardIterator1 last1,

                                 ForwardIterator2 first2 )

{

  while (first1!=last1) swap(*first1++, *first2++);

  return first2;

}

 

Iter_swap : swap과 동일함.

template <class ForwardIterator1, class ForwardIterator2>

  void iter_swap ( ForwardIterator1 a, ForwardIterator2 b )

{

  swap (*a, *b);

}

 

Transform: f(혹은 OP)를 수행한 값을 넣는다는 것에서 for_each와 비슷하다. 그러나 반환값을 OutputIterator에 복사한다는 차이가 있음

template < class InputIterator, class OutputIterator, class UnaryOperator >

  OutputIterator transform ( InputIterator first1, InputIterator last1,

                             OutputIterator result, UnaryOperator op )

{

  while (first1 != last1)

    *result++ = op(*first1++);  // or: *result++=binary_op(*first1++,*first2++);

  return result;

}

 

Replace : 구간 안의 모든 요소를 검사하여 oldValue newValue로 변경

template < class ForwardIterator, class T >

  void replace ( ForwardIterator first, ForwardIterator last,

                 const T& old_value, const T& new_value )

{

  for (; first != last; ++first)

    if (*first == old_value) *first=new_value;

}

 


 

Replace_if : 조건pred에 맞는것만 변경 (replace의 일반화 버전?)

template < class ForwardIterator, class Predicate, class T >

  void replace_if ( ForwardIterator first, ForwardIterator last,

                    Predicate pred, const T& new_value )

{

  for (; first != last; ++first)

    if (pred(*first)) *first=new_value;

}

 

Replace_copy : replace와 같은 동작을 하나, OutputIterator로 복사하면서 값을 치환한다. , 원본은 값이 유지된다.

template < class InputIterator, class OutputIterator, class T >

  OutputIterator replace_copy ( InputIterator first, InputIterator last,

                                OutputIterator result, const T& old_value, const T& new_value )

{

  for (; first != last; ++first, ++result)

    *result = (*first==old_value)? new_value: *first;

  return result;

}

 

Replace_copy_if : replace_if copy버전

template < class InputIterator, class OutputIterator, class Predicate, class T >

  OutputIterator replace_copy_if ( InputIterator first, InputIterator last,

                                   OutputIterator result, Predicate pred,

                                   const T& new_value )

{

  for (; first != last; ++first, ++result)

    *result = (pred(*first))? new_value: *first;

  return result;

}

 

Fill : 모든 요소들에 value를 배정해줌

template < class ForwardIterator, class T >

  void fill ( ForwardIterator first, ForwardIterator last, const T& value )

{

  while (first != last)  *first++ = value;

}

 


 

Fill_n : 구간 n개에 대해서 value를 채워줌

template < class OutputIterator, class Size, class T >

  void fill_n ( OutputIterator first, Size n, const T& value )

{

  for (; n>0; --n)  *first++ = value;

}

 

Generate : iteratorGen(인자없는 함수객체)을 호출한 결과를 채움

template <class ForwardIterator, class Generator>

  void generate ( ForwardIterator first, ForwardIterator last, Generator gen )

{

  while (first != last)  *first++ = gen();

}

 

Generate_n : generate와 비슷. 구간중 n개의 데이터만 채움

template <class OutputIterator, class Size, class Generator>

  void generate_n ( OutputIterator first, Size n, Generator gen )

{

  for (; n>0; --n)  *first++ = gen();

}

 

Remove : 구간에서 value값을 제거..반복자를 파괴하지 않고, first last사이의 거리를 변경하지도 않는다. 제거이후 남아있는 요소들의 상대적인 순서는 변하지 않는다. 실제로 삭제시 erase()호출해야 변경사항 적용됨

template < class ForwardIterator, class T >

  ForwardIterator remove ( ForwardIterator first, ForwardIterator last, const T& value )

{

  ForwardIterator result = first;

  for ( ; first != last; ++first)

    if (!(*first == value)) *result++ = *first;

  return result;

}

 


 

Remove_if : remove의 일반화. 그러나 value기준이 아니라 pred에 해당하는 값만 제외함. erase호출해야 실제 변경사항 반영됨

template < class ForwardIterator, class Predicate >

  ForwardIterator remove_if ( ForwardIterator first, ForwardIterator last,

                              Predicate pred )

{

  ForwardIterator result = first;

  for ( ; first != last; ++first)

    if (!pred(*first)) *result++ = *first;

  return result;

}

 

Remove_copy : remove와 비슷. 그러나 result에 값을 복사하면서 value와 같은 것은 복사하지 않음. 원본 유지. 요소들의 상대적 순서는 stable.

template <class InputIterator, class OutputIterator, class T>

  OutputIterator remove_copy ( InputIterator first, InputIterator last,

                               OutputIterator result, const T& value )

{

  for ( ; first != last; ++first)

    if (!(*first == value)) *result++ = *first;

  return result;

}

 

Remove_copy_if: remove_if의 복사버전. Result에 값 복사시에 pred와 일치하지 않는 값만 복사함. 원본 유지됨. 상대적 순서는 역시 stable.

template <class InputIterator, class OutputIterator, class Predicate>

  OutputIterator remove_copy_if ( InputIterator first, InputIterator last,

                                  OutputIterator result, Predicate pred )

{

  for ( ; first != last; ++first)

    if (!pred(*first)) *result++ = *first;

  return result;

}

 


 

Unique : 인접한 인자들 중. 중복되는 인자들을 제거한 결과를 리턴. 중복되는 인자 중 첫번째 인자만 남김. erase호출해야 실제 변경사항 반영됨

template <class ForwardIterator>

  ForwardIterator unique ( ForwardIterator first, ForwardIterator last )

{

  ForwardIterator result=first;

  while (++first != last)

  {

    if (!(*result == *first))  // or: if (!pred(*result,*first)) for the pred version

      *(++result)=*first;

  }

  return ++result;

}

 

Unique_copy : unique와 비슷. Result로 결과를 복사함. 중복되는 인자의 경우 첫 인자만 제거함. 역시 인접한 인자들에 대해서만 작용함.

template <class InputIterator, class OutputIterator>

  OutputIterator unique_copy ( InputIterator first, InputIterator last,

                               OutputIterator result )

{

  typename std::iterator_traits<InputIterator>::value_type value = *first;

  *result=*first;

  while (++first != last)

  {

    if (!(value == *first))  // or: if (!pred(value,*first)) for the pred version

      *(++result) = value = *first;

  }

  return ++result;

}

 

Reverse : 반복자들이 가리키는 값을 뒤집는다.

template <class BidirectionalIterator>

  void reverse ( BidirectionalIterator first, BidirectionalIterator last)

{

  while ((first!=last)&&(first!=--last))

    swap (*first++,*last);

}

 


 

Reverse_copy : first-last구간안의 요소들을 역순으로 result에 복사함.,

template <class BidirectionalIterator, class OutputIterator>

  OutputIterator reverse_copy ( BidirectionalIterator first,

                                BidirectionalIterator last, OutputIterator result )

{

  while (first!=last) *result++ = *--last;

  return result;

}

 

Rotate : middle을 기준점으로 하여 이후 data를 앞으로 땡기고, 이전 data는 순서대로 뒤로..

template <class ForwardIterator>

  void rotate ( ForwardIterator first, ForwardIterator middle,

                ForwardIterator last )

{

  ForwardIterator next = middle;

  while (first!=next)

  {

    swap (*first++,*next++);

    if (next==last) next=middle;

    else if (first == middle) middle=next;

  }

}

 

Rotate_copy : rotate의 복사버전 copy동작 후 rotate. 원본 유지

template <class ForwardIterator, class OutputIterator>

  OutputIterator rotate_copy ( ForwardIterator first, ForwardIterator middle,

                               ForwardIterator last, OutputIterator result )

{

  result=copy (middle,last,result);

  return copy (first,middle,result);

}

 

Random_shuffle : 구간을 무작위로 재배치. 난수 생성기의 seed를 명시적으로 지정하는 것이 중요할 때가 있으므로 방법2가 추천됨

 

방법1.

template <class RandomAccessIterator>

  void random_shuffle ( RandomAccessIterator first, RandomAccessIterator last );

 

방법2.

template <class RandomAccessIterator, class RandomNumberGenerator>

  void random_shuffle ( RandomAccessIterator first, RandomAccessIterator last,

                        RandomNumberGenerator& rand )

{

  iterator_traits<RandomAccessIterator>::difference_type i, n;

  n = (last-first);

  for (i=n-1; i>0; --i) swap (first[i],first[rand(i+1)]);

}

 

Partition : pred에 따라 iterator를 나눔 (pred를 만족하면 앞쪽으로)

template <class BidirectionalIterator, class Predicate>

  BidirectionalIterator partition ( BidirectionalIterator first,

                                    BidirectionalIterator last, Predicate pred )

{

  while (true)

  {

    while (first!=last && pred(*first)) ++first;

    if (first==last--) break;

    while (first!=last && !pred(*last)) --last;

    if (first==last) break;

    swap (*first++,*last);

  }

  return first;

}

 

Stable_partition : partition하고 동일하지만 조건에 맞을경우 기존 순서 유지.

template <class BidirectionalIterator, class Predicate>

  BidirectionalIterator stable_partition ( BidirectionalIterator first,

                                           BidirectionalIterator last,

                                           Predicate pred );

 


반응형

댓글