Читаем Thinking In C++. Volume 2: Practical Programming полностью

  print(v.begin(), v.end(), "partial_sort");

  v = original;

  // Move iterator to a quarter position

  it = v.begin();

  for(size_t i = 0; i < v.size() / 4; i++)

    it++;

  // Less elements to copy from than to the destination

  partial_sort_copy(v.begin(), it, w.begin(), w.end());

  print(w.begin(), w.end(), "partial_sort_copy");

  // Not enough room in destination

  partial_sort_copy(v.begin(), v.end(), w.begin(),

    w.end());

  print(w.begin(), w.end(), "w partial_sort_copy");

  // v remains the same through all this process

  assert(v == original);

  nth_element(v.begin(), it, v.end());

  cout << "The nth_element = " << *it << endl;

  print(v.begin(), v.end(), "nth_element");

  string f = original[rand() % original.size()];

  cout << "binary search: "

    << binary_search(v.begin(), v.end(), f)

    << endl;

  sort(v.begin(), v.end());

  it = lower_bound(v.begin(), v.end(), f);

  it2 = upper_bound(v.begin(), v.end(), f);

  print(it, it2, "found range");

  pair ip =

    equal_range(v.begin(), v.end(), f);

  print(ip.first, ip.second,

    "equal_range");

} ///:~


This example uses the NString class seen earlier, which stores an occurrence number with copies of a string. The call to stable_sort( ) shows how the original order for objects with equal strings is preserved. You can also see what happens during a partial sort (the remaining unsorted elements are in no particular order). There is no "partial stable sort.".

Notice in the call to nth_element( ) that, whatever the nth element turns out to be (which will vary from one run to another because of URandGen), the elements before that are less, and after that are greater, but the elements have no particular order other than that. Because of URandGen, there are no duplicates, but if you use a generator that allows duplicates, you’ll see that the elements before the nth element will be less than or equal to the nth element.

This example also illustrates all three binary search algorithms. As advertised, lower_bound( ) refers to the first element in the sequence equal to a given key, upper_bound( ) points one past the last, and equal_range( ) returns both results as a pair.

Merging sorted ranges

As before, the first form of each function assumes the intrinsic operator< performs the sort. The second form must be used if some other comparison function object performs the sort. You must use the same comparison for locating elements as you do to perform the sort; otherwise, the results are undefined. In addition, if you try to use these functions on unsorted ranges, the results will be undefined.

OutputIterator merge(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); OutputIterator merge(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, StrictWeakOrdering binary_pred);

Copies elements from [first1, last1) and [first2, last2) into result, such that the resulting range is sorted in ascending order. This is a stable operation.

void inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last); void inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, StrictWeakOrdering binary_pred);

This assumes that [first, middle) and [middle, last) are each sorted ranges in the same sequence. The two ranges are merged so that the resulting range [first, last) contains the combined ranges in sorted order.

Example

It’s easier to see what goes on with merging if ints are used; the following example also emphasizes how the algorithms (and our own print template) work with arrays as well as containers.

//: C06:MergeTest.cpp

// Test merging in sorted ranges

#include

#include "PrintSequence.h"

#include "Generators.h"

using namespace std;


int main() {

  const int sz = 15;

  int a[sz*2] = {0};

  // Both ranges go in the same array:

  generate(a, a + sz, SkipGen(0, 2));

  a[3] = 4;

  a[4] = 4;

  generate(a + sz, a + sz*2, SkipGen(1, 3));

  print(a, a + sz, "range1", " ");

  print(a + sz, a + sz*2, "range2", " ");

  int b[sz*2] = {0}; // Initialize all to zero

  merge(a, a + sz, a + sz, a + sz*2, b);

  print(b, b + sz*2, "merge", " ");

  // Reset b

  for(int i = 0; i < sz*2; i++)

    b[i] = 0;

  inplace_merge(a, a + sz, a + sz*2);

  print(a, a + sz*2, "inplace_merge", " ");

  int* end = set_union(a, a + sz, a + sz, a + sz*2, b);

  print(b, end, "set_union", " ");

} ///:~


In main( ), instead of creating two separate arrays, both ranges are created end to end in the same array a. (This will come in handy for the inplace_merge.) The first call to merge( ) places the result in a different array, b. For comparison, set_union( ) is also called, which has the same signature and similar behavior, except that it removes duplicates from the second set. Finally, inplace_merge( ) combines both parts of a.

Перейти на страницу:

Похожие книги

3ds Max 2008
3ds Max 2008

Одни уверены, что нет лучшего способа обучения 3ds Мах, чем прочитать хорошую книгу. Другие склоняются к тому, что эффективнее учиться у преподавателя, который показывает, что и как нужно делать. Данное издание объединяет оба подхода. Его цель – сделать освоение 3ds Мах 2008 максимально быстрым и результативным. Часто после изучения книги у читателя возникают вопросы, почему не получился тот или иной пример. Видеокурс – это гарантия, что такие вопросы не возникнут: ведь автор не только рассказывает, но и показывает, как нужно работать в 3ds Мах.В отличие от большинства интерактивных курсов, где работа в 3ds Мах иллюстрируется на кубиках-шариках, данный видеокурс полностью практический. Все приемы работы с инструментами 3ds Мах 2008 показаны на конкретных примерах, благодаря чему после просмотра курса читатель сможет самостоятельно выполнять даже сложные проекты.

Владимир Антонович Верстак , Владимир Верстак

Программирование, программы, базы данных / Программное обеспечение / Книги по IT