STL Tutorial Reference 读后总结
来源:互联网 发布:mac 电源线皮破了 编辑:程序博客网 时间:2024/05/05 18:17
把平常经常遇到,但是又没掌握的STL技术摘录下来,希望在以后能方便的索引。
- 解决两个空容器之间复制时空间问题:
- list<int> m_List;
- vector<int> m_Vector;
- for(int i=0; i<10; ++i)
- {
- m_List.push_back(i);
- }
- copy(m_List.begin(),m_List.end(),m_Vector.begin());
- 此时,m_Vector中没有空间,不能复制
- 解决方案:
- 1. m_Vector.resize(m_List.size())
- 2. Vector<int> m_Vector(m_List.size());
- 3. copy(m_List.begin(),m_List.end(),back_inserter(m_Vector));
- //----------------------------------------------------------------------------------------------------
- 向容器插入元素另一种方法
- void print(string str)
- {
- cout << str << endl;
- }
- vector<string> vec;
- copy(istream_iterator<string>(cin),istream_iterator<string>(),back_iterator(vec));
- for_each(vec.begin(),vec.end(),print);
- vector<string> vec((istream_iterator<string>(cin)),(istream_iterator<string>()));
- 注意:括号
- copy不需要自定义函数
- for_each需要自定义函数
- //------------------------------------------------------------------------------------------------------
- 打印容器中元素
- 1.
- copy (coll.rbegin(), coll.rend(), //source
- ostream_iterator<int> (cout," "));
- 2.
- template<class T> struct print : public unary_function<T, void>
- {
- print(ostream& out) : os(out), count(0) {}
- void operator() (T x) { os << x << ' '; ++count; }
- ostream& os;
- int count;
- };
- list<int> coll1;
- //insert elements from 1 to 9 into the first collection
- for (int i=1; i<=9; ++i)
- {
- coll1.push_back(i);
- }
- for_each(coll1.begin(),coll1.end(),print<int>(cout));
- cout << endl;
- // copy the elements of coll1 into coll2 by appending them
- vector<int> coll2;
- copy (coll1.begin(), coll1.end(), back_inserter(coll2)); //destination
- for_each(coll2.begin(),coll2.end(),print<int>(cout));
- //------------------------------------------------------------------------------------------------------
- unique_copy()只打印临近不相同的元素,若临近的元素有相同的,则只打印一个
- 示例:
- vector<string> vec;
- copy(istream_iterator<string>(cin),istream_iterator<string>(),back_inserter(vec));
- for_each(vec.begin(),vec.end(),print);
- cout << endl
- unique_copy(vec.begin(), vec.end(), ostream_iterator<string> (cout, "/n"));
- 输入:1 2 2 3 3 3
- 输出:1 2 2 3 3 3
- 1 2 3
- //--------------------------------------------------------------------------------------------------------------
- Vector
- 删除含有值为val的元素
- vector<Elem> coll;
- ...
- coll.erase(remove(coll.begin(),coll.end(),val),coll.end());
- 删除指定元素
- vector<Elem> coll;
- ...
- vector<Elem>::iterator iter;
- iter=find(coll.begin(),coll.end(),val);
- if( iter!=coll.end() )
- {
- coll.erase(pos);
- }
- //--------------------------------------------------------------------------------------------------------------
- List特殊函数示例:
- void PrintList(const list<int> &list1,const list<int> &list2)
- {
- cout << "List1:" << endl;
- copy(list1.begin(),list1.end(),ostream_iterator<int>(cout," "));
- cout << endl;
- cout << "List2:" << endl;
- copy(list2.begin(),list2.end(),ostream_iterator<int>(cout," "));
- cout << endl;
- }
- int main()
- {
- //create two empty lists
- list<int> list1, list2;
- //fill both lists with elements
- for (int i=0; i<6; ++i)
- {
- list1.push_back(i);
- list2.push_front(i);
- }
- PrintList(list1,list2);
- //insert all elements of list1 before the first element with value 3 of list2
- //-find() returns an iterator to the first element with value 3
- list2.splice(find(list2.begin(),list2.end(),3),list1);
- PrintList(list1,list2);
- //move first element to the end
- list2.splice(list2.end(), list2, list2.begin()); // source position
- PrintList(list1,list2);
- cout << endl;
- //sort second list, assign to list1 and remove duplicates
- list2.sort();
- list1 = list2;
- list2.unique();
- PrintList(list1, list2);
- cout << endl;
- //merge both sorted lists into the first list
- list1.merge(list2);
- PrintList(list1, list2);
- system("pause");
- return 0;
- }
- 输出结果:
- list1: 0 1 2 3 4 5
- list2: 5 4 3 2 1 0
- list1:
- list2: 5 4 0 1 2 3 4 5 3 2 1 0
- list1:
- list2: 4 0 1 2 3 4 5 3 2 1 0 5
- list1: 0 0 1 1 2 2 3 3 4 4 5 5
- list2: 0 1 2 3 4 5
- list1: 0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5
- list2:
- 分析:
- c.unique() 删除重复的元素
- c1.splice(pos,c2) 移动c2中的全部元素到c1前位置
- c1.splice(pos,c2,c2pos) 移动c2中c2pos前的元素到pos位置前
- c1.splice(pos,c2,c2beg,c2end)移动c2中的[c2beg,c2end)的元素到pos位置前
- c.sort() 按<排序
- c.sort(op) 按函数op的排序
- c1.merge(c2) 假设全部容器里的元素已经排序,移动所有c2元素到c1,仍然处于排序
- c1.merge(c2,op) 按op的排序,把c2移动到c1
- c.reverse() 反转
- //-------------------------------------------------------------------------------------------------------------
- 在set和multiset中,提供以下函数:
- count(elem) 返回含有elem元素的个数
- find(elem) 返回第一个elem元素的位置
- lower_bound(elem) 返回第一个>=elem元素的位置进行插入
- upper_bound(elem) 返回最后一个>elem元素的位置进行插入
- euqal_range() 返回第一个和最后一个==elem元素的位置进行插入
- set<int> c;
- c.insert(1);
- c.insert(2);
- c.insert(4);
- c.insert(5);
- c.insert(6);
- cout << "lower_bound(3): " << *c.lower_bound(3) << endl;
- cout << "lower_bound(3): " << *c.upper_bound(3) << endl;
- cout << endl;
- cout << "equal_range(3): " << *c.equal_range(3).first << endl;
- cout << "equal_range(3): " << *c.equal_range(3).second << endl;
- 输出结果:
- lower_bound(3): 4
- upper_bound(3): 4
- equal_range(3): 4 4
- set提供两种插入方式
- 1.pair<iterator,bool> insert(const value_type &elem);
- 2.iterator insert(iterator pos_hint,const valu_type &elem);
- pair结构的第二个成员代表插入成功的标志
- pair结构的第一个成员代表新插入元素的位置
- //-------------------------------------------------------------------------------------------------------------
- map和multimap
- 标准库没有提供他们的remove函数
- 插入元素有三种方法:
- 1.value_type
- map<string,float> coll;
- coll.insert(map<string,float>::value_type("ptt",22.3));
- 2.pair<>
- map<string,float> coll;
- //use no implcit conversion
- coll.insert(pair<string,float>("ptt",22.4));
- //use no implicit conversion
- cool.insert(pair<const string,float>("ptt",23.3));
- 3.make_pair()
- map<string,float> coll;
- coll.insert(make_pair("ppt",22.3));
- 插入并检查元素是否存在:
- map<string,float> coll;
- ...
- if (coll.insert(make_pair("otto",22.3)).second)
- {
- cout << "OK, could insert otto/22.3" << endl;
- }
- else
- {
- cout << "Oops, could not insert otto/22.3 "
- << "(key otto already exists)" << endl;
- }
- 删除元素:
- map<string,float> coll;
- ...
- //remove all elements with the passed key
- coll.erase(key);
- 该版本的erase返回删除了的元素数目,且map类型时只能为0或1,而multimap则是所有
- 当删除元素会造成位置失效
- 故又两种方案解决删除元素:
- for(pos=coll.begin(); pos!=coll.end();)
- {
- if( strcmp(pos->first.c_str(),"VAT")==0 )
- {
- 1.//pos=coll.erase(pos);
- 2.//coll.erase(pos++);
- }
- else
- {
- ++pos;
- }
- }
- //-----------------------------------------------------------------------------------------------------------
- iterator对象的使用
- vector<int> vec((istream_iterator<int>(cin)),(istream_iterator<int>()));
- copy(vec.begin(),vec.end(),ostream_iterator<int>(cout," "));
- advance()增加位置,iterator传递参数的值作为计量
- #include <iterator>
- void advance(InputIterator &pos,Dist n)
- distance()提供处理两个distance之间的数据
- #include <iterator>
- Dist distance (InputIterator pos1, InputIterator pos2)
- 注意:
- 1.返回值是iterator pos1和pos2之间的距离
- 2.两个iterator要指向同一个容器
- 3.如果iterator不是随机访问的iterator,则pos2必须能到达pos1,也就是说,必须为相同位置或者在pos1后
- 4.返回的类型是根据iterator的类型
- iter_swap()交换两个iterator的位置
- #include <algorithm>
- void iter_swap (ForwardIterator1 pos1, ForwardIterator2 pos2)
- 1.交换pos1和pos2的引用
- 2.iterator不一定要相同的类型,但是指向的值要能赋值
- //-----------------------------------------------------------------------------------------------------------
- rbegin()和rend()
- rbegin()和container::reverse_iterator(end())相同
- rend()和container::reverse_iterator(begin())相同
- base()把反向iterator转回正常iterator
- 例:
- 1 2 3 4 5 6 7 8 9
- list<int>::iterator pos;
- pos = find (coll.begin(), coll.end(), 5);
- cout << *pos; //5
- //convert iterator to reverse iterator
- list<int>::reverse_iterator rpos(pos);
- cout << *rpos; //4
- //convert reverse iterator back to normal iterator
- list<int>::iterator rrpos;
- rrpos = rpos.base();
- cout << *rrpos //5
- //-------------------------------------------------------------------------------------------------------------
- Kinds of Insert Iterators
- Name Class Called Function Creation
- Back inserter back_insert_iterator push_back (value) back_inserter (cont)
- Front inserter front_insert_iterator push_front (value) front_inserter (cont)
- General inserter insert_iterator insert (pos, value) inserter (cont, pos)
- back iterator只适合于vector deque list和string
- front iterator只适合于deque和list
- 使用前一定要初始化
- back_insert_iterator<vector<int> > iter(vec);
- back_inserter(vec)=44;
- back_inserter(vec)=55;
- //-------------------------------------------------------------------------------------------------------------
- istream_iterator的用法
- 两个istream iterators相等的条件是:
- 1.都是end_of_stream并且不能再读
- 2.都是用相同的输入流
- //create istream iterator that reads integers from cin
- istream_iterator<int> intReader(cin);
- //create end-of-stream iterator
- istream_iterator<int> intReaderEOF;
- /* while able to read tokens with istream iterator
- * - write them twice
- */
- while (intReader != intReaderEOF)
- {
- cout << "once: " << *intReader << endl;
- cout << "once again: " << *intReader << endl;
- ++intReader;
- }
- //--------------------------------------------------------------------------------------------------------------------
- 函数对象
- 函数形式:
- FunctionObjectType fo;
- ...
- fo(...);
- void fo() {
- statements
- }
- 函数对象形式:
- class FunctionObjectType
- {
- public:
- void operator()
- {
- statements
- }
- };
- 使用函数对象比使用函数有三大优点:
- 1.函数对象可以有不同的实例,在不同的时间有不同的状态
- 2.函数对象都有自己的类型,所以可以用模板来提升类型的选择
- 3.函数对象通常情况下比函数指针速度更快,内联
- //--------------------------------------------------------------------------------------------------------------------
- generate_n和generate
- 第三个参数是函数对象
- generate_n把生成的值写到容器
- generate_n (back_inserter(coll),9,IntSequence(1));
- generate_n(ostream_iterator<int>(cout, "/n"), 100, rand);
- generate替换迭代器范围的值
- generate(V.begin(), V.end(), rand);
- vector<int> v (100);
- generate (v.begin(), v.end(), zero);
- //--------------------------------------------------------------------------------------------------------------------
- for_each的用法
- for_each拥有返回函数对象(唯一的一个algorithm成员)
- MeanValue mv = for_each (coll.begin(), coll.end(), MeanValue());
- template<class T> struct print : public unary_function<T, void>
- {
- print(ostream& out) : os(out), count(0) {}
- void operator() (T x) { os << x << ' '; ++count; }
- ostream& os;
- int count;
- };
- int main()
- {
- int A[] = {1, 4, 2, 8, 5, 7};
- const int N = sizeof(A) / sizeof(int);
- print<int> P = for_each(A, A + N, print<int>(cout));
- cout << endl << P.count << " objects printed." << endl;
- }
- //--------------------------------------------------------------------------------------------------------------------
- mem_fun_ref和mem_fun
- 当类没有重载operator()时候,调用成员函数需要使用mem_fun_ref或者mem_fun.
- 前者是直接引用,一般使用前者。当要传递参数的时候,需要使用bind2nd
- class Person
- {
- private:
- string name;
- public:
- Person(string str):name(str)
- {}
- void print() const
- {
- std::cout << name << std::endl;
- }
- void printWithPrefix (std::string prefix) const
- {
- std::cout << prefix << name << std::endl;
- }
- };
- vector<Person > coll;
- coll.push_back(Person("chenyu"));
- coll.push_back(Person("haha"));
- for_each (coll.begin(), coll.end(),mem_fun_ref(&Person::print));
- for_each (coll.begin(), coll.end(),bind2nd (mem_fun_ref (&Person::printWithPrefix),"person: "));
- mem_fun使用方法:
- struct B
- {
- virtual void print() = 0;
- };
- struct D1 : public B
- {
- void print() { cout << "I'm a D1" << endl; }
- };
- struct D2 : public B
- {
- void print() { cout << "I'm a D2" << endl; }
- };
- int main()
- {
- vector<B*> V;
- V.push_back(new D1);
- V.push_back(new D2);
- V.push_back(new D2);
- V.push_back(new D1);
- for_each(V.begin(), V.end(), mem_fun(&B::print));
- }
- //---------------------------------------------------------------------------------------------------------------------
- random_shuffle
- 头文件 <algo.h> 有两个版本,使容器元素排列混乱(相对于sort)
- template <class RandomAccessIterator>
- void random_shuffle(RandomAccessIterator first, RandomAccessIterator last);
- template <class RandomAccessIterator, class RandomNumberGenerator>
- void random_shuffle(RandomAccessIterator first, RandomAccessIterator last,
- RandomNumberGenerator& rand)
- 示例:
- const int N = 8;
- int A[] = {1, 2, 3, 4, 5, 6, 7, 8};
- random_shuffle(A, A + N);
- copy(A, A + N, ostream_iterator<int>(cout, " "));
- // The printed result might be 7 1 6 3 2 5 4 8,
- // or any of 40,319 other possibilities.
- //---------------------------------------------------------------------------------------------------------------------
- itoa的使用
- template <class ForwardIterator, class T>void iota (ForwardIterator first, ForwardIterator last, T value);
- 填充vector,且值从0开始不断增大,结果为0,1,2...
- vector<int> a(100); // initial size 100
- iota (a.begin(), a.end(), 0);
- 标准库没有提供itoa范围复制,如generate和generate_n,如下是自己提供的:
- template <class ForwardIterator, class T>
- void iota_n (ForwardIterator first, int n, T value)
- {
- for (int i = 0; i < n; i++)
- *first++ = value++;
- }
- //---------------------------------------------------------------------------------------------------------------------
- 反转字符串顺序(每个单词反转)
- const string delims(" /t,.;");
- string line;
- //for every line read successfully
- while (getline(cin,line))
- {
- string::size_type begIdx, endIdx;
- //search beginning of the first word
- begIdx = line.find_first_not_of(delims);
- //while beginning of a word found
- while (begIdx != string::npos)
- {
- //search end of the actual word
- endIdx = line.find_first_of(delims, begIdx);
- if (endIdx == string::npos)
- {
- //end of word is end of line
- endIdx = line.length();
- }
- //print characters in reverse order
- for (int i=endIdx-1; i>=static_cast<int>(begIdx); --i)
- cout << line [i];
- cout << ' ';
- //search beginning of the next word
- begIdx = line.find_first_not_of (delims, endIdx);
- }
- }
- 注意,使用 string::npos时,一定要用std::string::size_type作为类型
- string::npos定义为:static const size_type npos = -1;
- //---------------------------------------------------------------------------------------------------------------------
- string的构造函数
- 只有单个参数char *的版本'/0'才是一个特殊符号--终止符,在其他版本里就不是
- std::string s1("nico"); //initializes s1 with: 'n' 'i' 'c' 'o'
- std::string s2("nico",5) ; //initializes s2 with: 'n' 'i' 'c' 'o' '/0'
- std::string s3(5,'/0'); //initializes s3 with: '/0' '/0' '/0' '/0' '/0'
- s1.length() //yields 4
- s2.length() //yields 5
- s3.length() //yields 5
- std:: string s('x'); //ERROR
- std:: string s(1, 'x'); //OK, creates a string that has one character 'x'
- //---------------------------------------------------------------------------------------------------------------------
- IOStream库重要的操作符
- Manipulator Class Meaning
- endl ostream Outputs '/n' and flushes the output buffer
- ends ostream Outputs '/0'
- flush ostream Flushes the output buffer
- ws istream Reads and discards whitespaces
- 特别注意ws
- //---------------------------------------------------------------------------------------------------------------------
- set_union
- 具有两个重载函数:
- template <class InputIterator1, class InputIterator2, class OutputIterator>
- OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,
- InputIterator2 first2, InputIterator2 last2,
- OutputIterator result);
- template <class InputIterator1, class InputIterator2, class OutputIterator,
- class StrictWeakOrdering>
- OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,
- InputIterator2 first2, InputIterator2 last2,
- OutputIterator result,
- StrictWeakOrdering comp);
- set_union构造排序范围为[first1,last1)和[first2,last2),使其具有唯一性,返回值是output range的末尾
- inline bool lt_nocase(char c1, char c2) { return tolower(c1) < tolower(c2); }
- int main()
- {
- int A1[] = {1, 3, 5, 7, 9, 11};
- int A2[] = {1, 1, 2, 3, 5, 8, 13};
- char A3[] = {'a', 'b', 'B', 'B', 'f', 'H'};
- char A4[] = {'A', 'B', 'b', 'C', 'D', 'F', 'F', 'h', 'h'};
- const int N1 = sizeof(A1) / sizeof(int);
- const int N2 = sizeof(A2) / sizeof(int);
- const int N3 = sizeof(A3);
- const int N4 = sizeof(A4);
- cout << "Union of A1 and A2: ";
- set_union(A1, A1 + N1, A2, A2 + N2,
- ostream_iterator<int>(cout, " "));
- cout << endl
- << "Union of A3 and A4: ";
- set_union(A3, A3 + N3, A4, A4 + N4,
- ostream_iterator<char>(cout, " "),
- lt_nocase);
- cout << endl;
- }
- STL Tutorial Reference 读后总结
- STL Tutorial and Reference Guide -- summary
- rabbitmq第二次tutorial读后总结
- stl reference
- web tutorial and reference
- iPhone Development Tutorial/Reference Links
- MySQL 5.7 Reference Manual Chapter 4 Tutorial 参考手册第四章教程内容总结
- An Introductory STL tutorial
- A modest STL tutorial
- MathJax basic tutorial and quick reference
- MathJax basic tutorial and quick reference
- MathJax basic tutorial and quick reference
- Effective STL & C++ STL tutorial summaries
- Memory Management in Objective-C Tutorial 读后小记
- undefined reference问题总结
- undefined reference问题总结
- undefined reference问题总结
- undefined reference问题总结
- 利用存储过程进行分页
- .Net中如何操作IIS
- Hibernate基础知识
- 转载一个EXCEL操作类
- 高中数学公式
- STL Tutorial Reference 读后总结
- c#将数据导出到EXCEL(从网上搜集)
- VC++问题集7
- spartan 3e starter kit平台,使用usb cable和rs232接口的spi flash编程软件
- 网站收录
- Struts1.x Spring2.x Hibernate3.x DWR2.x整合工具文档v1.00
- Ubuntu 3D桌面特效的详细设置
- JQuery选择器
- 一个简单的RMI会话实现