C++ string
标准库定义了三种类型字符串流:istringstream,ostringstream,stringstream,看名字就知道这几种类型和iostream中的几个非常类似,分别可以读、写以及读和写string类型,它们也确实是从iostream类型派生而来的。要使用它们需要包含sstream头文件。
除了从iostream继承来的操作
- sstream类型定义了一个有string形参的构造函数,即:
stringstream stream(s);创建了存储s副本的stringstream对象,s为string类型对象 - 定义了名为str的成员,用来读取或设置stringstream对象所操纵的string值:
stream.str();返回stream中存储的string类型对象stream.str(s);将string类型的s复制给stream,返回void
类型转换
- string转char*
string str=“world”;const char *p = str.c_str();//同上,要加const或者等号右边用char*
- char * 转string
可以直接赋值。
string s;char *p = "hello";//直接赋值s = p;
- int转string
c++11标准增加了全局函数std::to_string:
string to_string (int val);string to_string (long val);string to_string (long long val);string to_string (unsigned val);string to_string (unsigned long val);string to_string (unsigned long long val);string to_string (float val);string to_string (double val);string to_string (long double val);
采用sstream中定义的字符串流对象来实现
int aa = 30;stringstream ss;ss<<aa;string s1 = ss.str();cout<<s1<<endl; // 30string s2;ss>>s2;cout<<s2<<endl; // 30
- string转换成int
stringstream可以吞下任何类型,根据实际需要吐出不同的类型。
string s = "17";stringstream ss;ss<<s;int i;ss>>i;cout<<i<<endl; // 17
采用sstream头文件中定义的字符串流对象来实现转换
istringstream is("12"); //构造输入字符串流,流的内容初始化为“12”的字符串int i;is >> i; //从is流中读入一个int整数存入i中
将n进制的字符串转化为十进制 stoi(字符串,起始位置,几进制);
bool isnum(string s){//题目只保证第二个非空,第一个未说if(s.length()<1)return false;for(int i = 0;i<s.length();i++){if(!isdigit(s[i]))//不是数字,返回falsereturn false;}//遍历完后,可以断定是数字,但需要判断是否越界,测试点5和6if(stoi(s)<1||stoi(s)>1000)return false;return true;}
find函数
c++中string类中的find函数用于寻找字符串中是否包含子串,如果包含,那么函数返回第一个找到的子串的位置,如果不包含,返回-1.
用法例子:
#include<iostream>#include<string>using namespace std;int main(){string a="testcodecodecode";string b="code";string c="lee";int a_b=a.find(b);int a_c=a.find(c);cout<<a_b<<endl;cout<<a_c<<endl;return 0;}
输出:
4-1
分割字符串
find_first_not_of()函数:
size_type find_first_not_of( const basic_string &str, size_type index = 0 );size_type find_first_not_of( const char *str, size_type index = 0 );size_type find_first_not_of( const char *str, size_type index, size_type num );size_type find_first_not_of( char ch, size_type index = 0 );
- 在字符串中查找第一个与str中的字符都不匹配的字符,返回它的位置。搜索从index开始。如果没找到就返回string::nops
- 在字符串中查找第一个与str中的字符都不匹配的字符,返回它的位置。搜索从index开始,最多查找num个字符。如果没找到就返回string::nops
- 在字符串中查找第一个与ch不匹配的字符,返回它的位置。搜索从index开始。如果没找到就返回string::nops
C++11之前只能自己写,我目前发现的史上最优雅的一个实现是这样的:
void split(const string& s, const string& delimiters = " ", vector<string>& tokens){string::size_type first_pos = s.find_first_not_of(delimiters, 0);string::size_type last_pos = s.find_first_of(delimiters, first_pos);while (string::npos != first_pos || string::npos != last_pos) {tokens.push_back(s.substr(first_pos, last_pos - first_pos));//use emplace_back after C++11first_pos = s.find_first_not_of(delimiters, last_pos);last_pos = s.find_first_of(delimiters, first_pos);}}
从C++11开始,标准库中提供了regex,regex用来做split就是小儿科了,比如:
std::string text = "Quick brown fox.";std::regex ws_re("\\s+"); // delimiter is whitespacestd::vector<std::string> v(std::sregex_token_iterator(text.begin(), text.end(), ws_re, -1),std::sregex_token_iterator());for(auto&& s: v)std::cout<<s<<"\n";
统计函数
统计元素出现的次数
头文件 algorithmstd::count(Iterator first, Iterator last, T &val) 统计区间中某个元素出现的次数 std::count_if(InputIterator first, InputIterator last, UnaryPredicate pred) 自定义比较函数
// count_if example#include <iostream> // std::cout#include <algorithm> // std::count_if#include <vector> // std::vectorbool IsOdd (int i) { return ((i%2)==1); }int main () {std::vector<int> myvector;for (int i=1; i<10; i++) myvector.push_back(i); // myvector: 1 2 3 4 5 6 7 8 9int mycount = count_if (myvector.begin(), myvector.end(), IsOdd);std::cout << "myvector contains " << mycount << " odd values.\n";return 0;}
查找给定区间内最大/小值
头文件 algorithmmin_element() 查找给定区间内最小值max_element() 查找给定区间内最大值
#include <iostream>#include <vector>#include <windows.h>#include <algorithm>using namespace std;int main(){vector<int> vec = {-7, 1, 10, 7, 2, 1};vector<int>::iterator itMax = max_element(vec.begin(), vec.end());vector<int>::iterator itMin = min_element(vec.begin(), vec.end());cout << "最大值为:" << *itMax << " " << "所在位置:" << distance(vec.begin(), itMax) << endl;cout << "最小值为:" << *itMin << " " << "所在位置:" << distance(vec.begin(), itMin) << endl;system("pause");return 0;}
累加求和
#include <numeric>template <class InputIterator, class T>T accumulate (InputIterator first, InputIterator last, T init);template <class InputIterator, class T, class BinaryOperation>T accumulate (InputIterator first, InputIterator last, T init,BinaryOperation binary_op);
accumulate带有三个形参:头两个形参指定要累加的元素范围,第三个形参则是累加的初值。
accumulate函数将它的一个内部变量设置为指定的初始值,然后在此初值上累加输入范围内所有元素的值。accumulate算法返回累加的结果,其返回类型就是其第三个实参的类型。
int sum = accumulate(vec.begin() , vec.end() , 42);
对于自定义数据类型,我们就需要自己动手写一个回调函数来实现自定义数据的处理,然后让它作为accumulate()的第四个参数
#include <vector>#include <string>using namespace std;struct Grade{string name;int grade;};int main(){Grade subject[3] = {{ "English", 80 },{ "Biology", 70 },{ "History", 90 }};int sum = accumulate(subject, subject + 3, 0, [](int a, Grade b){return a + b.grade; });cout << sum << endl;system("pause");return 0;}
