您的位置:首页 > 其它

算法竞赛入门经典习题与解答-第一章

2018-02-04 01:13 441 查看
1.1.1 排序性能问题

 C语言的函数qsort,C++中的sort(直接传入排序函数)以及传入functor对象的sort函数代码以及时间。

#include<bits/stdc++.h>
using namespace std;
#define _for(i,a,b) for( int i=(a); i<(b); ++i)
const int N = 10000000;
struct TS{
int a,b,c;
};
inline bool cmp (const TS&t1, const TS&t2){
if(t1.a!=t2.a)return t1.a<t2.a;
if(t1.b!=t2.b)return t1.b<t2.b;
return t1.c<t2.c;
}

int cmp4qsort(const void * a, const void * b){
TS *t1 = (TS*)a, *t2 = (TS*)b;
if(t1->a != t2->a) return t1->a - t2->a;
if(t1->b != t2->b) return t1->b - t2->b;
return t1->c - t2->c;
}
struct cmpFunctor{
inline bool operator() (const TS& t1, const TS& t2){
if(t1.a != t2.a) return t1.a < t2.a;
if(t1.b != t2.b) return t1.b < t2.b;
return t1.c < t2.c;
}
};

TS tss
;

void genData(){
_for(i , 0, N){
tss[i].a = rand();
tss[i].b = rand();
tss[i].c = rand();
}
}

int main()
{
srand(time(NULL));

genData();
clock_t start = clock();
sort(tss, tss+N, cmp);
printf("sort by funtion pointer : %ld\n",clock() - start);

genData();
start = clock();
sort(tss, tss+N, cmpFunctor());
printf("sort by functor : %ld\n",clock() - start);

genData();
start = clock();
qsort(tss, N, sizeof(TS), cmp4qsort);
printf("qsort by funtion pointer : %ld\n",clock() - start);
return 0;
}


两次编译结果(-O2优化):





1.1.4 STL容器的输出

 使用IO流对容器的内容进行输出。

#include<bits/stdc++.h>
using namespace std;

#define _for(i,a,b) for(int i=(a); i<=(b); i++)
template<typename T>
ostream& operator<<(ostream& os,const vector<T>& v){
_for(i,0,v.size()-1) os<<v[i]<<" ";
return os;
}

template<typename T>
ostream& operator<<(ostream& os, const set<T>& v){
for(typename set<T>::iterator it = v.begin(); it!=v.end(); it++)os<<*it<<" ";
return os;
}

int main()
{
vector<int> a;
set<int> b;
_for(i,1,3)a.push_back(i);
_for(i,4,6)b.insert(i);
cout<<a<<endl;
cout<<b<<endl;
return 0;
}

1.2.1 类型推导(auto)

平时使用的较长的类型声明,如STL的枚举器(iterator)在C++11中可使用auto。编译器在遇见auto时会根据右边的表

达式自动推导出其类型,同时也支持引用类型的变量

vector <int> v;
//枚举器写法。
vector<int>::iterator it = v.begin();
//auto写法。
auto itt = v.begin();
1.2.2 空指针(nullptr)

 一般表示空指针使用 p = NULL,但是NULL只是一个定义为0的宏,容易与整数类型0混淆。而C++11中使用nullptr关键字

 来专门表示空指针。NULL和nullptr的主要区别有NULL可以直接赋值给整数类型,但是nullptr不可以。nullptr可以转化为bool

 类型,表示false。

1.2.3 auto实现容器的遍历

 C++11中可以使用auto来遍历容器以及修改数据,vector、map、string以及数据都可以遍历。

#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char const *argv[])
{
vector <int> v;
for(int i=1;i<=10;i++)v.push_back(i);
for(typename vector<int>::iterator it = v.begin(); it!=v.end(); it++)cout<<*it<<endl;

for(const auto& p : v)
{
cout<<p<<endl;
}

int a[] = {1,2,3,4,5};
for(auto &i : a)i+=10;
for(int i=0;i<5;i++)cout<<a[i]<<endl;
return 0;
}
1.2.4 匿名函数(Lambda)
 匿名函数就是可以不用提前定义函数及其功能,而是在使用该函数的时候定义函数,有函数式编程的风格。lambda的用法

有很多,包括对引用捕捉等,在这里仅将1.1.1的部分代码改写如下:

#include<bits/stdc++.h>
using namespace std;
#define _for(i,a,b) for( int i=(a); i<(b); ++i)
const int N = 10000000;
struct TS{
int a,b,c;
};

TS tss
;

void genData(){
_for(i , 0, N){
tss[i].a = rand();
tss[i].b = rand();
tss[i].c = rand();
}
}

int main()
{
srand(time(NULL));

genData();
clock_t start = clock();
sort(tss, tss+N, [](const TS&t1, const TS&t2){
if(t1.a != t2.a) return t1.a < t2.a;
if(t1.b != t2.b) return t1.b < t2.b;
return t1.c < t2.c;
});
printf("sort by funtion pointer : %ld\n",clock() - start);

return 0;
}
1.2.6 哈希容器

 C++11引用了几个基于Hash算法的容器: unordered_map、unordered_se
4000
t、unordered_multimap、unordered_multiset。

当不需要排序时,这些容器的查找性能更好。默认的Hash容器提供了内置数据类型的Hash算法,但是自定义类型需要提供自定义

的Hash算法:自定义类型包含几种内置类型时,分别算出其Hash,进行组合后得到一个新的Hash值,一般采用移位+异或。容器

处理碰撞时需要判断两对象是否相等,所以需要重载"=="操作符。

#include<bits/stdc++.h>
using namespace std;

struct Type
{
int x;
string y;
bool operator==(const Type& a) const
{
return x==a.x && y==a.y;
}
};

struct HashFunc
{
std::size_t operator()(const Type &o) const
{
return ((hash<int>()(o.x))^(hash<string>()(o.y) <<1));
}
};

int main()
{
unordered_map<Type, string, HashFunc> testHash =
{
{   { 1, "1"}, "one"},
{   { 2, "2"}, "two"},
{   { 3, "3"}, "three"}
};
for(const auto& k : testHash)
{
cout<<k.first.x<<","<<k.first.y<<" - "<<k.second<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: