C++ sgi STL学习笔记之non-mutating algorithm

非变易算法:

以下资料参考sgi stl.
1.for_each

template <class InputIterator, class UnaryFunction>
UnaryFunction for_each(InputIterator first, InputIterator last, UnaryFunction f);

函数接受三个参数,将函数对象f应用于[first,last)区间内的所有*iterator,并返回f的返回值的函数对象。
example:

template<class T> struct print : public unary_function<T, void>
{
  print(ostream& out) : os(out), count(0) {}
  void operator() (T x) { os << x << ' '; ++count; }
  ostream& os;
  int count;
};

int main()
{
  int A[] = {1, 4, 2, 8, 5, 7};
  const int N = sizeof(A) / sizeof(int);

  print<int> P = for_each(A, A + N, print<int>(cout));
  cout << endl << P.count << " objects printed." << endl;
}

2.find

template<class InputIterator, class EqualityComparable>
InputIterator find(InputIterator first, InputIterator last,
                   const EqualityComparable& value);

返回第一个i在区间[first,last)中,*i==value的迭代器。
example:

list<int> L;
L.push_back(3);
L.push_back(1);
L.push_back(7);

list<int>::iterator result = find(L.begin(), L.end(), 7);
assert(result == L.end() || *result == 7);

3.find_if

template<class InputIterator, class Predicate>
InputIterator find_if(InputIterator first, InputIterator last,
                      Predicate pred);

返回第一个i在区间[first,last)中,满足pred(*i)==true的迭代器。
example:

list<int> L;
L.push_back(-3);
L.push_back(0);
L.push_back(3);
L.push_back(-2);

list<int>::iterator result = find_if(L.begin(), L.end(),
                                     bind2nd(greater<int>(), 0));
assert(result == L.end() || *result > 0);

4.adjacent_find

template <class ForwardIterator>
ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last);

template <class ForwardIterator, class BinaryPredicate>
ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last,
                              BinaryPredicate binary_pred);

adjacent_find是一个重载函数。
第一个版本接受两个参数,返回第一个i在区间[first,last)中满足i==(i+1)的迭代器。
第二个版本接受三个参数,返回第一个i在区间[first,last)中满足binary_pred(i, (i+1))==true的迭代器。
example:

int A[] = {1, 2, 3, 4, 6, 5, 7, 8};
const int N = sizeof(A) / sizeof(int);

const int* p = adjacent_find(A, A + N, greater<int>());

cout << "Element " << p - A << " is out of order: "
     << *p << " > " << *(p + 1) << "." << endl;

5.find_first_of

template <class InputIterator, class ForwardIterator>
InputIterator find_first_of(InputIterator first1, InputIterator last1,
                            ForwardIterator first2, ForwardIterator last2);

template <class InputIterator, class ForwardIterator, class BinaryPredicate>
InputIterator find_first_of(InputIterator first1, InputIterator last1,
                            ForwardIterator first2, ForwardIterator last2,
                            BinaryPredicate comp);

该函数是一个重载函数,存在两个版本。
第一个版本与第二个版本的区别是比较方式不同,第一个直接使用operator==,第二个采用比较函数comp。
用于查找位于某个范围之内的元素。在迭代器区间[first1, last1)上查找元素*i,使得迭代器区间[first2, last2)有某个元素*j,满足*i ==*j或满足二元谓词函数comp(*i, *j)==true的条件。元素找到则返回迭代器i,否则返回last1。
example:

int main()
{
  const char* WS = "\t\n ";
  const int n_WS = strlen(WS);

  char* s1 = "This sentence contains five words.";
  char* s2 = "OneWord";


  char* end1 = find_first_of(s1, s1 + strlen(s1),
                             WS, WS + n_WS); 
  char* end2 = find_first_of(s2, s2 + strlen(s2),
                             WS, WS + n_WS); 

  printf("First word of s1: %.*s\n", end1 - s1, s1); 
  printf("First word of s2: %.*s\n", end2 - s2, s2); 
}

6.count

template <class InputIterator, class EqualityComparable>
iterator_traits<InputIterator>::difference_type
count(InputIterator first, InputIterator last, 
      const EqualityComparable& value);

template <class InputIterator, class EqualityComparable, class Size>
void count(InputIterator first, InputIterator last, 
           const EqualityComparable& value,
           Size& n);

函数是一个重载函数,第一个版本返回在区间[first,last)中等于value的个数。
第二个版本限制了迭代器i在区间的次数。
example:

int main() {
  int A[] = { 2, 0, 4, 6, 0, 3, 1, -7 };
  const int N = sizeof(A) / sizeof(int);

  cout << "Number of zeros: " 
       << count(A, A + N, 0)
       << endl;
}

7.count_if

template <class InputIterator, class Predicate>
iterator_traits<InputIterator>::difference_type
count_if(InputIterator first, InputIterator last, Predicate pred);

template <class InputIterator, class Predicate, class Size>
void count_if(InputIterator first, InputIterator last, 
              Predicate pred,
              Size& n);

函数count_if和count相似,在原来的operator==value变成了pred(*i)==true
example:

int main() {
  int A[] = { 2, 0, 4, 6, 0, 3, 1, -7 };
  const int N = sizeof(A) / sizeof(int);

  cout << "Number of even elements: " 
       << count_if(A, A + N, 
                   compose1(bind2nd(equal_to<int>(), 0), 
                            bind2nd(modulus<int>(), 2)))
       << endl;
} 

8.mismatch

template <class InputIterator1, class InputIterator2>
pair<InputIterator1, InputIterator2> 
mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2);

template <class InputIterator1, class InputIterator2, 
          class BinaryPredicate>
pair<InputIterator1, InputIterator2> 
mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2,
         BinaryPredicate binary_pred);

函数是重载函数。第一个版本返回从first2开始的第一个与[first1,last1)不匹配的指针。
第二个版本通过二元谓词函数pred(i, (first2+ (i-first1) ))判断,返回第一个false的指针。
example:

int A1[] = { 3, 1, 4, 1, 5, 9, 3 };
int A2[] = { 3, 1, 4, 2, 8, 5, 7 };
const int N = sizeof(A1) / sizeof(int);

pair<int*, int*> result = mismatch(A1, A1 + N, A2);
cout << "The first mismatch is in position " << result.first - A1 << endl;
cout << "Values are: " << *(result.first) << ", " << *(result.second) << endl;

9.equal

template <class InputIterator1, class InputIterator2>
bool equal(InputIterator1 first1, InputIterator1 last1,
           InputIterator2 first2);

template <class InputIterator1, class InputIterator2, 
          class BinaryPredicate>
bool equal(InputIterator1 first1, InputIterator1 last1,
           InputIterator2 first2, BinaryPredicate binary_pred);

函数返回类型为bool,重载函数的两个版本区别为比较不同,版本一使用operator==比较,第二个版本使用二元谓词函数pred比较。当两个区间比较全部一致时,或pred()==true在整个区间成立,则返回true,否则返回false
example:

int A1[] = { 3, 1, 4, 1, 5, 9, 3 };
int A2[] = { 3, 1, 4, 2, 8, 5, 7 };
const int N = sizeof(A1) / sizeof(int);

cout << "Result of comparison: " << equal(A1, A1 + N, A2) << endl;

10.search

template <class ForwardIterator1, class ForwardIterator2>
ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1,
                        ForwardIterator2 first2, ForwardIterator2 last2);

template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1,
                        ForwardIterator2 first2, ForwardIterator2 last2,
                        BinaryPredicate binary_pred);

函数为重载函数,第一个版本采用operator==查找[first1,last1)区间内存在的匹配子串满足==[first2,last2),第二个版本的不同时采用二元谓词函数pred做比较。函数返回匹配子串的头指针,如果没有匹配则返回last1
example:

  const char S1[] = "Hello, world!";
  const char S2[] = "world";
  const int N1 = sizeof(S1) - 1;
  const int N2 = sizeof(S2) - 1;

  const char* p = search(S1, S1 + N1, S2, S2 + N2);
  printf("Found subsequence \"%s\" at character %d of sequence \"%s\".\n",
         S2, p - S1, S1);

11.search_n

Search_n is an overloaded name; there are actually two search_n functions.
template <class ForwardIterator, class Integer, class T>
ForwardIterator search_n(ForwardIterator first, ForwardIterator last,
                         Integer count, const T& value);

template <class ForwardIterator, class Integer, 
          class T, class BinaryPredicate>
ForwardIterator search_n(ForwardIterator first, ForwardIterator last,
                         Integer count, const T& value,
                         BinaryPredicate binary_pred);

函数查找count个等于value的子串。即满足j在区间[i , i+count)中 *j==value,函数返回第一个这样的i的指针。如果没有,则返回last
函数为重载函数,两个版本的不同在于比较方式,第二种采用二元函数binary_pred(*i,value)代替operator==
example:

bool eq_nosign(int x, int y) { return abs(x) == abs(y); }

void lookup(int* first, int* last, size_t count, int val) {
  cout << "Searching for a sequence of "
       << count
       << " '" << val << "'"
       << (count != 1 ? "s: " : ":  ");
  int* result = search_n(first, last, count, val);
  if (result == last)
    cout << "Not found" << endl;
  else
    cout << "Index = " << result - first << endl;
}

void lookup_nosign(int* first, int* last, size_t count, int val) {
  cout << "Searching for a (sign-insensitive) sequence of "
       << count
       << " '" << val << "'"
       << (count != 1 ? "s: " : ":  ");
  int* result = search_n(first, last, count, val, eq_nosign);
  if (result == last)
    cout << "Not found" << endl;
  else
    cout << "Index = " << result - first << endl;
}

int main() {
  const int N = 10;
  int A[N] = {1, 2, 1, 1, 3, -3, 1, 1, 1, 1};

  lookup(A, A+N, 1, 4);
  lookup(A, A+N, 0, 4);
  lookup(A, A+N, 1, 1);
  lookup(A, A+N, 2, 1);
  lookup(A, A+N, 3, 1);
  lookup(A, A+N, 4, 1);

  lookup(A, A+N, 1, 3);
  lookup(A, A+N, 2, 3);
  lookup_nosign(A, A+N, 1, 3);
  lookup_nosign(A, A+N, 2, 3);
}

12.find_end

template <class ForwardIterator1, class ForwardIterator2>
ForwardIterator1 
find_end(ForwardIterator1 first1, ForwardIterator1 last1, 
         ForwardIterator2 first2, ForwardIterator2 last2);

template <class ForwardIterator1, class ForwardIterator2, 
          class BinaryPredicate>
ForwardIterator1 
find_end(ForwardIterator1 first1, ForwardIterator1 last1, 
         ForwardIterator2 first2, ForwardIterator2 last2,
         BinaryPredicate comp);

函数与serach相似,与search的区别在于search返回第一个匹配的子串,而find_end返回最后一个匹配的子串。
example:

int main()
{
  char* s = "executable.exe";
  char* suffix = "exe";

  const int N = strlen(s);
  const int N_suf = strlen(suffix);

  char* location = find_end(s, s + N,
                            suffix, suffix + N_suf);

  if (location != s + N) {
    cout << "Found a match for " << suffix << " within " << s << endl;
    cout << s << endl;

    int i;
    for (i = 0; i < (location - s); ++i)
      cout << ' ';
    for (i = 0; i < N_suf; ++i)
      cout << '^';
    cout << endl;
  }
  else
    cout << "No match for " << suffix << " within " << s << endl;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值