STL非修改算法 由于STL算法都是通过迭代器间接处理容器,下面定义istream_iteratorInIt,ostream_itreatorOutIt,forward_iteratorFwdIt,bidirectional_iterator BidIt,random_iterator RanIt 非修改算法: 算法 用法 说明 adjacent_find FwdIt adjacent_find(FwdIt first,FwdIt last);FwdIt adjacent_find(FwdIt first,FwdIt last,Pred pr); 在[first,last)查找相同元素的首次出现或能使pr(elem,nextElem)为true的元素的位置 ,函数查找成功返回位置,失败返回last binary_search bool binary_search(FwdIt first,FwdIt last,const T& val);bool binary_search(FwdIt first,FwdIt last,const T& val,Pred pr); 在区间[first,last)中查找元素val,如果找到返回true,否则返回false,第二种形式pr用于设定查找准则 count size_t count(InIt first,InIt last,const T& val); 返回区间[first,last)上val出现的次数 count_if size_t count_if(InIt first,InIt last,Pred pr); 返回区间[first,last)上满足条件pr(elem)的元素个数 equal bool equal(InIt1 first,InIt1 last,InIt2 x);bool equal(InIt1 first,InIt1 last,InIt2 x,Pred pr); 判断[first,last)与x开始的区间的元素是否相等,pr用于指定判断函数 equal pair<FwdIt,FwdIt> equal_range(FwdIt first,FwdIt last,const T& val);pair<FwdIt,FwdIt> equal_range(FwdIt first,FwdIt last,const T& val,Pred pr); 返回元素val第一次出现的位置和最后出现的位置的下一位组成的对,pr指定比较算法 lower_bound FwdIt lower_bound(FwdIt first,FwdIt last,const T& val);FwdIt lower_bound(FwdIt first,FwdIt last,const T& val,Pred pr); 返回已排序序列[first,last)中val首次出现的位置,pr指定比较算法 upper_bound FwdIt upper_bound(FwdIt first,FwdIt last,const T& val);FwdIt upper_bound(FwdIt first,FwdIt last,const T& val,Pred pr); 返回已排序序列[first,last)中val最后一次出现的下一个位置,pr指定比较算法 find InIt find(InIt first,InIt last,const T& val); 在[first,last)之间查找元素val,如果找到返回位置,找不到返回last find_if InIt find_if(InIt first,InIt last, Pred pr); 在[first,last)之间查找能使函数pr返回true的元素,找到返回位置,否则返回last find_end FwdIt1 find_end(FwdIt1 first1,FwdIt1 last1,FwdIt2 first2,FwdIt2 last2);FwdIt1 find_end(FwdIt1 first1,FwdIt1 last1,FwdIt2 first2,FwdIt2 last2, Pred pr); 在[first1,last1)之间查找[first2,last2)最后出现的位置,如果找到返回位置,失败返回last1,第二个函数的pr函数用于比较两个容器的元素,在两个容器的元素相等时返回true find_first_of FwdIt1 find_first_of(FwdIt1 first1,FwdIt1 last1,FwdIt2 first2,FwdIt2 last2);FwdIt1 find_first_of(FwdIt1 first1,FwdIt1 last1,FwdIt2 first2,FwdIt2 last2, Pred pr); 在[first1,last1)之间查找第一次出现[first2,last2)中元素的位置,找到返回位置,失败返回last1,第二个函数pr用于比较两个容器的元素是否相等 for_each Fun for_each(InIt first,InIt last, Fun f); 对[first,last)上的所有元素执行函数f(elem),返回值常被忽略 includes bool includes(InIt1 first1,InIt1 last1,InIt2 first2,InIt2 last2);bool includes(InIt1 first1,InIt1 last1,InIt2 first2,InIt2 last2, Pred pr); 判断已排序序列[first1,last1)中是否包含区间已排序区间[first2,last2),pr指定元素的顺序 mismatch pair<InIt1,InIt2> mismatch(InIt1 first,InIt1 last,InIt2 x);pair<InIt1,InIt2> mismatch(InIt1 first,InIt1 last,InIt2 x, Pred pr); 返回序列[first,last)与x开始的序列第一个不匹配的位置的两个迭代器组成的对 max const T& max(const T& x,const T& y);const T& max(const T& x,const T& y, Pred pr); 返回x,y之间的较大者,pr(elem1,elem2)用于指定比较规则 max_element FwdIt max_element(FwdIt first,FwdIt last);FwdIt max_element(FwdIt first,FwdIt last, Pred pr); 返回区间[first,last)上最大值的位置,pr(elem1,elem2)用于指定比较规则 min const T& min(const T& x,const T& y);const T& min(const T& x,const T& y, Pred pr); 返回x,y之间的较小者,pr(elem1,elem2)用于指定比较规则 min_element FwdIt min_element(FwdIt first,FwdIt last);FwdIt min_element(FwdIt first,FwdIt last, Pred pr); 返回区间[first,last)上的最小值的位置,pr(elem1,elem2)用于指定比较规则 search FwdIt1 search(FwdIt1 first1,FwdIt1 last1,FwdIt2 first2,FwdIt2 last2);FwdIt1 search(FwdIt1 first1,FwdIt1 last1,FwdIt2 first2,FwdIt2 last2, Pred pr); 在[first1,last1)中查找子区间[first2,last2),如果找到返回在第一个区间中的位置,失败返回last1,第二种形式pr函数用于设定比较函数 search_n FwdIt search_n(FwdIt first,FwdIt last,Dist n,const T& val);FwdIt search_n(FwdIt first,FwdIt last,Dist n,const T& val, Pred pr); 在[first,last)中查找连续n个val,如果找到返回在区间中的位置,失败返回last,第二种形式pr用于设定比较函数 STL修改算法 修改算法: 算法 用法 说明 copy OutIt copy(InIt first,InIt last,OutIt x); 将[first,last)之间的元素复制到x指定的位置 copy_backward BidIt2 copy_backward(BidIt1 first,BidIt1 last,BidIt2 x); 将[first,last)之间的元素复制到x指定位置的前面 fill void fill(FwdIt first,FwdIt last,const T& x); 将[first,last)之间的部分用元素x填充 fill_n void fill_n(OutIt first, Size n,const T& x); 从first开始向容器中填充n个元素x generate void generate(FwdIt first,FwdIt last, Gen g); 调用函数g()填充[first,last)之间的元素 generate_n void generate_n(OutIt first,size n, Gen g); 调用函数g()填充从first开始的n个元素 remove FwdIt remove(FwdIt first,FwdIt last,const T& val); 从[first,last)中删除元素val,返回新区间中最后一个元素后的位置 remove_if FwdIt remove_if(FwdIt first,FwdIt last, Pred pr); 从[first,last)中删除所有能使函数pr返回true的元素,返回新区间最后一个元素后的位置 remove_copy OutIt remove_copy(InIt first,InIt last,OutIt x,const T& val); 从[first,last)中删除元素val,并把其余的元素复制到x开始的区间中,返回被拷贝的最后一个元素的位置 remover_copy_if OutIt remove_copy_if(InIt first,InIt last,OutIt x,Pred pr); 从[first,last)中删除所有能使函数pr返回true的元素,并把其余元素复制到x开始的空间,返回被拷贝最后一个元素的位置 replace void replace(FwdIt first,FwdIt last,const T& vold,const T& vnew); 用vnew替换[first,last)中所有值为vold的元素 replace_if void replace_if(FwdIt first,FwdIt last,Pred pr,const T& val); 用val替换[first,last)中所有能使函数pr返回true的元素 replace_copy OutIt replace_copy(InIt first,InIt last,OutIt x,const T& vold,const T& vnew); 把[first,last)中的所有元素复制到以x开始的空间中,如果拷贝的元素中存在值为vold的元素,则以vnew替换,返回拷贝到目标容器的最后一个元素的后一个位置 replace_copy_if OutIt replace_copy_if(InIt first,InIt last,OutIt x,Pred pr,const T& val); 把[first,last)中的所有元素复制到以x开始的空间中,如果拷贝的元素中存在能够使函数pr返回true的元素,则以vnew替换,返回拷贝到目标容器的最后一个元素的后一个位置 swap void swap(Container &c1,Container &c2); 交换容器c1与c2的元素 iter_swap void iter_swap(FwdIt1 x,FwdIt2 y); 交换迭代器x,y所指元素的值 swap_ranges FwdIt2 swap_ranges(FwdIt1 first,FwdIt1 last,FwdIt2 x); 用起始于x的连续元素交换区间[first,last)的所有元素,返回第二个区间的最后一个元素的下一个位置 sort void sort(RanIt first, RanIt last);void sort(RanIt first, RanIt last, Pred pr); 将区间[first,last)中的元素按升序排序,第二种形式pr用于设定比较函数 merge OutIt merge(InIt1 first1,InIt1 last1,InIt2 first2,InIt2 last2,OutIt x);OutIt merge(InIt1 first1,InIt1 last1,InIt2 first2,InIt2 last2,OutIt x, Pred pr); 合并两个有序区间[first1,last1)和[first2,last2),并将合并后的元素存储到x开始的容器里,第二种形式pr(elem1,elem2)指定比较规则 inplace_merge void inplace_merge(BidIt first, BidIt middle, BidIt last);void inplace_merge(BidIt first, BidIt middle, BidIt last, Pred pr); 合并区间[first,middle)和[middle,last),并将合并后的元素存储到first开始的区间,第二种形式pr(elem1,elem2)指定比较规则 reverse void reverse(BidIt first, BidIt last); 将区间[first,last)的元素顺序倒置 reverse_copy OutIt reverse_copy(BidIt first, BidIt last,OutIt x); 将区间[first,last)的元素拷贝到x开始的区间,导致拷贝的元素顺序,源区间没有被修改,返回拷贝到目标区间的最后一个元素的下一个位置 rotate void rotate(FwdIt first,FwdIt middle,FwdIt last); 交换区间[first,middle)和[middle,last)的元素位置 rotate_copy OutIt rotate_copy(FwdIt first,FwdIt middle,FwdIt last,OutIt x); 将区间[first,last)的元素拷贝到x开始的容器中,拷贝时交换[first,middle)和[middle,last)的位置,源区间不发生修改,返回拷贝到目标区间的最后一个元素的下一位 random_shuffle void random_shuffle(RanIt first, RanIt last);void random_shuffle(RanIt first, RanIt last, Fun& f); 对区间[first,last)上的元素进行随机排序,f用于指定排序函数 transform OutIt transform(InIt first,InIt last,OutIt x, Unop uop); 对区间[first,last)上的所有元素执行uop(elem)操作,结果放到以x开始的区间内,返回拷贝到目标端的最后一个元素的下一位 transform OutIt transform(InIt1 first1,InIt1 last1,InIt2 first2,OutIt x, Binop bop); 对区间[first1,last1)和以first2开始的区间的元素执行二元运算bop(elem1,elem2),结果放到以x开始的区间内,返回拷贝到目标端的最后一个元素的下一位 set_itersection OutIt set_intersection(InIt1 first1,InIt1 last1,InIt2 first2,InIt2 last2,OutIt x);OutIt set_intersection(InIt1 first1,InIt1 last1,InIt2 first2,InIt2 last2,OutIt x, Pred pr); 求两个区间[first1,last1),[first2,last2)的交集,存储到x开始的容器里,源区间元素没有被修改,pr用于指定操作函数,返回拷贝到目标区间的最后一个元素的下一个位置 set_union OutIt set_union(InIt1 first1,InIt1 last1,InIt2 first2,InIt2 last2,OutIt x);OutIt set_union(InIt1 first1,InIt1 last1,InIt2 first2,InIt2 last2,OutIt x, Pred pr); 求两个区间[first1,last1),[first2,last2)的并集,存储到x开始的容器里,源区间元素没有修改,pr用于指定操作函数,返回拷贝到目标区间的最后一个元素的下一位 set_difference OutIt set_difference(InIt1 first1,InIt1 last1,InIt2 first2,InIt2 last2,OutIt x);OutIt set_difference(InIt1 first1,InIt1 last1,InIt2 first2,InIt2 last2,OutIt x, Pred pr); 求两个集合[first1,last1),[first2,last2)的差集,存储到x开始的容器里,源区间元素没有被修改,pr用于指定操作函数,返回拷贝到目标区间的最后一个元素的下一个位置 set_symmetric_ difference OutIt set_symmetric_difference(InIt1 first1,InIt1 last1,InIt2 first2,InIt2 last2,OutIt x);OutIt set_symmetric_difference(InIt1 first1,InIt1 last1,InIt2 first2,InIt2 last2,OutIt x, Pred pr); 求集合[first1,last1),[first2,last2)的对称差(即(A-B)+(B-A)),存储到x开始的容器里,源区间元素没有被修改,pr用于指定操作函数,返回拷贝到目标区间最后一个元素的下一个位置 C++string类常用函数 string类的构造函数:string(const char *s); //用c字符串s初始化string(int n,char c); //用n个字符c初始化此外,string类还支持默认构造函数和复制构造函数,如string s1;string s2="hello";都是正确的写法。当构造的string太长而无法表达时会抛出length_error异常 string类的字符操作:const char &operator[](int n)const;const char &at(int n)const;char &operator[](int n);char &at(int n);operator[]和at()均返回当前字符串中第n个字符的位置,但at函数提供范围检查,当越界时会抛出out_of_range异常,下标运算符[]不提供检查访问。const char *data()const;//返回一个非null终止的c字符数组const char *c_str()const;//返回一个以null终止的c字符串int copy(char *s, int n, int pos = 0) const;//把当前串中以pos开始的n个字符拷贝到以s为起始位置的字符数组中,返回实际拷贝的数目 string的特性描述:int capacity()const; //返回当前容量(即string中不必增加内存即可存放的元素个数)int max_size()const; //返回string对象中可存放的最大字符串的长度int size()const; //返回当前字符串的大小int length()const; //返回当前字符串的长度bool empty()const; //当前字符串是否为空void resize(int len,char c);//把字符串当前大小置为len,并用字符c填充不足的部分 string类的输入输出操作:string类重载运算符operator>>用于输入,同样重载运算符operator<<用于输出操作。函数getline(istream &in,string &s);用于从输入流in中读取字符串到s中,以换行符'\n'分开。 string的赋值:string &operator=(const string &s);//把字符串s赋给当前字符串string &assign(const char *s);//用c类型字符串s赋值string &assign(const char *s,int n);//用c字符串s开始的n个字符赋值string &assign(const string &s);//把字符串s赋给当前字符串string &assign(int n,char c);//用n个字符c赋值给当前字符串string &assign(const string &s,int start,int n);//把字符串s中从start开始的n个字符赋给当前字符串string &assign(const_iterator first,const_itertor last);//把first和last迭代器之间的部分赋给字符串 string的连接:string &operator+=(const string &s);//把字符串s连接到当前字符串的结尾 string &append(const char *s); //把c类型字符串s连接到当前字符串结尾string &append(const char *s,int n);//把c类型字符串s的前n个字符连接到当前字符串结尾string &append(const string &s); //同operator+=()string &append(const string &s,int pos,int n);//把字符串s中从pos开始的n个字符连接到当前字符串的结尾string &append(int n,char c); //在当前字符串结尾添加n个字符cstring &append(const_iterator first,const_iterator last);//把迭代器first和last之间的部分连接到当前字符串的结尾 string的比较:bool operator==(const string &s1,const string &s2)const;//比较两个字符串是否相等运算符">","<",">=","<=","!="均被重载用于字符串的比较;int compare(const string &s) const;//比较当前字符串和s的大小int compare(int pos, int n,const string &s)const;//比较当前字符串从pos开始的n个字符组成的字符串与s的大小int compare(int pos, int n,const string &s,int pos2,int n2)const;//比较当前字符串从pos开始的n个字符组成的字符串与s中pos2开始的n2个字符组成的字符串的大小int compare(const char *s) const;int compare(int pos, int n,const char *s) const;int compare(int pos, int n,const char *s, int pos2) const;compare函数在>时返回1,<时返回-1,==时返回0 string的子串:string substr(int pos = 0,int n = npos) const;//返回pos开始的n个字符组成的字符串 string的交换:void swap(string &s2); //交换当前字符串与s2的值 string类的查找函数: int find(char c, int pos = 0) const;//从pos开始查找字符c在当前字符串的位置int find(const char *s, int pos = 0) const;//从pos开始查找字符串s在当前串中的位置int find(const char *s, int pos, int n) const;//从pos开始查找字符串s中前n个字符在当前串中的位置int find(const string &s, int pos = 0) const;//从pos开始查找字符串s在当前串中的位置//查找成功时返回所在位置,失败返回string::npos的值 int rfind(char c, int pos = npos) const;//从pos开始从后向前查找字符c在当前串中的位置int rfind(const char *s, int pos = npos) const;int rfind(const char *s, int pos, int n = npos) const;int rfind(const string &s,int pos = npos) const;//从pos开始从后向前查找字符串s中前n个字符组成的字符串在当前串中的位置,成功返回所在位置,失败时返回string::npos的值 int find_first_of(char c, int pos = 0) const;//从pos开始查找字符c第一次出现的位置int find_first_of(const char *s, int pos = 0) const;int find_first_of(const char *s, int pos, int n) const;int find_first_of(const string &s,int pos = 0) const;//从pos开始查找当前串中第一个在s的前n个字符组成的数组里的字符的位置。查找失败返回string::npos int find_first_not_of(char c, int pos = 0) const;int find_first_not_of(const char *s, int pos = 0) const;int find_first_not_of(const char *s, int pos,int n) const;int find_first_not_of(const string &s,int pos = 0) const;//从当前串中查找第一个不在串s中的字符出现的位置,失败返回string::npos int find_last_of(char c, int pos = npos) const;int find_last_of(const char *s, int pos = npos) const;int find_last_of(const char *s, int pos, int n = npos) const;int find_last_of(const string &s,int pos = npos) const; int find_last_not_of(char c, int pos = npos) const;int find_last_not_of(const char *s, int pos = npos) const;int find_last_not_of(const char *s, int pos, int n) const;int find_last_not_of(const string &s,int pos = npos) const;//find_last_of和find_last_not_of与find_first_of和find_first_not_of相似,只不过是从后向前查找 string类的替换函数: string &replace(int p0, int n0,const char *s);//删除从p0开始的n0个字符,然后在p0处插入串sstring &replace(int p0, int n0,const char *s, int n);//删除p0开始的n0个字符,然后在p0处插入字符串s的前n个字符string &replace(int p0, int n0,const string &s);//删除从p0开始的n0个字符,然后在p0处插入串sstring &replace(int p0, int n0,const string &s, int pos, int n);//删除p0开始的n0个字符,然后在p0处插入串s中从pos开始的n个字符string &replace(int p0, int n0,int n, char c);//删除p0开始的n0个字符,然后在p0处插入n个字符cstring &replace(iterator first0, iterator last0,const char *s);//把[first0,last0)之间的部分替换为字符串sstring &replace(iterator first0, iterator last0,const char *s, int n);//把[first0,last0)之间的部分替换为s的前n个字符string &replace(iterator first0, iterator last0,const string &s);//把[first0,last0)之间的部分替换为串sstring &replace(iterator first0, iterator last0,int n, char c);//把[first0,last0)之间的部分替换为n个字符cstring &replace(iterator first0, iterator last0,const_iterator first, const_iterator last);//把[first0,last0)之间的部分替换成[first,last)之间的字符串 string类的插入函数: string &insert(int p0, const char *s);string &insert(int p0, const char *s, int n);string &insert(int p0,const string &s);string &insert(int p0,const string &s, int pos, int n);//前4个函数在p0位置插入字符串s中pos开始的前n个字符string &insert(int p0, int n, char c);//此函数在p0处插入n个字符citerator insert(iterator it, char c);//在it处插入字符c,返回插入后迭代器的位置void insert(iterator it, const_iterator first, const_iterator last);//在it处插入[first,last)之间的字符void insert(iterator it, int n, char c);//在it处插入n个字符c string类的删除函数 iterator erase(iterator first, iterator last);//删除[first,last)之间的所有字符,返回删除后迭代器的位置iterator erase(iterator it);//删除it指向的字符,返回删除后迭代器的位置string &erase(int pos = 0, int n = npos);//删除pos开始的n个字符,返回修改后的字符串 string类的迭代器处理: string类提供了向前和向后遍历的迭代器iterator,迭代器提供了访问各个字符的语法,类似于指针操作,迭代器不检查范围。用string::iterator或string::const_iterator声明迭代器变量,const_iterator不允许改变迭代的内容。常用迭代器函数有:const_iterator begin()const;iterator begin(); //返回string的起始位置const_iterator end()const;iterator end(); //返回string的最后一个字符后面的位置const_iterator rbegin()const;iterator rbegin(); //返回string的最后一个字符的位置const_iterator rend()const;iterator rend(); //返回string第一个字符位置的前面rbegin和rend用于从后向前的迭代访问,通过设置迭代器string::reverse_iterator,string::const_reverse_iterator实现 字符串流处理: 通过定义ostringstream和istringstream变量实现,<sstream>头文件中例如: string input("hello,this is a test"); istringstream is(input); string s1,s2,s3,s4; is>>s1>>s2>>s3>>s4;//s1="hello,this",s2="is",s3="a",s4="test" ostringstream os; os<<s1<<s2<<s3<<s4; cout<<os.str(); C++I/O操作 格式控制 在前面,输入/输出的数据没有指定格式,它们都按缺省的格式输入/输出。然而,有时需要对数据 格式进行控制。这时需利用ios类中定义的格式控制成员函数,通过调用它们来完成格式的设置。ios类的格式控制函数如下所示: long flags( ) const 返回当前的格式标志。 long flays(long newflag) 设置格式标志为newflag,返回旧的格式标志。 long setf(long bits) 设置指定的格式标志位,返回旧的格式标志。 long setf(long bits,long field) 将field指定的格式标志位置为bits,返回旧的格式标志。 long unsetf(long bits) 清除bits指定的格式标志位,返回旧的格式标志。 long fill(char c) 设置填充字符,缺省条件下是空格。 char fill( ) 返回当前填充字符。 int precision(int val) 设置精确度为val,控制输出浮点数的有效位,返回旧值。 int precision( ) 返回旧的精确度值。 int width(int val) 设置显示数据的宽度(域宽),返回旧的域宽。 int width( ) 只返回当前域宽,缺省宽度为0。这时插入操作能按表示数 据的最小宽度显示数据。 预定义的操纵算子 使用成员函数控制格式化输入输出时,每个函数调用需要写一条语句,尤其是它不能用在插入或提取运算符的表达式中,而使用操纵算子,则可以在插入和提取运算符的表达式中控制格式化输 入和输出。在程序中使用操纵算字必须嵌入头文件 iomanip.h dec 十进制的输入输出 hex 十六进制的输入输出 oct 八进制的输入输出 ws 提取空白字符 ends 输出一个nul字符 endl 输出一个换行字符,同时刷新流 flush 刷新流 resetiosflags(long) 请除特定的格式标志位 setiosflags(long) 设置特定的格式标志位 setfill(char) 设置填充字符 setprecision(int) 设置输出浮点数的精确度 setw(int) 设置域宽格式变量 其它流函数 错误处理 在对一个流对象进行I/O操作时,可能会产生错误。当错误发生时,错误的性质被记录在ios类的一个数据成员中。 ios类中定义的描述错误状态的常量: goodbit 没有错误,正常状态 eofbit 到达流的结尾 failbit I/O操作失败,清除状态字后,可以对流继续进行操作。 badbit 试图进行非法操作,清除状态字后,流可能还可以使用。 hardfail 致命错误,不可恢复的错误。 ostream类的成员函数流的其它成员函数可以从流中读取字符或字符串,对流进行无格式化的输入 输出操作,以及直接控制对流的I/O操作。 返回类型 ios类的成员 描 述 ostream* tie(ostream*) 将当前流与指定的输出流连接起来。每当需要 读取当前流时,连接的流会自动刷新。C++流库已用cin.tie(cout)将输入流与输出流连接 起来。要取消与输出流的连接可采用is.tie(0) ostream* tie( ) 返回指向连接流的指针 返回类型 ostream类的成员 描 述 ostream& put(char ch) 向流中输出一个字符ch,不进行任何转换 ostream& write(char*,int) 向流中输出指定长度的字符串,不进行转换 ostream& flush( ) 刷新流,输出所有缓冲的但还未输出的数据 ostream& seekp(streampos) 移动流的当前指针到给定的绝对位置 ostream& seekp(sereamoff,seek_dir) 流的当前指针类似与文件的当前指针 streampos teelp( ) 返回流的当前指针的绝对位置 istream类的成员函数 返回类型 istream类的成员 描 述 int get( ) 读取并返回一个字符 istream& get(char&c) 读取字符并存入c中 istream& get(char*ptr,int len,char delim='') 读取指定的字符到缓冲区中,直到遇到指定的分界符为止,分界符不填入缓冲区。 istream& getline(char*ptr,int len,char delim='') 与get(char*ptr,int len,chardelim ='') 类似,但将分界符填 入缓冲区。 istream& putback( ) 将最近读取的字符放回流中 istream& read(char*,int) 读取规定长度的字符串到缓冲区中函数gcount()返回读取的字节数 int peek( ) 返回流中下一个字符,但不移动文 件指针 istream& seekg(streampos) 移动当前指针到一绝对地址 istream& seekg(streampos,seek_dir) 移动当前指针到一相对地址 streampos tellg( ) 返回当前指针 istream& ignore(int n=1,delim=EOF) 跳过流中几个字符,或直到遇到指定的分界符为止 getch()函数用于从键盘输入一个字符,不回显,包含头文件<conio.h>中 字符串操作 字符串操作是一个不小的主题,在标准C++中,string字符串类成为一个标准,之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必担心内存是否足够、字符串长度等等,而且作为一个类出现,他集成的操作函数足以完成我们大多数情况下的需要. 下面我们首先从一些示例开始学习下string类的使用.1)#include <string>#include <iostream>using namespace std; void main(){ string s("hehe"); cout<<s<<endl; cin.get();}2)#include <string>#include <iostream>using namespace std; void main(){ char chs[] = "hehe"; string s(chs); cout<<s<<endl; cin.get();}3)#include <string>#include <iostream>using namespace std; void main(){ char chs[] = "hehe"; string s(chs,1,3); //指定从chs的索引1开始,最后复制3个字节 cout<<s<<endl; cin.get();}4)#include <string>#include <iostream>using namespace std; void main(){ string s1("hehe"); string s2(s1); cout<<s2<<endl; cin.get();}5)#include <string>#include <iostream>using namespace std; void main(){ string s1("hehe",2,3); string s2(s1); cout<<s2<<endl; cin.get();}6)#include <string>#include <iostream>using namespace std; void main(){ char chs[] = "hehe"; string s(chs,3); //将chs前3个字符作为初值构造 cout<<s<<endl; cin.get();}7)#include <string>#include <iostream>using namespace std; void main(){ string s(10,'k'); //分配10个字符,初值都是'k' cout<<s<<endl; cin.get();}//以上是string类实例的构造手段,都很简单. 9)//赋新值#include <string>#include <iostream>using namespace std; void main(){ string s(10,'k'); //分配10个字符,初值都是'k' cout<<s<<endl; s = "hehehehe"; cout<<s<<endl; s.assign("kdje"); cout<<s<<endl; s.assign("fkdhfkdfd",5); //重新分配指定字符串的前5的元素内容 cout<<s<<endl; cin.get();}10)//swap方法交换#include <string>#include <iostream>using namespace std; void main(){ string s1 = "hehe"; string s2 = "gagaga"; cout<<"s1 : "<<s1<<endl; cout<<"s2 : "<<s2<<endl; s1.swap(s2); cout<<"s1 : "<<s1<<endl; cout<<"s2 : "<<s2<<endl; cin.get();}11)//+=,append(),push_back()在尾部添加字符#include <string>#include <iostream>using namespace std; void main(){ string s = "hehe"; s += "gaga"; cout<<s<<endl; s.append("嘿嘿"); //append()方法可以添加字符串 cout<<s<<endl; s.push_back('k'); //push_back()方法只能添加一个字符... cout<<s<<endl; cin.get();}12)//insert() 插入字符.其实,insert运用好,与其他的插入操作是一样的.#include <string>#include <iostream>using namespace std; void main(){ string s = "hehe"; s.insert(0,"头部"); //在头部插入 s.insert(s.size(),"尾部"); //在尾部插入 s.insert(s.size()/2,"中间");//在中间插入 cout<<s<<endl; cin.get();}13)#include <string>#include <iostream>using namespace std; void main(){ string s = "abcdefg"; s.erase(0,1); //从索引0到索引1,即删除掉了'a' cout<<s<<endl; //其实,还可以使用replace方法来执行删除操作 s.replace(2,3,"");//即将指定范围内的字符替换成"",即变相删除了 cout<<s<<endl; cin.get();} 14)//clear() 删除全部字符#include <string>#include <iostream>using namespace std; void main(){ string s = "abcdefg"; cout<<s.length()<<endl; s.clear(); cout<<s.length()<<endl; //使用earse方法变相全删除 s = "dkjfd"; cout<<s.length()<<endl; s.erase(0,s.length()); cout<<s.length()<<endl; cin.get();}15)//replace() 替换字符#include <string>#include <iostream>using namespace std; void main(){ string s = "abcdefg"; s.replace(2,3,"!!!!!");//从索引2开始3个字节的字符全替换成"!!!!!" cout<<s<<endl; cin.get();}16)//==,!=,<,<=,>,>=,compare() 比较字符串#include <string>#include <iostream>using namespace std; void main(){ string s1 = "abcdefg"; string s2 = "abcdefg"; if (s1==s2)cout<<"s1 == s2"<<endl; else cout<<"s1 != s2"<<endl; if (s1!=s2)cout<<"s1 != s2"<<endl; else cout<<"s1 == s2"<<endl; if (s1>s2)cout<<"s1 > s2"<<endl; else cout<<"s1 <= s2"<<endl; if (s1<=s2)cout<<"s1 <= s2"<<endl; else cout<<"s1 > s2"<<endl; cin.get();}17)//size(),length() 返回字符数量#include <string>#include <iostream>using namespace std; void main(){ string s = "abcdefg"; cout<<s.size()<<endl; cout<<s.length()<<endl; cin.get();}18)//max_size() 返回字符的可能最大个数#include <string>#include <iostream>using namespace std; void main(){ string s = "abcdefg"; cout<<s.max_size()<<endl; cin.get();}19)//empty() 判断字符串是否为空#include <string>#include <iostream>using namespace std; void main(){ string s ; if (s.empty()) cout<<"s 为空."<<endl; else cout<<"s 不为空."<<endl; s = s + "abcdefg"; if (s.empty()) cout<<"s 为空."<<endl; else cout<<"s 不为空."<<endl; cin.get();}20)// [ ], at() 存取单一字符#include <string>#include <iostream>using namespace std; void main(){ string s = "abcdefg1111"; cout<<"use []:"<<endl; for(int i=0; i<s.length(); i++) { cout<<s[i]<<endl; } cout<<endl; cout<<"use at():"<<endl; for(int i=0; i<s.length(); i++) { cout<<s.at(i)<<endl; } cout<<endl; cin.get();}21)#include <string>#include <iostream>using namespace std; void main(){ string s = "abcdefg1111"; const char * chs1 = s.c_str(); const char * chs2 = s.data(); cout<<"use at():"<<endl; int i; for(i=0; i<s.length(); i++) { cout<<"c_str() : "<<chs1[i]<<endl; cout<<"data() : "<<chs2[i]<<endl; } cout<<"c_str() : "<<chs1<<endl; cout<<"data() : "<<chs2<<endl; cout<<endl; cin.get();}22)// substr() 返回某个子字符串#include <string>#include <iostream>using namespace std; void main(){ string s = "abcdefg1111"; string str = s.substr(5,3);//从索引5开始3个字节 cout<<str<<endl; cin.get();}23)// find 查找函数#include <string>#include <iostream>using namespace std; void main(){ string s = "abcdefg1111"; string pattern = "fg"; string::size_type pos; pos = s.find(pattern,0); //从索引0开始,查找符合字符串"f"的头索引 cout<<pos<<endl; string str = s.substr(pos,pattern.size()); cout<<str<<endl; cin.get();}24)// begin() end() 提供类似STL的迭代器支持#include <string>#include <iostream>using namespace std; void main(){ string s = "abcdefg1111"; for(string::iterator iter = s.begin(); iter!=s.end(); iter++) { cout<<*iter<<endl; } cout<<endl; cin.get();} 一个C++字符串存在三种大小:a)现有的字符数,函数是size()和length(),他们等效。 Empty()用来检查字符串是否为空。b)max_size() 这个大小是指当前C++字符串最多能包含的字符数,很可能和机器本身的限制或者字符串所在位置连续内存的大小有关系。我们一般情况下不用关心他,应该大小足够我们用的。但是不够用的话,会抛出length_error异常c)capacity()重新分配内存之前 string所能包含的最大字符数。这里另一个需要指出的是reserve()函数,这个函数为string重新分配内存。重新分配的大小由其参数决定,默认参数为0,这时候会对string进行非强制性缩减 STL学习与示例 STL的本质就是:类模板,函数模板,运算符重载.说起来也是"多态"的表现形式,只不过具有高超的编程技巧和运用,能减少程序员的很多繁琐重复的工作,是一个优秀的"库". STL提供六大组件,彼此可以组合套用,共同组合成STL丰富多彩的编程应用:1)容器(containers):各种数据结构(基本上就是集合类.容器是STL的最主要的标志,可以浅显得认为STL就是容器类的集合...) 如:vector,list,deque,set,map,用来存放数据. 2)算法(algorithms):各种常用算法如:sort,search,copy,erase... 3)迭代器(iterator): 扮演容器与算法直接的胶合剂,所所谓的"泛型指针".(我靠,本质还是从指针来的,只不过"变异"了..) 共有5种类型,以及其他衍生变化: 4)仿函数(functors):行为类似函数,可作为算法的某种策略.(靠,其实就是类....) 仿函数是一种重载了operator()的class或class template,一般函数指针可看作为狭义的仿函数. 5)配接器(adapters):(其实就是C#中的接口啦!!!) 一种用来修饰容器(containers)或仿函数或迭代器接口的东西. 6)配置器(allocators): 负责空间配置与管理. 是一个实现了动态空间配置\空间管理\空间释放 的class template. OK.STL就是容器类+算法实现+迭代器+配接器+仿函数+配置器. 容器通过配置器取得数据存储空间,算法通过迭代器存取容器内容,仿函数可以协助算法完成不同的策略变化,配接器可以修饰或套界仿函数. 以下着重说明STL的容器类以及一些基本的算法: STL容器 所在头文件 特性向量vector <vector> 相当于多功能数组,但是最好不要对向量头进行添加或删除操作双端队列deque <deque> 基本与vector一样表list <list> 对某一位置插入和删除操作花费小队列queue <queue> 插入只可以在尾部,删除\检索和修改只能在头部.先进先出(与stack相反)堆栈stack <stack> 后进先出集合set <set> 每个节点包含一个元素,查找十分快速,不支持重复元素多重集合multiset <set> 和集合基本相同,支持重复元素映射map <map> 由键/值对组成的集合.(不能有重复键)多重映射multimap <map> 可以有重复键. 很多功能,可以用不同的容器来实现(这点很重要),但是要考虑实际的需要,选择合适的容器将大大提高程序性能.(对于新手来说,嘿嘿,能用就好,用顺手了,好好比较下不同情况下不同容器实现相同功能的效率撒...) STL算法:主要头文件<algorithm>,<numeric>,<functional>.<algorithm>:由模板函数组成.常用功能算法:比较,交换,查找,遍历,复制,修改,移除,反转,排序,合并等.<numeric>:包含几个在序列上进行简单数学运算的模板函数,包括加法和乘法在序列上的一些操作.<functional>:定义了一些模板类,即仿函数. STL迭代器:<iterator> (注意,可以把迭代器理解为指针,但是不能像指针一样使用迭代器...)迭代器功能 功能 头文件输入迭代器(Input iterator) 向前读 istream输出迭代器(Output iterator) 向前写 ostream,inserter前向迭代器(Forward iterator) 向前读写 双向迭代器 向前向后读写 list,set,vector,map,multimap,deque,queue随即迭代器 随即读写 vector,deque,array,string 1)构造STL容器对象#include <iostream>#include <vector>using namespace std; class VS{public: static void Show(vector<int> iv) { for(vector<int>::iterator iter=iv.begin(); iter!=iv.end(); iter++) cout<<*iter<<endl; cout<<"-----------------------------------------------"<<endl; }};void main(){ vector<int> iv1; //构造方法1,默认构造无元素,使用push_back方法向容器中添加元素 iv1.push_back(11); iv1.push_back(222); VS::Show(iv1); vector<int> iv2(2); //构造方法2,构造2个int元素,默认初始值为0 VS::Show(iv2); vector<int> iv3(3,1); //构造方法3,构造3个int元素,指定初始值为1 VS::Show(iv3); int a[] = {1,2,343,542,22}; //构造方法4,从数组中直接构造容器元素 vector<int> iv4(a,a+5); VS::Show(iv4); vector<int> iv5(iv4); //构造方法5,从其他容器中直接构造本容器元素 VS::Show(iv5); vector<int>::iterator iter = iv4.begin(); //构造方法6,使用迭带器指针构造 vector<int> iv6(iter+1,iter+3); VS::Show(iv6); cin.get();} //2)容器类的几种输出方式#include <iostream>#include <vector>#include <algorithm>using namespace std; template<typename T>class print //仔细看了,print其实是一个类,只不过重载了"()"运算符,使用起来就像函数,所以称为"仿函数"{public: void operator()(const T& elem) { cout<<elem<<" "; }}; void show(const vector<int>& iv){ for (int i=0; i<iv.size(); i++) cout<<iv[i]<<" "; cout<<endl<<"-----------------------------------"<<endl;}void display(const vector<int>& iv){ for (vector<int>::const_iterator iter=iv.begin(); iter!=iv.end(); iter++) cout<<*iter<<" "; cout<<endl<<"-----------------------------------"<<endl;} void main(){ int ia[6] = {0,1,2,3,4,5}; vector<int> iv(ia,ia+6); show(iv); //1)传统的索引输出 display(iv); //2)使用迭代器输出 for_each(iv.begin(),iv.end(),print<int>()); //3)使用for_each方法输出,需要配合自定义输出函数 cout<<endl<<"------------------------------------"<<endl; copy(iv.begin(), iv.end(), ostream_iterator<int>(cout, " ")); //4)使用copy方法,调用系统输出函数 cin.get();}//3)STL算法:演示sort排序和reverse翻转(这两个方法配合,就可以实现从小到大和从大到小排序了)#include <iostream>#include <algorithm>using namespace std; int main(){ int a[10] = {12,0,5,3,6,8,9,34,32,18}; int b[5] = {5,3,6,8,9}; int d[15]; sort(a,a+10); //sort是从小到大排序,要实现从大到小排序,使用reverse方法翻转即可 for (int i=0; i<10; i++) { cout<<" "<<a[i]; } cout<<endl; sort(b,b+5); //b数组排序好,判断是否包含在排序好的a数组中 if(includes(a,a+10,b,b+5)) //includes方法判断一个数组是否是另一个数组的子集合... cout<<"sorted b members are included in a.";//这里,可以发现数组a中也有"3,5,6,8,9"元素 else cout<<"sorted a dosn't contain sorted b!"; cout<<endl; reverse(a,a+10); //翻转 for (int i=0; i<10; i++) { cout<<" "<<a[i]; } cout<<endl; cin.get(); return 0;}//4)list列表容器,很常用的.#include <iostream>#include <list> //使用list容器,必须加此头文件using namespace std; void main(){ list<int> pp; //声明int元素类型的list容器对象 for (int i=0; i<=9; i++)//后插 { pp.push_back(i);//在当前list<int>容器的最后位置插上i的值 pp.push_front(i*i); //在头部插入元素 //insert() 在任意指定位置插入元素 } //使用迭代器pi进行循环迭代输出pp容器中的所有元素 copy(pp.begin(),pp.end(),ostream_iterator<int>(cout," ")); cout<<endl<<"-----------------------------------------"<<endl; //按常规做法进行迭代输出是不行的,因为list容器是用链表构建的,不支持随即访问功能(这点要注意) //for (int i=0; i<pp.size(); i++) //{ // cout<<pp[i]<<" "; //} cout<<pp.front()<<endl; //返回头元素 cout<<pp.back()<<endl; //返回尾元素 cout<<pp.size()<<endl; //显示此容器的所有元素个数 pp.pop_back(); //移除最后一个元素 pp.pop_front(); //移除最前一个元素 copy(pp.begin(),pp.end(),ostream_iterator<int>(cout," ")); cout<<endl<<"-----------------------------------------"<<endl; cout<< pp.max_size()<<endl; //此list容器所能申请的最大空间 list<int>::iterator pi = pp.begin(); //声明迭代器pi,用来操纵list<int>容器对象 pp.assign(2,3); //assign是重新分配和构造的方法 copy(pp.begin(),pp.end(),ostream_iterator<int>(cout," ")); cout<<endl<<"-----------------------------------------"<<endl; list<int> ppp; cout<<ppp.empty()<<endl; //empty方法判断容器是否为空 cout<< pp.empty()<<endl; //可以发现ppp.empty()返回1,即"true",而pp容器因为有2个元素,返回0,"false"非空 cout<<pp.size()<<"clear方法清除前容器元素个数"<<endl; pp.clear(); cout<<pp.size()<<"clear方法清除后容器元素个数"<<endl; cin.get();}//5)list进一步#include <iostream>#include <list> //使用list容器,必须加此头文件using namespace std; template<class T>void print_list(list<T>& p,string s){ list<T>::iterator iter; for (iter=p.begin(); iter!=p.end(); iter++) cout<<*iter<<" "; for (string::iterator siter=s.begin(); siter!=s.end(); siter++) cout<<*siter; cout<<endl;} void main(){ int ia[] = {1,2,45,6,2,3}; list<int> p1(ia,ia+6); //使用数组初始化list<int>容器对象 print_list(p1,"使用数组初始化list<int>容器对象"); list<int> p2(p1); //使用list<int>容器对象初始化list<int>容器对象 p2.push_front(101); p2.push_back(1001); print_list(p2,"使用list<int>容器对象初始化list<int>容器对象"); list<int> p3; p3 = p2; //直接赋值 print_list(p3,"直接赋值"); list<int>::iterator iter = p3.begin(); p3.insert(iter,10000); //使用迭代器在指定位置插入10000 print_list(p3,"用迭代器在指定位置插入10000"); iter++; //这时iter指向p3容器的第2位置了 p3.insert(iter,3,111); //在p3的第2个位置,连续插入3个111 print_list(p3,"在p3的第2个位置,连续插入3个111"); p3.sort(); //进行排序,默认为升序 print_list(p3,"进行排序,默认为升序"); p3.reverse(); print_list(p3,"翻转容器元素,即sort和reverse方法相配合,达到了按降序排列的目的"); //list<int>容器p3与p2互相交换各自的值 //常规做法,利用一个中间量来进行转换,这里直接使用一个swap就可以完成目的了 p3.swap(p2); print_list(p3,"与p2交换后的p3"); print_list(p2,"与p3交换后的p2"); p3.remove(1001); //移除指定元素值为1001 print_list(p3,"移除指定元素值为1001的p3"); p3.erase(p3.begin(),p3.end()); print_list(p3,"erase方法将指定区域内的容器元素全部清除"); cout<<p3.size()<<endl; cin.get();} 调用STL里algorithm的库函数的全排列程序 #include<iostream> #include<algorithm> using namespace std; #define n 4 int a[n]={1,2,3,4}; int main() { int i; while(1) { for(i=0;i<n;i++) printf("%d ",a[i]); printf("\n"); if(!next_permutation(a,a+n)) break; } return 0; }

评论