//algostuff.hpp头文件,以下程序都用此头文件。
/*********头文件开始**********/
#ifndef ALGOSTUFF_HPP
#define ALGOSTUFF_HPP
#include <iostream>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <string>
#include <algorithm>
#include <functional>
#include <numeric>
/* PRINT_ELEMENTS()
*- print optional C-string optcstr followed by
*- all elements of the collection coll
*- separated by spaces
*/
template <class T>
inline void PRINT_ELEMENTS (const T& coll, const char* optcstr = "")
{
typename T::const_iterator pos;
std::cout << optcstr;
for (pos = coll.begin(); pos != coll.end(); ++pos)
{
std::cout << *pos << ' ';
}
std::cout << std::endl;
}
/* INSERT_ELEMENTS(collection, first, last)
* - fill values from first to last into the collection
* - NOTE: NO half-open range
*/
template <class T>
inline void INSERT_ELEMENTS(T &coll, int first, int last)
{
for (int i = first; i <= last; ++i)
{
coll.insert(coll.end(), i);
}
}
#endif /*ALGOSTUFF_HPP*/
/*********头文件结束************/
/* for_each()事例程序
* - 程序输出:
1 2 3 4 5 6 7 8 9
* - 总结:
* - for_each()算法前两个参数传入的必须是指针(迭代器是一种智能指针,当传入的非迭代器时,
* - 语法没问题,但要考虑边界和安全问题)。此算法可以有返回值,返回值类型和所调函数的返回值
* - 是同一类型。所调函数可以有两种传递方式:值传递和引用传递。所以,此算法即可以读数据也
* - 可以写数据,就看所调函数的传递方式。如:void print (int &elem)此定义,就可写数据。
*/
#include "algostuff.hpp"
using namespace std;
void print (int elem)
{
cout << elem << ' ';
}
int main()
{
vector<int> coll;
INSERT_ELEMENTS(coll, 1, 9);
for_each(coll.begin(), coll.end(), print);
cout << endl;
getchar();
}
/* for_each()调用仿函数事例程序
* - 程序输出:
11 12 13 14 15 16 17 18 19
22 23 24 25 26 27 28 29 30
32 23 24 25 26 27 28 29 30
* - 总结:
* - const 修饰函数,在函数体中可修改传进来的参数,但不能修改外部定义的数据。
* - for_each(coll.begin(), coll.end(), AddValue<int>(10));
* - 执行过程:先是AddValue类构造对象,调用构造函数,把10传进theValue。
* - 之后,for_each语句逐个迭代器调用AddValue<int>(10)(*coll.begin());
* - 使用仿函数的好处是,你可以在执行期间传入欲加入的数值。
*/
#include "algostuff.hpp"
using namespace std;
template <class T>
class AddValue
{
private:
T theValue;
public:
AddValue(const T &v) : theValue(v)
{
}
void operator() (T &elem) const
{
elem += theValue;
}
};
int main()
{
vector<int> coll;
INSERT_ELEMENTS(coll, 1, 9);
for_each(coll.begin(), coll.end(), AddValue<int>(10));
PRINT_ELEMENTS(coll);
for_each(coll.begin(), coll.end(), AddValue<int>(*coll.begin()));
PRINT_ELEMENTS(coll);
//自己添加的语句,想知道仿函数是如何传参数的
AddValue<int>(10)(*coll.begin());
PRINT_ELEMENTS(coll);
getchar();
}
/* for_each()返回值的使用事例程序
* - 程序输出:
mean value: 4.5
* - 总结:
* - operator double();语句重载了double操作符。
* - 而double mv = for_each (coll.begin(), coll.end(), MeanValue());
* - 发生类型转换MeanValue转换成double,调用自定义的类型转换
* - 返回一个double型数据。
*/
#include "algostuff.hpp"
using namespace std;
class MeanValue
{
private:
long num;
long sum;
public:
MeanValue() : num(0), sum(0)
{
}
void operator() (int elem)
{
num++;
sum += elem;
}
operator double()
{
return static_cast<double>(sum) / static_cast<double>(num);
}
};
int main()
{
vector<int> coll;
INSERT_ELEMENTS(coll, 1, 8);
double mv = for_each (coll.begin(), coll.end(), MeanValue());
cout << "mean value: " << mv << endl;
getchar();
}
/* 操作符<<重载事例程序
* - 输出:
mean value: 4.5
* - 用<<重载来实现上个输出。
*/
#include "algostuff.hpp"
using namespace std;
class MeanValue
{
private:
long num;
long sum;
public:
MeanValue() : num(0), sum(0)
{
}
void operator() (int elem)
{
num++;
sum += elem;
}
friend ostream &operator<< (ostream &stream, MeanValue o);
};
ostream &operator<< (ostream &stream, MeanValue o)
{
double result = static_cast<double>(o.sum) / static_cast<double>(o.num);
stream << result << endl;
return stream;
}
int main()
{
vector<int> coll;
INSERT_ELEMENTS(coll, 1, 8);
MeanValue mv = for_each (coll.begin(), coll.end(), MeanValue());
cout << "mean value: " << mv ;
getchar();
}
/* count_if()事例程序
* - 程序输出:
coll: 1 2 3 4 5 6 7 8 9
number of elements equal to 4: 1
number of elements with even value: 4
number of elements greater than 4: 5
*/
#include "algostuff.hpp"
using namespace std;
bool isEven(int elem)
{
return elem % 2 == 0;
}
int main()
{
vector<int> coll;
int num;
INSERT_ELEMENTS(coll, 1, 9);
PRINT_ELEMENTS(coll, "coll: ");
num = count(coll.begin(), coll.end(), 4);
cout << "number of elements equal to 4: " << num << endl;
num = count_if(coll.begin(), coll.end(), isEven);
cout << "number of elements with even value: " << num << endl;
num = count_if(coll.begin(), coll.end(), bind2nd(greater<int>(), 4));
cout << "number of elements greater than 4: " << num << endl;
getchar();
}
/* copy()和copy_backward()事例程序
* - 程序输出:
source: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
c1: 0 1 2 3 4 5 6 7 7 8 9 10 11 12 14 15 16 17
c2: 0 1 2 3 7 8 9 10 11 12 10 11 12 13 14 15 16 17
* - 两者均可对源范围进行一定的覆盖,但可能会出现迭代器失效。
* - 在此程序中不会出现失效,是因为此程序中的begin()迭代器没有失效,
* - 其他的都是此迭代器的偏移量。
*/
#include "algostuff.hpp"
using namespace std;
int main()
{
vector<int> source;
for (int c = 0; c <= 17; c++)
{
source.push_back(c);
}
PRINT_ELEMENTS(source, "source: ");
vector<int> c1(source.begin(), source.end());
copy(c1.begin() + 7, c1.begin() + 13, c1.begin() + 8);
PRINT_ELEMENTS(c1, "c1: ");
vector<int> c2(source.begin(), source.end());
copy_backward(c2.begin() + 7, c2.begin() + 13, c2.begin() + 10);
PRINT_ELEMENTS(c2, "c2: ");
getchar();
}