Day006--标准模板库(standard template libaray)

目录

1. 什么是STL

2. STL的六大组件

3. 标准库中的string类

4. string类的模拟实现

5. vector的介绍及使用

6. vector深度剖析及模拟实现

7. list的介绍及使用

8. list的深度剖析及模拟实现

9. list与vector的对比

10. stack的介绍和使用

11. queue的介绍和使用

12. priority_queue的介绍和使用

13. 容器适配器


1. 什么是STL

        STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且 是一个包罗数据结构与算法的软件框架。

2. STL的六大组件

        

   STL由空间配置器+容器+配接器+迭代器+算法+仿函数六大组件构成。容器:就是数据结构,换了个名字。map+set的底层就是树。

3. 标准库容器中的string类

        3.1 string是一个模板,是一个字符数组,为了兼容C语言,很多接口它需要在后面手动增加一个\0

              string是一个模板,他的原型是basic_string<char>。为了解决编码的问题,需要将字符串写成一个模板。常见的编码有ASCII码,起初是漂亮国人为了解决英语/阿拉伯数字在计算中的显示问题而发明的,将二进制与文字符号之间建立映射关系,ASCII码256种状态就行了。为了全世界的语言也都显示出来,使用的是万国码(Unicode),他们给出了UTF-8(兼容ASCII)、UTF-16、UTF32等解决方案。中国的是GBK(汉字内码扩展规范):国标扩展使用双字节编码方案,一个汉字用两个字节表示。256*256=65536个汉字

#include<iostream>
int main()
{
    char arr[] = "比特";
    cout << sizeof(arr) << endl;
    arr[3]--;
    arr[3]--;
    arr[3]++;
    arr[3]++;
    arr[3]++;
    arr[3]++;

    return 0;
}

        上述发现:数组arr在自增自减过程中发现,汉字是依据同音字相似进行编码的。在净化网络文明中就要对某个确定的字及他的同音字进行屏蔽。

        回到前面的问题:为何要将basic_string写成string模板?就得到了解决,由于同一个字符的编码方式不同(同一个1按照UTF-8、UTF-16进行编码),所以需要统一一个模板。如果编码方式采用的是UTF-8用string(单字节存储)、UTF-16用u16string(两字节存储)、UTF-32用u32string(四字节存储)、宽字符(两字节存储)。这里学习的重点目标是UTF-8的string。

 

 

3.2 string类的成员函数

3.3  string类的构造函数((constructor)

        3.3.1 C++98string类的构造函数提供了7种情况可供我们选择,以应对不同的情形。如下:

         3.3.2  无参数的 empty string constructor (default constructor)

         3.3.3  复制构造的 copy constructor

         3.3.4  子字符串构造函数 substring constructor

                复制 str 中从字符位置 pos 开始并跨越 len 字符的部分(如果 str 太短或 str 等于 len ,len是字符串str::npos(),则直到 str 的末尾)。

3.4 string类中的迭代器成员函数(迭代器看作指针来用)

正向迭代器,反向迭代器(r),const正向迭代器(c),const反向迭代器(c++11)。

3.5 string类中关于容量的成员函数

        3.5.1 size()

        3.5.2 length()

        3.5.3 max_size()

        返回字符串可以达到的最大长度。这个最大长度是一个固定的值为四亿两千万字节,由于已知的系统或库实现限制,这是字符串可以达到的最大潜在长度,但是不能保证对象能够达到这个长度: 在达到这个长度之前,它仍然可能无法分配存储。

3.5.4 

         意为:将字符串的大小调整为 n 个字符的长度。假如有一串字符大小为49字节。若n小于49,则将[n+1,49]这个区间所有的内容全部省略掉,只保留[0,n]的内容;若n大于49小于capacity,则根据函数原型需要在[50,n]之间补齐需要添加的一个字符,注意这里只能是一个字符,不能是字符串。若n大于capacity,则扩容并插入数据

 3.5.5

         意为:为存储字符串所分配空间的大小。这个容量不一定等于字符串长度。它可以等于或大于这个值,但是额外的空间允许对象在向 basic _ string 添加新字符时优化其操作。请注意当这个容量耗尽并且需要更多时,对象会自动扩展它(重新分配它的存储空间)。关于 base _ string 长度的理论限制是由成员 max _ size 给出的。在修改对象的任何时候,base _ string 的容量都可以改变,即使这种修改意味着大小的减少或者容量没有用尽(这与向量容器中对容量的保证形成了对比)。可以通过调用成员预留显式更改 basic _ string 的容量。

3.5.6

         修改当前字符串的容量(capacity)主要是扩容,不同机器下,扩容底层实现不一样,vs下是扩容1.5倍,g++下是扩容2倍;并且vs下容量没有算/0。

        我们在提前知道要多大的空间容量的情况下,reserve可以使用

3.5.7

         擦除字符串的内容,该字符串变成空字符串(长度为0个字符)。        

3.5.8

        返回字符串是否为空(即其长度是否为0)。此函数不以任何方式修改字符串的值。若要清除字符串的内容,请参见 string: : clear。

3.5.9  

        请求字符串减小容量以适应其大小。可以将capacity减小到与siz同大小。不能更改其内容。 

3.6 string类中关于修改的成员函数

 3.6.1 operator+=():底层是由push_back实现的

        通过在字符串的当前值末尾附加其他字符来扩展字符串: (参见成员函数附加其他附加选项)

3.6.2  append()

        通过在字符串的当前值末尾附加其他字符来扩展该字符串。

 形参可以是:1、字符串。

            2、其他或者本身字符串的子字符串(从subpos位置开始,跨越sublen长度)

            3、字符串的首字母的地址。

            4、在s指向的字符数组中追加前n个字符的副本。

            5、追加字符c的n个连续副本。

3.6.3  push_back()

        将字符 c 追加到字符串的末尾,使其长度增加1。注意字符串常量是不被允许的。

3.6.4 assign():注意看源字符串比新字符串长,会先全部清空源字符串,再赋值新的字符串,不会保留源字符串

        为字符串分配一个新值,替换其当前内容。

 1、拷贝一个字符串。

 2、复制从字符位置 subpos 开始并跨越子单元字符的部分 str (或者直到 str 结束,如果 str 太短或者子单元为 string: : npos)。

 3、复制 s 指向的以空结尾的字符序列(C字符串)。

// string::assign
#include <iostream>
#include <string>

int main ()
{
  std::string str;
  std::string base="The quick brown fox jumps over a lazy dog.";

  // used in the same order as described above:

  str.assign(base);
  std::cout << str << '\n';

  str.assign(base,10,9);
  std::cout << str << '\n';         // "brown fox"

  str.assign("pangrams are cool",7);
  std::cout << str << '\n';         // "pangram"

  str.assign("c-string");
  std::cout << str << '\n';         // "c-string"

  str.assign(10,'*');
  std::cout << str << '\n';         // "**********"

  str.assign<int>(10,0x2D);
  std::cout << str << '\n';         // "----------"

  str.assign(base.begin()+16,base.end()-12);
  std::cout << str << '\n';         // "fox jumps over"

  return 0;
}

3.6.5 Insert():不推荐使用,时间复杂度高

        可以实现头插、中间位置插入

 1. pos位置处,插入字符串。

 2. pos位置处,插入子字符串,子字符串是从源字符串的subpos位置处,跨过sublen长度

 3. pos位置处,插入字符串。

 4. pos位置处,插入长度为n的字符串。

 5. pos位置处,插入n个字符c。

3.6.6 erase() :不推荐使用,时间复杂度高

        1. 在pos==0的位置处,删除跨越npos长度的数据,就是头删。另外如果len比字符串长度大或者我们不给参数(就会使用npos这个很大的缺省参数),则将字符串全部删掉。

3.6.7 replace() :注意看replace是直接原位替换,源字符串比新字符串长,会保留后面的部分。

用新的内容替换字符串中从pos开始并跨越len字符的部分(或字符串中位于[i1,i2)之间的部分)

 1、从pos位置,跨越len长度,被str字符串替换。

// replacing in a string
#include <iostream>
#include <string>

int main ()
{
  std::string base="this is a test string.";
  std::string str2="n example";
  std::string str3="sample phrase";
  std::string str4="useful.";

  // replace signatures used in the same order as described above:

  // Using positions:                 0123456789*123456789*12345
  std::string str=base;           // "this is a test string."
  str.replace(9,5,str2);          // "this is an example string." (1)
  str.replace(19,6,str3,7,6);     // "this is an example phrase." (2)
  str.replace(8,10,"just a");     // "this is just a phrase."     (3)
  str.replace(8,6,"a shorty",7);  // "this is a short phrase."    (4)
  str.replace(22,1,3,'!');        // "this is a short phrase!!!"  (5)

  // Using iterators:                                               0123456789*123456789*
  str.replace(str.begin(),str.end()-3,str3);                    // "sample phrase!!!"      (1)
  str.replace(str.begin(),str.begin()+6,"replace");             // "replace phrase!!!"     (3)
  str.replace(str.begin()+8,str.begin()+14,"is coolness",7);    // "replace is cool!!!"    (4)
  str.replace(str.begin()+12,str.end()-4,4,'o');                // "replace is cooool!!!"  (5)
  str.replace(str.begin()+11,str.end(),str4.begin(),str4.end());// "replace is useful."    (6)
  std::cout << str << '\n';
  return 0;
}

3.6.8 swap()

3.6.9  pop_back()

3.6 string类中关于查找的成员函数 

3.6.1 c_string()

        返回一个C字符串,字符串放在数组里面的,C字符串的意思就是:字符串的最后放了一个'/0'

// strings and c-strings
#include <iostream>
#include <cstring>
#include <string>

int main ()
{
  std::string str ("Please split this sentence into tokens");

  char * cstr = new char [str.length()+1];
  std::strcpy (cstr, str.c_str());

  // cstr now contains a c-string copy of str

  char * p = std::strtok (cstr," ");
  while (p!=0)
  {
    std::cout << p << '\n';
    p = std::strtok(NULL," ");
  }

  delete[] cstr;
  return 0;
}

3.6.2 data()

3.6.3 get_allocator()

3.6.4 copy()

3.6.5 find()

3.6.6 rfind()

        与find相反,反着找

3.6.7 substr()

        取出一部分子字符串,将其作为对象进行返回

3.6.8 find_first_of()

       只要目的字符串(下面的str)中有源字符串(found)中的任意一个,都将在目的字符串中标识出来

// string::find_first_of
#include <iostream>       // std::cout
#include <string>         // std::string
#include <cstddef>        // std::size_t

int main ()
{
  std::string str ("Please, replace the vowels in this sentence by asterisks.");
  std::size_t found = str.find_first_of("aeiou");
  while (found!=std::string::npos)
  {
    str[found]='*';
    found=str.find_first_of("aeiou",found+1);
  }

  std::cout << str << '\n';

  return 0;
}

5. vector的介绍及使用

        5.1 vector的构造函数

6. vector深度剖析及模拟实现

7. list的介绍及使用

8. list的深度剖析及模拟实现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值