泛型算法:generic algorithm

Abstract

  泛型算法:generic algorithm。

Introduction

  C++ primer P336

//********************************************************************
/*(C) Do what you can, with what you have, where you are. 
Flie	: generic_algorithm.cpp
Path	: D:\on the way to C++\0816_generic algorithm
Author	: Yung
E-mail	: softpart@126.com
Date	: 2013/8/17 13:40
Comment	: 泛型算法:generic algorithm  C++ primer P336
*///******************************************************************
#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
#include <numeric>
#include <time.h>
#include <string>
#include <iterator>
#include <functional>
using namespace std;

#define  MAX 100;
int main()
{
	//1、泛型算法:实现共同的操作;可以操作在多种容器上,包括内置数组以及其他类型(string)
	//P338  生成100个随机数存入vector中,然后使用count
	srand((unsigned)time(NULL)); //#include <time.h>
	
	vector<int> ivec;

	for (int i = 0; i < 100; i++)
	{
		int iv =  rand() % MAX ;
		ivec.push_back(iv);	
	}

	cout << "Size:" << ivec.size() << endl;

	int num_ivec = count(ivec.begin(), ivec.end(), 23);
	cout << "Num_ivec:" << num_ivec << endl;

	//使用泛型算法需要包含头文件:#include <algorithm>
	//泛化的算法: #include<numeric>

	int sum_ivec = accumulate(ivec.begin(), ivec.end(), 0);
	cout << "Sum_ivec:" << sum_ivec << endl;

	int sum1_ivec = accumulate(ivec.begin(), ivec.end(), 10);
	cout << "Sum1_ivec:" << sum1_ivec << endl;
	
	//2、只读算法:读取范围内的元素,而不会写这些元素,其中一个find算法
	//另外一个简单算法为accumulate算法
	//对于int返回数据:第三个参数(起始值)+范围内元素之和
	//那么对于string类型呢
	//eg:

	string s[] = {"s","t","i","n","g"};
	
	vector<string> svec(s,s+sizeof(s)/sizeof(string));
	
	void display_svec(const string &s);
	for_each(svec.begin(), svec.end(), display_svec);

	//下面是错误的
	//int sum_svec = accumulate(svec.begin(), svec.end(), 1);
	//cout << "Sum_svec:" << sum_svec << endl;
	
	string sum_svec = accumulate(svec.begin(), svec.end(), string("look "));
	//其实从这里可以看出,初始值为第三个参数
	cout << "Sum_svec:" << sum_svec << endl;

	//find_first_of()函数

	vector<int> ivec2 = ivec;

	int ia[] = {22,34,14,23};

	vector<int>::iterator iter_ivec2 = ivec2.begin();
	int cnt_ia = 0;
	while ((iter_ivec2 = find_first_of(iter_ivec2, ivec2.end(), ia, ia + sizeof(ia)/sizeof(int))) != ivec2.end())
	{
		cnt_ia++;
		++iter_ivec2;
	}
	cout << "The same: " << cnt_ia << endl;
	//这个是什么意思呢?
	//find_first_of需要提供两段元素范围a,b
	//在a中查找是否有元素和b中的任意一元素相匹配。若有相同返回第一个匹配的元素,反正返回end
	//针对上述代码:要求两段范围a,b内的元素类型精确匹配,至于a和b的类型不做要求

	//3、写算法
	//一些算法写入元素值,在使用这些元素时候需要当心,必须确保算法所写的序列至少足以存储要写入的元素

	//写入输入序列的元素
	//fill
	vector<int> ivec_fill;
	srand((unsigned)time(NULL));
	for (int i = 0; i != 100; i++)
	{
		int ifill = rand() % MAX;
		ivec_fill.push_back(ifill);
	}

	fill(ivec_fill.begin(), ivec_fill.begin() + ivec_fill.size()/2,22);

	void display_fill(const int &a );
	for_each(ivec_fill.begin(), ivec_fill.end(), display_fill);
	//将范围内的每个元素都填充为第三个参数==>范围为有效范围

	//vector<int> ivec_fill1;
	//cout << "capacity:" << ivec_fill1.capacity() << endl;
	//ivec_fill1.reserve(50);
	//
	//cout << "capacity:" << ivec_fill1.capacity() << endl;

	//fill(ivec_fill1.begin(), ivec_fill1.end(), 11);
	//for_each(ivec_fill1.begin(), ivec_fill1.end(), display_fill);
	
	//fill_n:不检查目标的大小是否足以储存要写入的元素

	vector<int> ivec_fill_n;
	srand((unsigned)time(NULL));
	for (int i = 0; i != 100; i++)
	{
		int ifill = rand() % MAX;
		ivec_fill_n.push_back(ifill);
	}
	
	//fill_n(ivec_fill_n.end(),2,2); //这是有错误的
	fill_n(ivec_fill_n.begin(),ivec_fill_n.size() / 2,2);
	for_each(ivec_fill_n.begin(), ivec_fill_n.end(),display_fill);
	
	//4、插入迭代器
	//通常用迭代器给容器赋值,被赋值的是迭代器所指向的元素(存在),而使用插入迭代器则是会在容器中添加一个新元素
	//back_inserter
	vector<int> ivec_in;
	fill_n(back_inserter(ivec_in), 10, 10);
	cout << "back_inserter:" << endl;
	for_each(ivec_in.begin(), ivec_in.end(), display_fill);

	//5、copy
	list<int> lst;
	vector<int> ivec_lst;
	copy(lst.begin(), lst.end(), back_inserter(ivec_lst));
	//效率不好
	//可以这样初始化
	vector<int> ivec_lst2(lst.begin(), lst.end());

	//replace : 将序列中特定的值替换为新的值
	int ia_copy[] = {1,2,3,5,1,4,1,1,1,1,1,1};
	vector<int> ivec_copy(ia_copy, ia_copy + sizeof(ia_copy) / sizeof(int));
	replace(ivec_copy.begin(), ivec_copy.end(), 1, 13);
	//把数值为1的替换成13
	cout << "Copy:" << endl;
	for_each(ivec_copy.begin(), ivec_copy.end(), display_fill);

	list<int> lst_copy;

	//replace_copy
	replace_copy(ivec_copy.begin(), ivec_copy.end(), back_inserter(lst_copy), 13, 88);
	//原本ivec_copy元素不变,lst_copy是ivec_copy的一个副本,并且元素为13的都替换为88

	cout << "LST:" << endl;
	for_each(lst_copy.begin(), lst_copy.end(), display_fill);
	cout << "VEC:" << endl;
	for_each(ivec_copy.begin(), ivec_copy.end(), display_fill);
	
	//P400
	void find_words();
	find_words();

	//迭代器
	void about_iter();
	about_iter();
	
	//五种迭代器

	//
	return 0;
}

//迭代器
void about_iter()
{
	//在 #include <iterator> 头文件中定义了如下迭代器
	//1、插入迭代器:insert iterator 迭代器与容器绑定在一起,实现在容器中插入元素
	//2、iostream迭代器:iostream iterator 迭代器与输入输出流绑定在一起,用于迭代遍历所有关联的IO流
	//3、反向迭代器: reverse iterator 迭代器实现向后遍历,而不是向前遍历,所有容器都定义了reverse_iterator类型,由rbegin和rend成员函数返回

	//const_iterator容器

	//1、插入迭代器
	//(1)back_inserter 创建使用push_back实现插入
	//(2)front_inserter 使用push_front实现插入 只有容器提供push_front操作才能使用front_inserter,vecter不可以用
	//(3)inserter 使用insert实现插入 将产生在指定位置实现插入的迭代器

	vector<int> ivec;
	for (int i = 10; i < 20; i++)
		ivec.push_back(i);
	
	list<int> ilst;

	for (int i = 0; i < 10; i++)
		ilst.push_back(i);
	
	list<int>::iterator iter = find(ilst.begin(), ilst.end(), 3);
	replace_copy(ivec.begin(), ivec.end(), inserter(ilst, iter), 13, 100);
	//其作用?

	cout << "Size:" << ivec.size() << endl;
	cout << "Size2:" << ilst.size() << endl;
	
	for (vector<int>::iterator i = ivec.begin(); i != ivec.end(); i++)
		cout << " " << *i ;
	cout << endl;
	for (list<int>::iterator i = ilst.begin(); i != ilst.end(); i++)
		cout << " " << *i ;

	//2、iostream迭代器
	//istream_iterator 用于读取输入流; ostream_iterator用于写输出流

	cout << endl;
	//istream_iterator<int> cin_it(cin);
	//istream_iterator<int> end_of_stream;

	//vector<int> vec(cin_it, end_of_stream);

	//sort(vec.begin(), vec.end());

	//ostream_iterator<int> output(cout, " ");
	//unique_copy(vec.begin(), vec.end(), output);

	//3、反向迭代器
	//反向迭代器是一种反向遍历的迭代器。对于反向迭代器,++运算将访问前一个元素,--运算则是访问的是下一个元素
	vector<int> rvec;
	//逆序输出
	for (vector<int>::size_type i = 0; i != 10; ++i)
	rvec.push_back(i);
	vector<int>::reverse_iterator riter;
	for(riter = rvec.rbegin(); riter != rvec.rend(); riter++)
		cout << "r:" << *riter << endl;
	
	vector<int> rvec2;
	srand((unsigned)time(NULL));
	for (int i = 0; i < 10; i++)
	{
		int a =  rand() / MAX;
		rvec2.push_back(a);
	}

	//升序排列
	sort(rvec2.begin(), rvec2.end());
	cout << "升序排列:" << endl;
	for(vector<int>::iterator iter = rvec2.begin(); iter != rvec2.end(); iter++)
		cout << "R:" << *iter << endl;

	//降序排列
	sort(rvec2.rbegin(), rvec2.rend());
	cout << "降序排列:" << endl;
	for(vector<int>::iterator iter = rvec2.begin(); iter != rvec2.end(); iter++)
		cout << "R:" << *iter << endl;
}

void find_words()
{
	string str[] = {"the", "quick", "red", "fox", "jumps", "over", "the", "slow","red", "turtle"};
	vector<string> vstr(str, str + sizeof(str)/sizeof(string));

	//sort 排序 字典 规则
	//cout << "size:" << vstr.size() << endl; 
	sort(vstr.begin(), vstr.end());
	void display_string(const string &s);
	//cout << "String:" << endl;
	//for_each(vstr.begin(), vstr.end(), display_string);
	//cout << endl;
	//cout << "size:" << vstr.size() << endl;

	//unique
	vector<string>::iterator iter = unique(vstr.begin(), vstr.end());
	//cout << "String2:" << endl;
	//for_each(vstr.begin(), vstr.end(), display_string);
	//cout << endl;
	//cout << "size:" << vstr.size() << endl; //10
	//其实对unique有疑问的,和primer p344上的结果是不一样的,其功能是把相邻的不重复的移动到容器前面(并非把重复的移动到后面)
	//http://bbs.csdn.net/topics/390554845

	//unique的作用其实是返回的迭代器是指向 超出无重复元素的下一位置
	vstr.erase(iter, vstr.end());//至此已经删除了重复的元素
	for_each(vstr.begin(), vstr.end(), display_string);
	cout << endl;
	bool shorter_size(const string &s1, const string &s2);
	bool getsize6(const string &s);

	//stable_sort
	stable_sort(vstr.begin(), vstr.end(), shorter_size);
	for_each(vstr.begin(), vstr.end(), display_string);
	cout << endl;
	vector<string>::size_type cnum = count_if(vstr.begin(), vstr.end(), getsize6);
	cout << "The sum:" << cnum << endl; 
}

bool shorter_size(const string &s1, const string &s2)
{
	return s1.size() < s2.size();
}

bool getsize6(const string &s)
{
	return s.size() >= 6;
}

void display_string(const string &s)
{
	cout << s << " ";
}

void display_svec(const string &s)
{
	cout << "svec:" << s << endl;
}

int fi = 0;
void display_fill(const int &a)
{
	cout << "fill " << ++fi <<":" << a << endl; 
}

  <End>

posted on 2013-08-21 16:50  从此无她不见月  阅读(390)  评论(0)    收藏  举报

导航