1. 模板
模板分类模板和函数模板,其中函数模板是一个通用的函数,其参数类型和返回类型不具体指定,类模板类似,建立一个通用类,其数据成员的类型、成员函数的返回类型和参数类型都不具体指定,用一个虚拟类型来代表。
1 #include <iostream>
2
3 using namespace std;
4 //函数模板
5 template <class T>
6 T cmin(T m,T n)
7 {
8 return ( m<n) ? m : n;
9 }
10 int main()
11 {
12 int n1 = 2;
13 int n2 = 10;
14 double d1 = 1.0;
15 double d2 = 2.0;
16 cout << "n1,n2中最小的是:" << cmin(n1,n2) << endl;
17 cout << "d1 d2中最小的是:" << cmin(d1,d2) << endl;
18 return 0;
19 }
1 #include <iostream>
2
3 using namespace std;
4
5 //模板类
6 template <class T1,class T2>
7 class MyClass
8 {
9 private:
10 T1 i;
11 T2 j;
12 public :
13 MyClass(T1 a,T2 b);
14 void show();
15 };
16
17 template <class T1,class T2>
18 MyClass<T1,T2>::MyClass(T1 a,T2 b):i(a),j(b){}
19
20 template<class T1,class T2>
21 void MyClass<T1,T2>::show()
22 {
23 cout << "i = " << i << ",j = " << j << endl;
24 }
25 int main()
26 {
27 MyClass<int,int> class1(3,5);
28 class1.show();
29 MyClass<int,char> class2(3,'a');
30 class2.show();
31 return 0;
32 }
非类型模板
#include <iostream>
using namespace std;
//非类型模板参数
//非类型模板参数可以是常整数(包括枚举)或者指向外部链接对象的指针
//浮点数是不行的,指向内部链接对象的指针是不行的
template <class T,int MAXSIZE>
class Stack
{
private:
T elems[MAXSIZE];
public:
Stack();
void show();
};
template<class T,int MAXSIZE>
Stack<T,MAXSIZE>::Stack()
{
for(int i = 0;i < MAXSIZE;i ++)
elems[i] = i;
}
template<class T,int MAXSIZE>
void Stack<T,MAXSIZE>::show()
{
for(int i = 0;i < MAXSIZE;i ++)
cout << elems[i] << " ";
cout << endl;
}
int main()
{
Stack<int,20> int20Stack;
int20Stack.show();
cout << "=======================" << endl;
Stack<int,40> int40Stack;
int40Stack.show();
return 0;
}
2 STL中全排列的函数 next_permutation prev_permutation
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int arr[] = {1, 2, 3};
do
//next_permutation得到的是所以的全排列,
//如果原序列是从最小字典排列的
{
std::cout<<arr[0]<<" "<<arr[1]<<" "<<arr[2]<<std::endl;
} while (next_permutation(arr, arr + 3));
cout << "==============================" << endl;
//prev_permutation与next_permutation相反,
//由原排列得到字典序中上一次最近排列。
int a[] = {3,2,1};
do
{
cout << a[0] << " " << a[1] << " " << a[2] << endl;
}
while (prev_permutation(a,a+3));
return 0;
}
其中 next_permutation()是用模板实现的,线面给出一个int版本的实现(参考源码)
#include <iostream>
#include <algorithm>
using namespace std;
bool myNext_permutation(int *frist,int *last)
{
if(frist == last)
return false;
int *i = frist;
++i;
if(i == last)
return false;
i = last;
--i;
for(;;)
{
//j是i的上一个元素
int *j = i;
--i;
if(*i < *j)
{
int *k = last;
while(!(*i < *--k));
std::iter_swap(i,k);
std::reverse(j,last);
return true;
}
if(i == frist)
{
std::reverse(frist,last);
return false;
}
}
}
int main()
{
int arr[] = {1,2,3};
do
{
cout << arr[0] << " " << arr[1] << " " << arr[2] << endl;
}while(myNext_permutation(arr,arr+3));
return 0;
}
过程参考自:
算法描述:
1、从尾部开始往前寻找两个相邻的元素
第1个元素i,第2个元素j(从前往后数的),且i<j
2、再从尾往前找第一个大于i的元素k。将i、k对调
3、[j,last)范围的元素置逆(颠倒排列)
运行过程:
next: 01234
-> i=3,j=4
-> k=4,对调后01243
-> j指向最后一个元素,故结果为01243
next: 01243
-> i=2,j=4
-> k=3,对调后01342
-> j指向4,颠倒后为01324 即结果
...
next: 01432
-> i=1,j=4
-> k=2,对调后02431
-> j指向4,颠倒02134
按默认字典序的内部实现(带仿函数的类似):
#include <algorithm>
#include <iostream>
template<typename BidirectionalIterator>
bool next_permutation(BidirectionalIterator first, BidirectionalIterator last)
{
// 空区间
if(first == last)
return false;
BidirectionalIterator i = first;
++i;
// 只有一个元素
if(i == last)
return false;
// i指向尾部
i = last;
--i;
for (;;)
{
// i是j的上一个元素
BidirectionalIterator j = i;
--i;
if(*i < *j)
{
// 由尾部往前找到第一个比*i大的元素,并交换i,k
BidirectionalIterator k = last;
while(!(*i < *--k))
;
std::iter_swap(i, k);
// 将[j,last)的元素逆向重排
std::reverse(j, last);
return true;
}
// 到最前面了
if(i == first)
{
std::reverse(first, last);
return false;
}
}
}
3.一道函数参数传递问题
#include <iostream> #include <vector> // http://www.cnblogs.com/AnnieKim/archive/2011/05/16/2048062.html using namespace std; void out(char *ch,int i) { cout << ch << "," << endl; } int main() { vector<char *> vec; vec.push_back("str1"); vec.push_back("str2"); int i = 0; cout << "=======begin============";
//这里输出的时候,使用out(vec[i],i ++)胡出现异常,因为函数调用的参数是从右向左压入堆栈中的,所以,先压入i,然后是i++,最后才是vec[i],会出现越界访问 while(i < vec.size()) { out(vec[i], i); i ++; } cout << "=======begin============"; return 0; }