string是动态增长的字符数组。
#include
using namespace std;
template
class basic_string
{
private:
T*_str;
size_t _size;
size_t _capacity;
};
typedef basic_string string;
void test1()
{
string s1;
string s2("河南省巩义市");
}
int main()
{
test1();
return 0;
}
void test1()
{
string s1;
string s2("河南省巩义市");
/*s2 += "北山口镇";*/
string s3 = "河南省巩义市";
}
int main()
{
test1();
return 0;
}
成员函数没有加explicit,所以可以隐式类型转换,相当于把const char*转换为string类型的对象。
string s4(10,'*');
表示用十个'*'来初始化对象s4.
void test1()
{
string s1;
string s2("河南省巩义市");
/*s2 += "北山口镇";*/
string s3 = "河南省巩义市";
string s4(10, '*');
///*cout << s1 << endl;*/
//cout << s2 << endl;
//cout << s3 << endl;
//cout << s4 << endl;
string s7(s3);
string s8 = s4;
}
int main()
{
test1();
return 0;
}
表示用字符串的前n个字符初始化。
void Test2()
{
string s2("zmszms",3);
cout << s2 << endl;
}
int main()
{
Test2();
return 0;
}
从字符串str的pos位置处开始,传len个字符,初始化。
void Test2()
{
string s1("woshizmszmsshiwo");
string s2(s1, 3, 6);
cout << s2 << endl;
}
int main()
{
Test2();
return 0;
}
如果这个字符串很短或者没有显示传第三个参数len,那么该函数的作用就是把字符串str的pos位置处开始,所有元素都初始化。
void Test2()
{
string s1("woshizmszmsshiwo");
string s2(s1, 3, 20);
string s3(s1, 3);
cout << s2 << endl;
cout << s3 << endl;
}
int main()
{
Test2();
return 0;
}
无符号类型的最大值,也就是2^32.
返回字符串第pos个位置元素的引用。
返回字符串的长度,单位是字节。
void Test()
{
string s1("1234");
for (int i = 0; i < s1.size(); i++)
{
s1[i]++;
}
cout << s1 << endl;
}
int main()
{
Test();
return 0;
}
void Test()
{
string s1("1234");
/*for (int i = 0; i <= s1.size(); i++)
{
s1[i]++;
}*/
for (auto&ch : s1)
{
ch++;//依次把s1的每一个元素传引用给ch
}
cout << s1 << endl;
}
int main()
{
Test();
return 0;
}
void test()
{
string s1("123456");
size_t begin = 0;
size_t end = s1.size() - 1;
while (begin < end)
{
swap(s1[begin++], s1[end--]);
}
cout << s1 << endl;
}
int main()
{
test();
return 0;
}
现阶段我们可以理解为指针。
iterator是一个类型。
int main()
{
string s1("hello world");
string::iterator it1 = s1.begin();
return 0;
}
我们可以把iterator理解为被命名空间string包裹的类。
表示返回字符串第一个受位置的迭代器。
表示返回字符串最后一个有效数据的下一个位置的迭代器。
int main()
{
string s1("123456789");
string::iterator it1 = s1.begin();
while (it1 != s1.end())
{
*it1++;
++it1;
}
cout << s1 << endl;
return 0;
}
int main()
{
string s1 = "1234";
string::iterator it1 = s1.begin();
while (it1 != s1.end())
{
*it1 +=1;
++it1;
}
string::iterator it2 = s1.begin();
while (it2 != s1.end())
{
cout << *it2;
++it2;
}
return 0;
}
迭代器不仅可以读,也可以写。
int main()
{
string s1 = "1234";
string::iterator it1 = s1.begin();
while (it1 != s1.end())
{
*it1 +=1;
++it1;
}
/*string::iterator it2 = s1.begin();
while (it2 != s1.end())
{
cout << *it2;
++it2;
}*/
string::reverse_iterator rit1 = s1.rbegin();
while (rit1 != s1.rend())
{
cout << *rit1 << endl;
rit1++;
}
return 0;
}
注意:反向迭代器+的方向也是与正向迭代器+的方向相反。
反向迭代器名字太长,我们可以用auto代替类型。
int main()
{
string s1 = "1234";
string::iterator it1 = s1.begin();
while (it1 != s1.end())
{
*it1 +=1;
++it1;
}
/*string::iterator it2 = s1.begin();
while (it2 != s1.end())
{
cout << *it2;
++it2;
}*/
auto rit1 = s1.rbegin();
while (rit1 != s1.rend())
{
cout << *rit1 << endl;
rit1++;
}
return 0;
}
我们先自主实现一个打印函数的架构:
这时候,我们想要使用迭代器写:
void Print(const string&s)
{
string::iterator it1 = s.begin();
while (it1 != s.end())
{
*it1 += 1;
++it1;
}
}
int main()
{
string s1 = "1234";
string::iterator it1 = s1.begin();
while (it1 != s1.end())
{
*it1 +=1;
++it1;
}
/*string::iterator it2 = s1.begin();
while (it2 != s1.end())
{
cout << *it2;
++it2;
}*/
auto rit1 = s1.rbegin();
while (rit1 != s1.rend())
{
cout << *rit1 << endl;
rit1++;
}
Print(s1);
return 0;
}
因为s对象是只读的,所以我们需要使用const迭代器。
void Print(const string&s)
{
string::const_iterator it1 = s.begin();
while (it1 != s.end())
{
cout << *it1;
++it1;
}
cout << endl;
}
因为这里const修饰的是it1,我们并不是要对迭代器进行访问,我们是要对迭代器指向的数据进行访问。
const修饰的迭代器的作用:只能对迭代器指向的数据读,不能对迭代器指向的数据写。
总结:
void test_string4()
{
string s("hello world");
cout << s.size() << endl;
cout << s.length() << endl;
}
int main()
{
test_string4();
return 0;
}
void test_string4()
{
string s("hello world");
cout << s.size() << endl;
cout << s.length() << endl;
cout << s.capacity() << endl;
}
int main()
{
test_string4();
return 0;
}
void test_string4()
{
string s("hello world");
cout << s.size() << endl;
cout << s.length() << endl;
cout << s.capacity() << endl;
cout << s.max_size() << endl;
}
int main()
{
test_string4();
return 0;
}
清除字符串的内容。
在当前这个编译器vs下,会清理数据,不会清理空间。
void test_string4()
{
string s("hello world");
//cout << s.size() << endl;
/*cout << s.length() << endl;*/
cout << s.capacity() << endl;
//cout << s.max_size() << endl;
s.clear();
cout << s.capacity() << endl;
}
int main()
{
test_string4();
return 0;
}
请求把字符串的容量减少到和字符串元素个数相等。
int main()
{
std::string str(100, 'x');
std::cout << "1. capacity of str: " << str.capacity() << '\n';
str.resize(10);
std::cout << "2. capacity of str: " << str.capacity() << '\n';
str.shrink_to_fit();
std::cout << "3. capacity of str: " << str.capacity() << '\n';
return 0;
}
void TestPushBack()
{
string s;
size_t sz = s.capacity();
cout << "making a grow" << endl;
for (int i = 0; i < 100; i++)
{
s.push_back(i);
while (sz != s.capacity())
{
sz = s.capacity();
cout << sz << endl;
}
}
}
int main()
{
TestPushBack();
return 0;
}
在vs2013上按照1.5倍原容量进行扩容。
在g++下插入是二倍扩容。
要插入数据,就需要扩容,异地扩容的消耗很大。
如果我们知道要插入多少数据,我们可以提前设置容量的话,就可以避免扩容了。
要求容量改变
这里容量已经变成了200,不会继续扩容了。
修改字符串的长度。
void TestResize()
{
string s("hello world");
cout << s.size() << endl;
cout << s.capacity() << endl;
s.resize(16);
cout << s.size() << endl;
cout << s.capacity() << endl;
}
int main()
{
TestResize();
return 0;
}
resize的参数比对象容量还要大时:
对象的元素增多,并且还会扩容。
void TestResize()
{
string s("hello world");
cout << s.size() << endl;
cout << s.capacity() << endl;
s.resize(14);
cout << s.size() << endl;
cout << s.capacity() << endl;
}
int main()
{
TestResize();
return 0;
}
resize的参数大于对象元素个数,小于对象的容量。
对象元素增多,不会扩容。
void TestResize()
{
string s("hello world");
cout << s.size() << endl;
cout << s.capacity() << endl;
s.resize(7);
cout << s.size() << endl;
cout << s.capacity() << endl;
}
int main()
{
TestResize();
return 0;
}
resize的参数小于对象元素个数。
对象元素减少,不会缩容。
resize只加一个参数,元素个数增多时,增多元素默认为\0。
表示增多的元素用c进行初始化。
类似于[]:获取string中的某一个元素。
返回string最后一个有效元素的引用。
返回string第一个有效元素的引用。
对string进行尾插字符。
尾插并不能够尾插字符串。
append可以尾插字符串或者string对象。
既可以实现尾插字符,也可以尾插字符串和string对象。
assign的作用是赋值
插入字符
从string对象中删除元素。
注意:insert和erase使用的都不多:原因是插入中间数据和删除中间数据效率太低。
class Solution {
public:
bool isalpha(char c)
{
if(c>='a'&&c<='z')
return true;
if(c>='A'&&c<='Z')
return true;
return false;
}
string reverseOnlyLetters(string s) {
size_t begin=0,end=s.size()-1;
while(begin
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
class Solution {
public:
int firstUniqChar(string s) {
int count[256]={0};
for(int i=0;i
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
class Solution {
public:
string addStrings(string num1, string num2) {
string retstr;
int end1=num1.size()-1;
int end2=num2.size()-1;
retstr.reserve(max(num1.size(),num2.size())+1);
int carry=0;
while(end1>=0||end2>=0)
{
int val1=end1>=0?num1[end1]-'0':0;
int val2=end2>=0?num2[end2]-'0':0;
int ret=val1+val2+carry;
if(ret>9)
{
ret%=10;
carry=1;
}
else
{
carry=0;
}
retstr+=ret+'0';
end1--;
end2--;
}
if(carry==1)
{
retstr+='1';
}
reverse(retstr.begin(),retstr.end());
return retstr;
}
};
找到了返回下标,找不到返回无符号整型的npos
#define _CRT_SECURE_NO_WARNINGS 1
#include
using namespace std;
#include
#include
#include
int main()
{
string file("test.cpp");
FILE*fout = fopen(file.c_str(), "r");
assert(fout);
char ch = fgetc(fout);
while (ch != EOF)
{
cout << ch;
ch = fgetc(fout);
}
fclose(fout);
return
表示用string对象的一部分去初始化另一个对象。
int main()
{
string file;
cin >> file;
size_t pos = file.find('.');
string suffix;
if (pos != string::npos)
{
suffix=file.substr(pos+1);
}
cout << suffix << endl;
}
表示从字符串中找到第一个匹配的字符,返回对应位置。
比较大小函数。
写一行内容到string对象
int main()
{
string str;
while (getline(cin, str))
{
size_t pos=str.rfind(' ');
/*string s2=str.substr(pos);*/
/*cout << s2 << endl;*/
cout << str.size() - pos-1 << endl;
}
return 0;
}