算法竞赛入门经典习题与解答-第一章
2018-02-04 01:13
441 查看
1.1.1 排序性能问题
C语言的函数qsort,C++中的sort(直接传入排序函数)以及传入functor对象的sort函数代码以及时间。
两次编译结果(-O2优化):
1.1.4 STL容器的输出
使用IO流对容器的内容进行输出。
1.2.1 类型推导(auto)
平时使用的较长的类型声明,如STL的枚举器(iterator)在C++11中可使用auto。编译器在遇见auto时会根据右边的表
达式自动推导出其类型,同时也支持引用类型的变量
一般表示空指针使用 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以及数据都可以遍历。
匿名函数就是可以不用提前定义函数及其功能,而是在使用该函数的时候定义函数,有函数式编程的风格。lambda的用法
有很多,包括对引用捕捉等,在这里仅将1.1.1的部分代码改写如下:
C++11引用了几个基于Hash算法的容器: unordered_map、unordered_se
4000
t、unordered_multimap、unordered_multiset。
当不需要排序时,这些容器的查找性能更好。默认的Hash容器提供了内置数据类型的Hash算法,但是自定义类型需要提供自定义
的Hash算法:自定义类型包含几种内置类型时,分别算出其Hash,进行组合后得到一个新的Hash值,一般采用移位+异或。容器
处理碰撞时需要判断两对象是否相等,所以需要重载"=="操作符。
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; }
相关文章推荐
- 怎样写C代码——《狂人C》习题解答1(第一章习题7)
- 快学Scala习题解答—第一章 基础
- 第一章 人力资源管理概述习题解答
- 算法竞赛入门经典(第2版)第一章习题(Java)
- 操作系统习题解答 (张尧学) 第一章
- 第一章 人力资源管理概述习题解答
- 算法竞赛入门经典第三章总结(2):后半部分习题解答
- 算法竞赛入门经典第四章:部分习题解答
- 编程珠玑——第一章习题解答
- 张恭庆编《泛函分析讲义》第一章第1节 度量空间习题解答
- 算法竞赛入门经典习题解答(1)
- 《C++ Primer》第五版课后习题解答_第一章(1)(01-11)
- 《组合数学引论》第一章部分习题解答
- 机器学习(周志华版) 第一章习题1.1个人解答
- 算法竞赛入门经典(第二版)习题解答参考(一)
- C++ Primer 习题解答 第一章
- 《算法竞赛入门经典》第一章 程序设计入门 习题
- SICP第一章——构造过程抽象之程序设计的基本元素(1.1)笔记及习题解答
- 张恭庆编《泛函分析讲义》第一章第2节 完备化习题解答
- 《C语言程序设计(第二版新版)》第一章习题解答(部分)