《C++面向对象程序设计》课程笔记 lessen8 程序示例

1 程序示例:vector

#include <iostream>
#include <vector>
using namespace std;
template<class T>
void PrintVector(T s, T e)
{
	for(;s!=e;++s)
		cout << *s << " ";
	cout << endl;
}

int main()
{
	int a[5] = {1,2,3,4,5};
	vector<int> v(a,a+5); //将数组a的元素添加到 v 中
	cout << "1) " << v.end() - v.begin() << endl;
	//两个随机迭代器可以相减,输出 1) 5
	cout << "2) ";
	PrintVector(v.begin(),v.end());
	//2) 1 2 3 4 5
	v.insert(v.begin()+2,13); //在v.begin()+2 (v[2])位置插入13
	cout << "3) ";
	PrintVector(v.begin(),v.end());
	//3) 1 2 13 3 4 5
	v.erase(v.begin()+2); //删除位于 v.begin()+2 (v[2])的元素
	cout << "4) ";
	PrintVector(v.begin(),v.end());
	//4) 1 2 3 4 5
	vector<int> v2 (4,100); //v2 有4个元素,都是100
	v2.insert(v2.begin(),v.begin()+1,v.begin()+3);
	//将 v 的一段插入 v2 开头
	cout << "5) v2: ";
	PrintVector(v2.begin(),v2.end());
	//5) v2: 2 3 100 100 100 100
	v.erase(v.begin()+1,v.begin()+3); //删除 v 上的一个区间,即 2 ,3
	cout << "6) ";
	PrintVector(v.begin(),v.end());
	//6) 1 4 5
	system("pause");
	return 0;
}

2 用 vector 实现二维数组

#include <iostream>
#include <vector>
using namespace std;

int main()
{
	vector<vector<int> > v(3); //两个 >> 之间的空格必须要有,不然会被当成是右移符号
	//v 有3个元素,每个元素都是 vector<int> 容器
	for(int i=0;i<v.size();i++)
		for(int j=0;j<4;j++)
			v[i].push_back(j);
	for(int i=0;i<v.size();i++)
	{
		for(int j=0;j<v[i].size();j++)
			cout << v[i][j] << " ";
	    cout << endl;
	}

	system("pause");
	return 0;
}

3 deque

  • 所有使用于 vector 的操作都使用于 deque。
  • deque 还有 push_front (将元素插入到前面)和 pop_front (删除最前面的元素)操作,复杂度是 O(1)。 

4 list 容器

  • 在任何位置插入删除都是常数时间,不支持随机存取。 

除了具有所有顺序容器都有的成员函数之外,还支持8个成员函数:

push_front:在前面插入

pop_front:删除前面的元素

sort:排序(list 不支持 STL 的算法 sort)

remove:删除和指定值相等的所有元素

unique:删除所有和前一个元素相同的元素(要做到元素不重复,则 unique 之前还需要 sort

merge:合并两个链表,并清空被合并的那个

reverse:颠倒链表

splice:在指定位置前面插入另一个链表中的一个或多个元素,并在另一链表中删除被插入的元素。 

#include <iostream>
#include <list>
#include <algorithm>
using namespace std;

class A
{
private:
	int n;
public:
	A(int n_) { n = n_; }
	friend bool operator <(const A & a1, const A & a2);
	friend bool operator ==(const A & a1, const A & a2);
	friend ostream & operator <<(ostream & o, const A & a );
};

bool operator< (const A & a1, const A & a2)
{
	return a1.n < a2.n;
}

bool operator ==(const A & a1, const A & a2)
{
	return a1.n == a2.n;
}

ostream & operator <<(ostream & o, const A & a )
{
	o << a.n;
	return o;
}

template <class T>
void PrintList(const list<T> & lst) //不推荐的写法,还是用两个迭代器作为参数更好
{
	typename list<T>::const_iterator i;
	i = lst.begin();
	for(i=lst.begin();i!=lst.end();i++)
		cout << *i << ",";
	cout << endl;
}//typename 用来说明 list<T>::const_iterator 是个类型。在 vs 中不写也可以。

int main()
{
	list<A> lst1,lst2;
	lst1.push_back(1);
	lst1.push_back(2);
	lst1.push_back(3);
	lst1.push_back(4);
	lst1.push_back(2);
	lst2.push_back(10);
	lst2.push_front(20);
	lst2.push_back(30);
	lst2.push_back(30);
	lst2.push_back(30);
	lst2.push_front(40);
	lst2.push_back(40);
	cout << "1) ";
	PrintList(lst1); //1) 1,2,3,4,2,
	cout << "2) ";
	PrintList(lst2); //2) 40,20,10,30,30,30,40,
	lst2.sort();
	cout << "3) ";
	PrintList(lst2);//3) 10,20,30,30,30,40,40,
	lst2.pop_front();
	cout << "4) ";
	PrintList(lst2); //4) 20,30,30,30,40,40,
	lst1.remove(2);//删除所有和A(2)相等的元素
	cout << "5) ";
	PrintList(lst1); //5) 1,3,4,
	lst2.unique(); //删除所有和前一个元素相等的元素
	cout << "6) ";
	PrintList(lst2); //6) 20,30,40,
	lst1.merge(lst2); //合并 lst2 到 lst1 并清空 lst2
	cout << "7) ";
	PrintList(lst1);//7) 1,3,4,20,30,40,
	cout << "8) ";
	PrintList(lst2); //8) 
	lst1.reverse();
	cout << "9) ";
	PrintList(lst1);//9) 40,30,20,4,3,1,
	lst2.push_back(100);
	lst2.push_back(200);
	lst2.push_back(300);
	lst2.push_back(400);
	list<A>::iterator p1,p2,p3;
	p1 = find(lst1.begin(),lst1.end(),3);
	p2 = find(lst2.begin(),lst2.end(),200);
	p3 = find(lst2.begin(),lst2.end(),400);
	lst1.splice(p1,lst2,p2,p3);
	//将 [p2,p3) 插入 p1 之前,并从 lst2 中删除 [p2,p3)
	cout << "10) ";
	PrintList(lst1); //10) 40,30,20,4,200,300,3,1,
	cout << "11) ";
	PrintList(lst2);//11) 100,400,

	system("pause");
	return 0;
}

 5 函数对象

若一个类重载了运算符 “()” ,则该类的对象就成为函数对象。 

函数对象示例:

#include <iostream>
using namespace std;

class CMyAverage  //函数对象类
{
public:
	double operator () (int a1, int a2, int a3)
	{
		return (double)(a1+a2+a3)/3;
	}
};

int main()
{
	CMyAverage average; //函数对象
	cout << average(3,2,3); // 类似执行了:average.operator()(3,2,3);
	// 输出:2.66667
	system("pause");
	return 0;
}

函数模板的应用示例:

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <functional>
using namespace std;
int sumSquares(int total, int value)
{
	return total + value * value;
}

template <class T>
void PrintInterval(T first, T last)
{//输出区间 [first, last) 中的元素
	for( ;first!=last;++first)
		cout << *first << " ";
	cout << endl;
}

template <class T>
class SumPowers
{
private:
	int power;
public:
	SumPowers(int p):power(p) { }
	const T operator()(const T & total,const T & value)
	{//计算 value 的 power 次方,加到 total 上
		T v = value;
		for(int i=0;i<power-1;++i)
			v = v * value;
		return total + v;
	}
};

int main()
{
	const int SIZE = 10;
	int a1[] = {1,2,3,4,5,6,7,8,9,10};
	vector<int> v(a1,a1+SIZE);
	cout << "1) ";
	PrintInterval(v.begin(),v.end());
	int result = accumulate(v.begin(),v.end(),0,sumSquares); //函数
	cout << "2)平方和:" << result << endl;
	result = accumulate(v.begin(),v.end(),0,SumPowers<int>(3));//函数模板(power=3,total=result,value=*v.begin())
	cout << "3)立方和:" << result << endl;
	result = accumulate(v.begin(),v.end(),0,SumPowers<int>(4)); //函数模板
	cout << "4)4次方和:" << result << endl;
	system("pause");
	return 0;
}
int result = accumulate(v.begin(),v.end(),0,sumSquares); //函数
//这条语句实例化出
int accumulate(vector<int>::iterator first,vector<int>::iterator last,int init,int (*op)(int,int)) //函数指针
{
	for(;first!=last;++first)
		init = op(init,*first);
	return init;
}
int result = accumulate(v.begin(),v.end(),0,SumPowers<int>(3));//函数模板
//实例化出
int accumulate(vector<int>::iterator first,vector<int>::iterator last,int init,SumPowers<int> op) //函数对象
{
	for(;first!=last;++first)
		init = op(init,*first);
	return init;
}
  • 函数对象的优点:比如要使用3次方,4次方,5次方,不用写多个函数,只需要写一个函数模板即可。

STL 中的函数对象模板:(以下模板可以用来生成函数对象)

  • equal_to
  • greater
  • less

头文件:<functional> 

5.1  greater 函数对象类模板

template <class T>
struct greater:public binary_function<T,T,bool>
{
	bool operator()(const T & x, const T & y) const
	{
		return x > y;   // x > y 成立时才返回 true
	}
};

greater 的应用:

list 有两个 sort 成员函数

  • void sort();    //将 list 中的元素按 “<” 规定的比较方法升序排列。
  • template <class Compare>     void sort(Compare op);    // 将 list 中的元素按 op 规定的比较方法升序排列。即要比较x,y大小时,看 op(x,y) 的返回值,为 true 则认为 x 小于 y。(若使用 graeter 函数对象,则此处的“小于”与数学意义上的小于相反。)
#include <iostream>
#include <list>
using namespace std;
class MyLess
{
public:
	bool operator() (const int & c1, const int & c2)
	{
		return (c1 % 10) < (c2 % 10); //谁的个位数小
	}
};
template <class T>
void Print(T first, T last)
{
	for(;first!=last;++first)
		cout << *first << ",";
	cout << endl;
}

int main()
{
	const int SIZE = 5;
	int a[SIZE] = {5,21,14,2,3};
	list<int> lst(a,a+SIZE);
	lst.sort(MyLess());
	Print(lst.begin(),lst.end());
	lst.sort(greater<int>());//greater<int>()是个对象
	Print(lst.begin(),lst.end());

	system("pause");
	return 0;
}

在 STL 中使用自定义的 “大”,“小”关系

关联容器和 STL 中许多算法,都是可以用函数或函数对象自定义比较器的。在自定义了比较器 op 的情况下,以下三种说法是等价的:1)x 小于 y。2)op(x,y) 返回值为 true。3)y 大于 x 。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值