常用的string构造相关类的接口
string类是一个管理字符串的字符数组,string类的出现方便管理我们日常所遇见的,字符名,字符串等等。下面们介绍一下常见的string类接口。
string();
默认构造,构造空的string类
int main()
{
string s1;
cout << s1 << endl;
return 0;
}
string (const string& str);
拷贝构造,构造一个和已存在的string对象一模一样的对象。
int main()
{
string s1("abcd");
cout << s1 << endl;
return 0;
}
string (const string& str, size_t pos, size_t len = npos);
从字符串的pos位置拷贝n个字符到字符串str上,pos是所拷贝的位置,len是所拷贝的长度。这里涉及到一个特殊的玩法,拷贝的长度如果大于字符串剩余的,这种情况并不会报错,会拷贝所以剩下的所有。还有一种情况,传入时若长度并未传入,也是会直接拷贝到字符串'\0'的位置。
int main()
{
string s1("abcd",1,5);
cout << s1 << endl;
return 0;
}
string (const char* s);
用字符串来构造类对象
int main()
{
char s1[] = "abcdfg";
string s2(s1);
cout << s2 << endl;
return 0;
}
string (const char* s, size_t n);
用s
所指向字符串(或字符数组)的前n
个来初始化创建一个string
类对象。
int main()
{
char s1[] = "abcdfg";
string s2(s1,3);
cout << s2 << endl;
return 0;
}
string (size_t n, char c);
n个字符进行初始化
int main()
{
string s1(5,'a');
cout << s1 << endl;
return 0;
}
常用的string遍历相关类的接口
1.[]+下标
[ ]+下标本质是调用函数string::operator[],operator[]
的返回值是一个引用,所以可以通过[]
加下标的方式去访问和修改string
类对象。string::operator[]即可以针对普通对象也可针对const对象。 [ ]+下标的方法适用于底层是连续的字符串这种情况。
补充[ ]与at的区别:在越界时[]会触发底层的断言,而at要通过捕获后显示。
int main()
{
//遍历方式
string s1("hello");
for (size_t i=0; i < s1.size(); i++)
{
s1[i]++;
cout << s1[i] << " ";
}
cout << endl;return 0;
}
2.迭代器
迭代器可以理解一种像指针的东西,它本身并不一定是指针,是不是指针取决与底层。
string::iterator 变量名 = s1.begin();
int main()
{
//迭代器的用法
string s1("hello");
string::iterator s = s1.begin();//起始位置
while (s!=s1.end())//字符串最后一个字符的下一个位置
{
cout << *s << " ";
cout << ++(*s) << " ";//字符串++的情况
s++;
}
cout << endl;
return 0;
}
上述案例中是否可以把s!=s1.end()改为s<s1.end
这里我们要明白是迭代器的底层并不是指针,在数组中这中情况是可以的,因为数组是空间是连续的,但是在链表中就不可以了。下面使用list进行验证一下底层到底是不是指针,这里我们通过对比可以看出,底层不是指针,如果是指针解引用不就是节点了吗?
“语法糖”
auto
auto的用法是可以自动识别右侧的类型,简化代码,代替写起来长的类型。
int i=10;
auto a=1;//int
auto b=1.0;//double
auto &c=i;//int &
auto f=c//int
auto &d=c;//int &
auto e=&i;//int *
范围for
//自动进行遍历,自动取出容器的值给左边的值
//自动++,自动判读结束
//适用于容器和数组,范围for底层是迭代器
for(auto 变量名:容器名);
如何实现修改
遍历for是自动取出容器的值给左边的对象,拷贝的值进行自增并不会影响容器的值,所以这里采用引用。
添加引用的两种情况
- 拷贝的数的较大时这种情况拷贝太难处理
- 要进行修改
反向迭代器
reverse_iterator rbegin();
int main()
{
string s("abcde");
std::string::reverse_iterator rit = s.rbegin();
//auto rit=s.rbegin();
while (rit != s.rend())
{
cout << *rit << " ";
rit++;//注意这里是++而不是--
}
cout << endl;
return 0;
}
rebegin()底层实现的图像解析,这里只是逻辑这样实现的,底层不一定是这样实现的。
const_ reverse_iterator rbegin();
const_ reverse_iterator rbegin();与reverse_iterator rbegin();功能一样,前者实现的不能进行修改。
插入用法
插入单个字符
s.push_back('x');
插入字符串
operator+=insert插入
上述的几种对数组的插入都是尾插,insert可以对不同位置进行插入。
int main()
{
string s1("abcde");
string s2("efg");
//在指定位置插入字符串
s1.insert(1, s2);
cout << s1 << endl;
//在指定位置插入指定长度,指定位置一段字符串
s1.insert(1, s2, 1, 2);
cout << s1 << endl;
//指定位置插入一段字符串
s1.insert(1, "xxx");
cout << s1 << endl;
//指定位置插入长度为n的一段字符串
s1.insert(1, "xxx", 1);
cout << s1 << endl;
//指定位置插入n个字符
s1.insert(s1.begin(), 3, '1');
cout << s1 << endl;
return 0;
}
实战演练
1.用C++实现仅仅反转字母
字符串相加
代码优化:
通过insert进行的插入是头插入,头插对于字符的处理时后面的字符要向后移动,因此头插入的时间复杂度在本题是0(),但是通过尾插是0(n),虽然尾插不是我们预期的,但是可以调用reverse模板进行反转。
总结
以上就是本期的主要内容主要介绍了string常用的基础用法,以及迭代的实现介绍。由于string具有较多的接口,这里不进行一一介绍,可以通过此处传送门进入Cplusplus官网进行查阅。最后期待各位大佬的一键三连(点赞,收藏,关注)。