ref:
Lec 1 Intro
Lec 2 Streams
String Stream
讲了sstream
库的istringstream
, ostringstream
和stringstream
,类似于C
的sscanf
和sprintf
#include <iostream>
#include <sstream>
using namespace std;
int main() {
ostringstream oss("3.14", stringstream::ate);
/* start at last
* remove 'stringstream::ate' will start at front
* */
cout << oss.str() << endl;
oss << 15;
cout << oss.str() << endl;
istringstream iss("19.6 dollars", stringstream::binary);
string s;
double amount;
iss >> amount;
//convert to double until meet white space, if cannot conevrt, will get '0'
iss >> s;
cout << s << endl << amount <<endl;
return 0;
}
//输出如下
/*
3.14
3.1415
dollars
19.6
*/
iss
划分token的方式是以空格、制表符为标志,如iss
读入的数据和类型有关,会在第一个不满足类型的字符处停止
State bits
- good:正常
iss.good()
- fail:失败,如文件无法打开,类型匹配错误
iss.fail()
- eof:读至文件末尾
iss.eof()
- bad:一些坏的错误,如正在读的文件突然被删掉了
iss.bad()
Manipulators | 控制符
一部分控制符需要
<iomanip>
头文件
这部分似乎有些太琐碎了,跳过了。比如`cout << setpercison(3) << 13.1769 <<endl;`会输出`13.177`,类似于`C`的`%3lf`。
Lec 2.5 Types
Pair
用法
pair<T1, T2> p1;
//创建一个空的pair对象(使用默认构造),它的两个元素分别是T1和T2类型,采用值初始化
pair<T1, T2> p1(v1, v2);
//创建一个pair对象,它的两个元素分别是T1和T2类型,其中first成员初始化为v1,second成员初始化为v2
make_pair(v1, v2);
// 以v1和v2的值创建一个新的pair对象,其元素类型分别是v1和v2的类型
p1 < p2;
// 两个pair对象间的小于运算,其定义遵循字典次序:如 p1.first < p2.first 或者 !(p2.first < p1.first) && (p1.second < p2.second) 则返回true
p1 == p2;
// 如果两个对象的first和second依次相等,则这两个对象相等;该运算使用元素的==操作符
p1.first; // 返回对象p1中名为first的公有数据成员
p1.second; // 返回对象p1中名为second的公有数据成员
pair<T1, T2> func();
//创建返回值为pair的函数,返回时可以使用make_pair()
Struct
和`C`中的结构体相似。
Uniform Initialization | 统一初始化
C++ 11的新特性
这里是语法
int arr[] {1, 2, 3};
vector<string> {"oneko", "hello"};
Lec 3 Sequence Containers
Sequence Containers就是C++库中定义的一系列模板,用于以sequence形式储存的元素进行一系列操作。
std::array<T>
:实现一个不可调整大小的数组std::vector<T>
:大小可变的数组std::list<T>
:实现一个双向链表std::forward_list<T>
:实现一个单向链表std::deque<T>
:实现一个双端队列- 输入限制双端队列是一种可以从两端进行删除,但只能在一端进行插入的队列
- 输出限制双端队列是一种可以在两端进行插入,但只能从一端进行删除的队列
- 一般意义上的
queue
和stack
可以看做特殊的双端队列vector & array
vector
一些基本操作,以//usage
std::vector<int> intArr;
std::vector<string> strArr;
std::vector<myStruct> structArr;
std::vector<std::vector<string>> vecArr;
//vector of vector<string>,二维数组
vector<int>arr
为例
arr.pushback(3)
:在末尾加入整数3arr.popback()
:删除末尾元素arr.size()
:数组大小arr.empty()
:判断是否为空arr.clear()
:清除所有元素arr.at(2)
:位置为2处的元素的引用
全面的操作看这里
a point
一个值得注意的点,一般的访问在下标越界时不会报出错误,而使用var_name.at(pos)
时,在越界时会报错并终止程序。
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main() {
vector<string>name{"czl", "oneko"};
cout << name[100] << endl;
cout << "Hey, It's out of range actually" << endl;
cout << name.at(100) << endl;
return 0;
}
//输出
/*
Hey, It's out of range actually
terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check: __n (which is 100) >= this->size() (which is 2)
*/
array
//usage
std::array<int, 3> arr = {1, 2, 3}; //初始化了一个大小为3的数组
std::array<std::array<string,3>,4>; //4*3的string数组
//访问,以二维数组为例
#include <iostream>
#include <string>
#include <array>
using namespace std;
int main() {
std::array<std::array<string, 2>, 2> strArr{"a", "b", "c", "d"};
for (int i = 0; i < strArr.size(); i++) {
for (int j = 0; j < strArr.at(i).size(); j++) {
cout << strArr.at(i).at(j) << " ";
}
cout << endl;
}
return 0;
}
//输出
/*
a b
c d
*/
deque
实际上,deque
支持vector
的所有操作,并且还支持快速的push_front()
操作,但是实践中vector
的应用更为广泛,因为一般的操作vector
快于deque
。
“vector is the type of sequene that should be used by default… deque is the data structure of choice when most insertions and deletions take place at the beginning ar at the end of the sequence.”
list & forward_list
Overview of STL
Lec 4 Associative Containers & Iterators
Container Adaptors
stack
和queue
被叫做 container adaptors。
Associative Containers
Associative Containers 也是C++中定义的用来储存有序/无序关联数组的一系列模板,有一些不同的地方是数据是以键的形式来访问的
std::map<T1, T2>
:键-值对,键唯一,值可以不唯一,字典序std::set<T>
:值本身也发挥键的作用,值唯一,字典序std::unordered_map<T1, T2>
:顾名思义,没有顺序的map,Hash表实现std::unordered_set<T>
:没有顺序的set,Hash表实现
map
//usage
#include <iostream>
#include <map>
using namespace std;
int main() {
map<string,int> GradeMap;
//two ways to insert
GradeMap.insert(pair<string,int>("czl", 60));
GradeMap.insert(map<string,int>::value_type("oneko",59));
//traverse
map<string,int>::iterator iter;
//forward
for(iter=GradeMap.begin();iter!=GradeMap.end();iter++){
cout << '(' << iter->first << ',' << iter->second << ')' << ' ';
}
cout << endl;
//backward
map<string,int>::reverse_iterator re_iter;
for(re_iter=GradeMap.rbegin();re_iter!=GradeMap.rend();re_iter++){
cout << '(' << re_iter->first << ',' << re_iter->second << ')' << ' ';
}
cout << endl;
//find
iter = GradeMap.find("czl");
if(iter != GradeMap.end()){
cout << "Found! " << iter->first << "'s grade is " << iter->second;
}
//delete
GradeMap.erase("oneko");
//after traverse
//(czl, 60)
return 0;
}
//输出
/*
(czl,60) (oneko,59)
(oneko,59) (czl,60)
Found! czl's grade is 60
*/
Lec 5 Advanced Containers
- 主要讲了迭代器的一些用法,比较基础。