364 lines
10 KiB
C++
364 lines
10 KiB
C++
/**************************************************************************
|
|
*
|
|
* alg3.cpp - Sample programs for STL generic algorihtms that modify
|
|
* their arguments in place.
|
|
*
|
|
* $Id: alg3.cpp 550991 2007-06-26 23:58:07Z sebor $
|
|
*
|
|
***************************************************************************
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* permissions and limitations under the License.
|
|
*
|
|
* Copyright 1994-2006 Rogue Wave Software.
|
|
*
|
|
**************************************************************************/
|
|
|
|
#include <algorithm> // for copy(), find(), generate(), ...
|
|
#include <functional> // for greater
|
|
#include <iostream> // for cout
|
|
#include <iterator> // for ostream_iterator
|
|
#include <list> // for list
|
|
#include <string> // for string
|
|
#include <vector> // for vector
|
|
|
|
#include <ctype.h>
|
|
#include <cstring>
|
|
|
|
#include <examples.h>
|
|
|
|
|
|
typedef std::ostream_iterator<int, char, std::char_traits<char> >
|
|
ostrm_iter_type;
|
|
|
|
|
|
struct iotaGenerator
|
|
{
|
|
iotaGenerator (int iv): current (iv) { }
|
|
|
|
int operator () () {
|
|
return current++;
|
|
}
|
|
|
|
private:
|
|
int current;
|
|
};
|
|
|
|
|
|
struct RandomInteger
|
|
{
|
|
static long seq [16];
|
|
|
|
long operator () (long n) const {
|
|
std::random_shuffle (seq, seq + sizeof seq / sizeof *seq);
|
|
|
|
const long rnd =
|
|
(seq [0] << 11) | (seq [1] << 8) | (seq [2] << 4) + seq [3];
|
|
|
|
return rnd % n;
|
|
}
|
|
};
|
|
|
|
long RandomInteger::seq [16] = {
|
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf
|
|
};
|
|
|
|
|
|
bool isEven (int n)
|
|
{
|
|
return 0 == (n % 2);
|
|
}
|
|
|
|
// Illustrate the use of the reverse function.
|
|
void reverse_example ()
|
|
{
|
|
std::cout << "Illustrate std::reverse() algorithm\n";
|
|
|
|
// Example 1, reversing a std::string.
|
|
char text[] = "<Rats live on no evil star>";
|
|
|
|
std::cout << text << '\n';
|
|
|
|
std::reverse (text, text + sizeof text - 1);
|
|
|
|
std::cout << text << '\n';
|
|
|
|
// Example 2, reversing a std::list.
|
|
std::list<int, std::allocator<int> > iList;
|
|
|
|
std::generate_n (std::inserter (iList, iList.begin ()),
|
|
10, iotaGenerator (2));
|
|
|
|
std::copy (iList.begin (), iList.end (),
|
|
ostrm_iter_type (std::cout, " "));
|
|
|
|
std::cout << '\n';
|
|
|
|
std::reverse (iList.begin (), iList.end ());
|
|
std::copy (iList.begin (), iList.end (),
|
|
ostrm_iter_type (std::cout, " "));
|
|
|
|
std::cout << '\n';
|
|
}
|
|
|
|
|
|
// Illustrate the use of the replace function.
|
|
void replace_example ()
|
|
{
|
|
std::cout << "Illustrate std::replace() algorithm\n";
|
|
|
|
// Make std::vector 0 1 2 3 4.
|
|
std::vector<int, std::allocator<int> > numbers (11);
|
|
for (std::size_t i = 0; i < numbers.size (); i++)
|
|
numbers [i] = int (i < 5U ? i : 10U - i);
|
|
|
|
std::copy (numbers.begin (), numbers.end (),
|
|
ostrm_iter_type (std::cout, " "));
|
|
|
|
std::cout << '\n';
|
|
|
|
// Replace 0 by 2.
|
|
std::replace (numbers.begin (), numbers.end (), 3, 7);
|
|
std::copy (numbers.begin (), numbers.end (),
|
|
ostrm_iter_type (std::cout, " "));
|
|
|
|
std::cout << '\n';
|
|
|
|
// Replace even numbers by 9.
|
|
std::replace_if (numbers.begin (),
|
|
numbers.end (), isEven, 9);
|
|
|
|
std::copy (numbers.begin (), numbers.end (),
|
|
ostrm_iter_type (std::cout, " "));
|
|
|
|
std::cout << '\n';
|
|
|
|
// Copy into a std::list, replastd::cing 9 by 3.
|
|
int aList[] = { 2, 1, 4, 3, 2, 5 };
|
|
int bList[6];
|
|
int cList[6];
|
|
|
|
std::replace_copy (aList, aList+6, &bList[0], 2, 7);
|
|
std::replace_copy_if (bList, bList+6, &cList[0],
|
|
std::bind2nd (std::greater<int> (), 3), 8);
|
|
|
|
std::copy (bList, bList + 6, ostrm_iter_type (std::cout, " "));
|
|
std::cout << '\n';
|
|
|
|
std::copy (cList, cList + 6, ostrm_iter_type (std::cout, " "));
|
|
std::cout << '\n';
|
|
}
|
|
|
|
|
|
// Illustrate the use of the rotate function.
|
|
void rotate_example ()
|
|
{
|
|
std::cout << "Illustrate std::rotate() algorithm\n";
|
|
|
|
// Create the std::list 1 2 3 ... 10
|
|
std::list<int, std::allocator<int> > iList;
|
|
std::generate_n (std::inserter (iList, iList.begin ()),
|
|
10, iotaGenerator (1));
|
|
|
|
// Find the location of the seven.
|
|
std::list<int, std::allocator<int> >::iterator
|
|
middle = std::find (iList.begin (), iList.end (), 7);
|
|
|
|
// Now rotate around that location.
|
|
std::rotate (iList.begin (), middle, iList.end ());
|
|
std::copy (iList.begin (), iList.end (),
|
|
ostrm_iter_type (std::cout, " "));
|
|
|
|
std::cout << '\n';
|
|
|
|
// Rotate again around the same location.
|
|
std::list<int, std::allocator<int> > cList;
|
|
|
|
std::rotate_copy (iList.begin (), middle, iList.end (),
|
|
std::inserter (cList, cList.begin ()));
|
|
std::copy (cList.begin (), cList.end (),
|
|
ostrm_iter_type (std::cout, " "));
|
|
|
|
std::cout << '\n';
|
|
}
|
|
|
|
|
|
// Illustrate the use of the paration function.
|
|
void partition_example ()
|
|
{
|
|
std::cout << "Illustrate std::partition() algorithm\n";
|
|
|
|
// First make the std::vector 1 2 3 ... 10.
|
|
std::vector<int, std::allocator<int> > numbers (10);
|
|
|
|
std::generate (numbers.begin (),
|
|
numbers.end (), iotaGenerator (1));
|
|
|
|
// Now put the odd values low, even values high.
|
|
std::vector<int, std::allocator<int> >::iterator
|
|
result = std::partition (numbers.begin (), numbers.end (),
|
|
isEven);
|
|
|
|
std::copy (numbers.begin (), numbers.end (),
|
|
ostrm_iter_type (std::cout, " "));
|
|
|
|
std::cout << "\nmiddle location " << result - numbers.begin () << '\n';
|
|
|
|
// Now do a stable partition.
|
|
std::generate (numbers.begin (),
|
|
numbers.end (), iotaGenerator (1));
|
|
|
|
std::copy (numbers.begin (), numbers.end (),
|
|
ostrm_iter_type (std::cout, " "));
|
|
|
|
std::cout << '\n';
|
|
}
|
|
|
|
|
|
bool nameCompare (const char *a, const char *b)
|
|
{
|
|
return std::strcmp (a, b) <= 0;
|
|
}
|
|
|
|
|
|
// Illustrate the use of the next_permutation function.
|
|
void permutation_example ()
|
|
{
|
|
std::cout << "Illustrate std::next_permutation() algorithm\n";
|
|
|
|
// Start with the values 1 2 3 in sequence.
|
|
int start [] = { 1, 2, 3 };
|
|
|
|
do {
|
|
std::copy (start, start + 3, ostrm_iter_type (std::cout, " "));
|
|
std::cout << '\n';
|
|
} while (std::next_permutation (start, start + 3));
|
|
|
|
const char alpha[] = "Alpha";
|
|
const char beta[] = "Beta";
|
|
const char gamma[] = "Gamma";
|
|
|
|
const char* names[] = { alpha, beta, gamma };
|
|
|
|
typedef std::ostream_iterator<const char*, char, std::char_traits<char> >
|
|
Iter;
|
|
|
|
do {
|
|
std::copy (names, names + 3, Iter (std::cout, " "));
|
|
std::cout << '\n';
|
|
} while (std::next_permutation (names, names + 3, nameCompare));
|
|
|
|
std::cout << "Illustrate std::prev_permutation() algorithm\n";
|
|
|
|
char word[] = "bela";
|
|
|
|
do
|
|
std::cout << word << ' ';
|
|
while (std::prev_permutation (word, &word[4]));
|
|
|
|
std::cout << '\n';
|
|
}
|
|
|
|
|
|
// Illustrate the use of the inplace_merge function.
|
|
void inplace_merge_example ()
|
|
{
|
|
std::cout << "Illustrate std::inplace_merge() algorithm\n";
|
|
|
|
// First generate the numbers 0 2 4 6 8 1 3 5 7 9.
|
|
std::vector<int, std::allocator<int> > numbers (10);
|
|
|
|
for (std::size_t i = 0; i < numbers.size (); i++)
|
|
numbers [i] = int (i < 5U ? 2U * i : 2U * (i - 5U) + 1U);
|
|
|
|
std::copy (numbers.begin (), numbers.end (),
|
|
ostrm_iter_type (std::cout, " "));
|
|
std::cout << '\n';
|
|
|
|
std::vector<int, std::allocator<int> >::iterator
|
|
midvec = std::find (numbers.begin (), numbers.end (), 1);
|
|
|
|
// Copy them into a std::list.
|
|
std::list<int, std::allocator<int> > numList;
|
|
std::copy (numbers.begin (), numbers.end (),
|
|
std::inserter (numList, numList.begin ()));
|
|
|
|
std::list<int, std::allocator<int> >::iterator
|
|
midList = std::find (numList.begin (), numList.end (), 1);
|
|
std::copy (numList.begin (), numList.end (),
|
|
ostrm_iter_type (std::cout, " "));
|
|
|
|
std::cout << '\n';
|
|
|
|
// Now put them back together.
|
|
std::inplace_merge (numbers.begin (), midvec, numbers.end ());
|
|
std::inplace_merge (numList.begin (), midList, numList.end ());
|
|
std::copy (numList.begin (), numList.end (),
|
|
ostrm_iter_type (std::cout, " "));
|
|
|
|
std::cout << '\n';
|
|
}
|
|
|
|
|
|
// Illustrate the use of the random_shuffle function.
|
|
void random_shuffle_example ()
|
|
{
|
|
std::cout << "Illustrate std::generate() algorithm\n";
|
|
|
|
// First make the std::vector 1 2 3 ... 10.
|
|
std::vector<int, std::allocator<int> > numbers (10);
|
|
|
|
std::generate (numbers.begin (),
|
|
numbers.end (), iotaGenerator (1));
|
|
std::copy (numbers.begin (), numbers.end (),
|
|
ostrm_iter_type (std::cout, " "));
|
|
|
|
std::cout << "\nIllustrate std::random_shuffle() algorithm\n";
|
|
|
|
// Randomly shuffle the elements.
|
|
RandomInteger rnd;
|
|
std::random_shuffle (numbers.begin (), numbers.end (), rnd);
|
|
std::copy (numbers.begin (), numbers.end (),
|
|
ostrm_iter_type (std::cout, " "));
|
|
|
|
std::cout << '\n';
|
|
|
|
// Do it again.
|
|
std::random_shuffle (numbers.begin (), numbers.end (), rnd);
|
|
std::copy (numbers.begin (), numbers.end (),
|
|
ostrm_iter_type (std::cout, " "));
|
|
|
|
std::cout << '\n';
|
|
}
|
|
|
|
|
|
int main ()
|
|
{
|
|
std::cout << "STL generic algorithms -- in-place algorithms\n";
|
|
|
|
reverse_example ();
|
|
replace_example ();
|
|
rotate_example ();
|
|
partition_example ();
|
|
permutation_example ();
|
|
inplace_merge_example ();
|
|
random_shuffle_example ();
|
|
|
|
std::cout << "End of in-place algorithm sample program\n";
|
|
|
|
return 0;
|
|
}
|