string

string是动态增长的字符数组。

string的架构

#include
using namespace std;
template
class basic_string
{
private:
	T*_str;
	size_t _size;
	size_t _capacity;
};
typedef basic_string string;

string的使用

构造函数:

void test1()
{
	string s1; 
	string s2("河南省巩义市");
}
int main()
{
	test1();
	return 0;
}

string_第1张图片

void test1()
{
	string s1; 
	string s2("河南省巩义市");
	/*s2 += "北山口镇";*/
	string s3 = "河南省巩义市";
}
int main()
{
	test1();
	return 0;
}

string_第2张图片

成员函数没有加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;
}

npos

无符号类型的最大值,也就是2^32.

 operator[]

string_第3张图片

返回字符串第pos个位置元素的引用。

size()

string_第4张图片

返回字符串的长度,单位是字节。

 遍历字符串:
void Test()
{
	string s1("1234");
	for (int i = 0; i < s1.size(); i++)
	{
		s1[i]++;
	}
	cout << s1 << endl;
}
int main()
{
	Test();
	return 0;
}

string_第5张图片

 范围for

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;
}

反转string的首尾

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包裹的类。

begin

string_第6张图片

表示返回字符串第一个受位置的迭代器。

 end

string_第7张图片

表示返回字符串最后一个有效数据的下一个位置的迭代器。

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;
}

 

迭代器不仅可以读,也可以写。

 反向迭代器

string_第8张图片

string_第9张图片

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;
}

string_第10张图片

注意:反向迭代器+的方向也是与正向迭代器+的方向相反。

 反向迭代器名字太长,我们可以用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;
}

const迭代器

我们先自主实现一个打印函数的架构:

这时候,我们想要使用迭代器写:

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迭代器。

string_第11张图片

void Print(const string&s)
{
	string::const_iterator it1 = s.begin();
	while (it1 != s.end())
	{
		cout << *it1;
		++it1;
	}
	cout << endl;
}

 

因为这里const修饰的是it1,我们并不是要对迭代器进行访问,我们是要对迭代器指向的数据进行访问。 

string_第12张图片

const修饰的迭代器的作用:只能对迭代器指向的数据读,不能对迭代器指向的数据写。

 

 总结:

string_第13张图片

size和length:返回字符有效长度

void test_string4()
{
	string s("hello world");
	cout << s.size() << endl;
	cout << s.length() << endl;
}
int main()
{
	test_string4();
	return 0;
}

 capacity:返回容量

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;
}

max_size:返回字符串最大长度

string_第14张图片

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;
}

string_第15张图片

 clear:清楚字符串数据

string_第16张图片

清除字符串的内容。

 在当前这个编译器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;
}

string_第17张图片

 string_第18张图片

shrink_to_fit

string_第19张图片

请求把字符串的容量减少到和字符串元素个数相等。

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;
}

string_第20张图片

在vs2013上按照1.5倍原容量进行扩容。

 string_第21张图片

在g++下插入是二倍扩容。

 要插入数据,就需要扩容,异地扩容的消耗很大。

如果我们知道要插入多少数据,我们可以提前设置容量的话,就可以避免扩容了。

reserve:请求修改容量

要求容量改变 

string_第22张图片

这里容量已经变成了200,不会继续扩容了。

 

 resize:修改元素个数

string_第23张图片

修改字符串的长度。

 resize的三种情况:

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的参数比对象容量还要大时:

对象的元素增多,并且还会扩容。

string_第24张图片

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的参数大于对象元素个数,小于对象的容量。

对象元素增多,不会扩容。

string_第25张图片

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的参数小于对象元素个数。

对象元素减少,不会缩容。

string_第26张图片

resize的用法:

resize只加一个参数,元素个数增多时,增多元素默认为\0。

string_第27张图片

 

表示增多的元素用c进行初始化。

 string_第28张图片

string_第29张图片

 at:

string_第30张图片

 类似于[]:获取string中的某一个元素。

string_第31张图片

 back:

string_第32张图片

返回string最后一个有效元素的引用。

 front:

string_第33张图片

返回string第一个有效元素的引用。

 push_back

string_第34张图片

对string进行尾插字符。

 尾插并不能够尾插字符串。

append

string_第35张图片

append可以尾插字符串或者string对象。

operator+=

string_第36张图片

 既可以实现尾插字符,也可以尾插字符串和string对象。

assign

string_第37张图片

assign的作用是赋值

 insert

插入字符

string_第38张图片

erase

string_第39张图片

从string对象中删除元素。

 注意:insert和erase使用的都不多:原因是插入中间数据和删除中间数据效率太低。

 算法

仅仅反转字母

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

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;
    }
};

 pop_back:尾删

string_第40张图片

 replace:替换

find:查找字符

string_第41张图片 string_第42张图片

找到了返回下标,找不到返回无符号整型的npos

 c_str:返回c形式的字符串

string_第43张图片

#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

 substr

string_第44张图片

表示用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;
}

find_first_of

string_第45张图片

string_第46张图片

 表示从字符串中找到第一个匹配的字符,返回对应位置。

relational operators

string_第47张图片

 比较大小函数。

getline

string_第48张图片

写一行内容到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;
}

你可能感兴趣的:(c++,算法,开发语言)