C/C++ 的一些乱七八糟的总结(二) 未完

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;
}

  

posted @ 2011-08-20 00:21  wtx  阅读(423)  评论(0编辑  收藏  举报