欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

關(guān)于C++STL string類的介紹及模擬實(shí)現(xiàn)

 更新時(shí)間:2021年09月09日 09:20:33   作者:世_生  
這篇文章主要介紹了關(guān)于C++STL string類的介紹及模擬實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下面具體的文章內(nèi)容

一、標(biāo)準(zhǔn)庫(kù)中的string類

1.string類

字符串的表示字符序列的類
標(biāo)準(zhǔn)的字符串類提供了對(duì)此類對(duì)象的支持,其接口類似于標(biāo)準(zhǔn)字符容器的接口,但添加了專門用于操作
單字節(jié)字符字符串的設(shè)計(jì)特性。
string類是使用char(即作為它的字符類型,使用它的默認(rèn)char_traits和分配器類型(關(guān)于模板的更多信
息,請(qǐng)參閱basic_string)。
string類是basic_string模板類的一個(gè)實(shí)例,它使用char來(lái)實(shí)例化basic_string模板類,并用char_traits
和allocator作為basic_string的默認(rèn)參數(shù)(根于更多的模板信息請(qǐng)參考basic_string)。
注意,這個(gè)類獨(dú)立于所使用的編碼來(lái)處理字節(jié):如果用來(lái)處理多字節(jié)或變長(zhǎng)字符(如UTF-8)的序列,這個(gè)
類的所有成員(如長(zhǎng)度或大小)以及它的迭代器,將仍然按照字節(jié)(而不是實(shí)際編碼的字符)來(lái)操作。

2.string類中的常用接口說(shuō)明+模擬實(shí)現(xiàn)

2.1 string類對(duì)象的常見構(gòu)造+模擬實(shí)現(xiàn)

代碼演示:

#include<iostream>
#include<string>
using namespace std;

int main()
{
 string s1;
 string s4("hello world");
 string s5("hello world", 7);
 string s6(10, 'x');
 string s2(s4);
 string s3(s4, 6, 3);

 cout << "s1:"<< s1.c_str() << endl;
 cout << "s4:" << s4.c_str() << endl;
 cout << "s5:" << s5.c_str() << endl;
 cout << "s6:" << s6.c_str() << endl;
 cout << "s2:" << s2.c_str() << endl;
 cout << "s3:" << s3.c_str() << endl; 
}

運(yùn)行結(jié)果:

模擬實(shí)現(xiàn)

由于上面有些接口不常用,所以我就模擬實(shí)現(xiàn)了一部分常用的接口

string (const char* s)

namespace cxy
{
 class string
 {
 public:
  string(const char*s = "")
  {
   if (s==nullptr)
    return;
   _size = strlen(s);
   _capacity = _size;
   _str = new char[_capacity + 1];
   strcpy(_str, s);
  }
  
  const char* c_str()
  {
   return _str;
  }
 private:
  size_t _size;
  size_t _capacity;
  char* _str;
 };
}

string (const string& str)
void swap (string& str)

namespace cxy
{
 class string
 {
 public:
  void swap(string& str)
  {
  //下面的swap會(huì)調(diào)用庫(kù)里面的接口
   ::swap(_size, str._size);
   ::swap(_capacity, str._capacity);
   ::swap(_str, str._str);
  }

  string(const char*s = "")
  {
   if (s==nullptr)
    return;
   _size = strlen(s);
   _capacity = _size;
   _str = new char[_capacity + 1];

   strcpy(_str, s);
  }

  string(const string& str)
   :_str(nullptr), _size(0), _capacity(0)
  {
   string tmp(str._str);
   swap(tmp);
  }

  char* c_str()
  {
   return _str;
  }

 private:
  size_t _size;
  size_t _capacity;
  char* _str;
 };
}

2.2 string類對(duì)象的容量操作+模擬實(shí)現(xiàn)

代碼演示:

int main()
{
 string s1("hello world");
 cout <<"s1.size(): " <<s1.size() << endl;
 cout <<"s1.length(): "<< s1.length() << endl;
 cout <<"s1.capacity(): "<<s1.capacity() << endl;
 cout <<"s1:"<< s1 << endl;
 cout << endl;

 s1.clear();
 cout <<"s1:"<< s1 << endl;
 cout << "s1.size(): " << s1.size() << endl;
 cout << "s1.capacity(): " << s1.capacity() << endl;
 cout << endl;

 s1 = "hello world";
 cout << "s1:" << s1 << endl;
 cout << "s1.size(): " << s1.size() << endl;
 cout << "s1.capacity(): " << s1.capacity() << endl;
 s1.resize(17,'x');
 //當(dāng)n>capacity,則擴(kuò)容,并且把0~27上位置的空余位置填充‘字符'
 cout << "s1:" << s1 << endl;
 cout << "s1.size(): " << s1.size() << endl;
 cout << "s1.capacity(): " << s1.capacity() << endl;
 s1.resize(27, 'x');
 //當(dāng)size<n<capacity,則把0~27上位置的空余位置填充‘字符'
 cout << "s1:" << s1 << endl;
 cout << "s1.size(): " << s1.size() << endl;
 cout << "s1.capacity(): " << s1.capacity() << endl;
 s1.resize(5, 'x');
 //當(dāng)n<size,則只保留n個(gè)‘字符',空間大小不變
 cout << "s1:" << s1 << endl;
 cout << "s1.size(): " << s1.size() << endl;
 cout << "s1.capacity(): " << s1.capacity() << endl;
 cout << endl;

 string s2("hello world");
 s2.reserve(5);
 //當(dāng)n<=capacity時(shí),空間大小不變,且不改變數(shù)據(jù)內(nèi)容
 cout << "s2:" << s2 << endl;
 cout << "s2.size(): " << s2.size() << endl;
 cout << "s2.capacity(): " << s2.capacity() << endl;

 s2.reserve(100);
 //當(dāng)n>capacity時(shí),空間會(huì)增大
 cout << "s2:" << s2 << endl;
 cout << "s2.size(): " << s2.size() << endl;
 cout << "s2.capacity(): " << s2.capacity() << endl;
}

運(yùn)行結(jié)果:

得知:

reserve和resize的區(qū)別:reserve不會(huì)影響內(nèi)容,resize會(huì)影響內(nèi)容。

模擬實(shí)現(xiàn)

size_t size() const
返回字符串的有效長(zhǎng)度

namespace cxy
{
 class string
 {
 public:
  size_t size()const
  {
   return _size;
  }
 private:
  size_t _size;
  size_t _capacity;
  char* _str;
 };
}

size_t capacity() const
返回空間的大小

namespace cxy
{
 class string
 {
 public:
  size_t capacity()const
  {
   return _capacity;
  }
 private:
  size_t _size;
  size_t _capacity;
  char* _str;
 };
}

bool empty() const
檢測(cè)字符串釋放為空串,是返回true,否則返回false

namespace cxy
{
 class string
 {
 public:
  bool empty()const
  {
   return _str == 0;
  }
 private:
  size_t _size;
  size_t _capacity;
  char* _str;
 };
}

void clear()
清空有效字符 ,不會(huì)改變?nèi)萘?/code>

namespace cxy
{
 class string
 {
 public:
  void clear()
  {
   _size = 0;
   _str[_size] = '\0';
  }
 private:
  size_t _size;
  size_t _capacity;
  char* _str;
 };
}

void reserve (size_t n = 0)
請(qǐng)求改變?nèi)萘?,此功能對(duì)字符串長(zhǎng)度沒(méi)有影響,無(wú)法改變其內(nèi)容

如果 n 大于當(dāng)前字符串容量,則該函數(shù)會(huì)導(dǎo)致容器將其容量增加到 n 字符(或更大)
n小于當(dāng)前字符串容量時(shí),不會(huì)發(fā)生改變

namespace cxy
{
 class string
 {
 public:
  void reserve(size_t n=0)
  {
   if (n > _capacity)
   {
    char *tmp = new char[n + 1];
    strncpy(tmp,_str,_size+1);
    delete[]_str;

    _str = tmp;
    _capacity = n;
   }
 private:
  size_t _size;
  size_t _capacity;
  char* _str;
 };
}

補(bǔ)充:strncpy是C語(yǔ)言中的函數(shù)

char * strncpy ( char * destination, const char * source, size_t num )

功能:

  • 將source中的字符串復(fù)制到destination中,且復(fù)制num個(gè)字符個(gè)數(shù),如果在沒(méi)有復(fù)制完num個(gè)字符之前,找到了source的末尾,則目標(biāo)填充零,直到向其編寫了總共num字符。
  • 如果來(lái)source中的字符有效長(zhǎng)度大于數(shù)字,則目的地末尾不會(huì)隱含任何空字符('\0')。
  • 因此,在這種情況下,目的地不應(yīng)被視為無(wú)效終止的 C 字符串(因此讀取它將溢出,所以這種時(shí)候記得要在末尾添加'\0')。

void resize (size_t n, char c)
void resize (size_t n)
將有效字符的個(gè)數(shù)該成n個(gè),多出的空間用字符c填充

  • 將字符串大小重新變?yōu)閚字符的長(zhǎng)度。
  • 如果 n 小于當(dāng)前字符串長(zhǎng)度,則當(dāng)前值將縮短為其第一個(gè) n 字符,從而刪除 n 之外的字符。
  • 如果 n 大于當(dāng)前字符串長(zhǎng)度,則通過(guò)在末尾插入盡可能多的字符c以達(dá)到 n 的大小來(lái)擴(kuò)展當(dāng)前內(nèi)容。
  • 如果指定c,則新元素初始化為c的副本,否則,它們是值初始化字符(空字符)。
namespace cxy
{
 class string
 {
 public:
  void resize(size_t n,char c='\0')
  {
   if (n<_size)
   {
    _size = n;
    _str[_size] = '\0';
   }
   else
   {  
    if (n > _capacity)
    {
     reserve(n);
    }
    memset(_str + _size, c, n - _size);   
    _size = n;
    _str[_size] = '\0';
   }
 private:
  size_t _size;
  size_t _capacity;
  char* _str;
 };
}

補(bǔ)充:memset是C語(yǔ)言中的函數(shù)

void * memset ( void * ptr, int value, size_t num )

功能:

  • 將value傳到prt中,以第一個(gè)位置開始傳,傳num個(gè),傳完為止。

總結(jié)

  • size()與length()方法底層實(shí)現(xiàn)原理完全相同,引入size()的原因是為了與其他容器的接口保持一致,一般情況下基本都是用size()。
  • clear()只是將string中有效字符清空,不改變底層空間大小。
  • resize(size_t n) 與 resize(size_t n, char c)都是將字符串中有效字符個(gè)數(shù)改變到n個(gè),不同的是當(dāng)字符個(gè)數(shù)增多時(shí):resize(n)用0來(lái)填充多出的元素空間,resize(size_t n, char c)用字符c來(lái)填充多出的元素空間。注意:resize在改變?cè)貍€(gè)數(shù)時(shí),如果是將元素個(gè)數(shù)增多,可能會(huì)改變底層容量的大
  • reserve(size_t res_arg=0):為string預(yù)留空間,不改變有效元素個(gè)數(shù),當(dāng)reserve的參數(shù)小于string的底層空間總大小時(shí),reserver不會(huì)改變?nèi)萘看笮 ?/code>

2.3 string類對(duì)象的訪問(wèn)及遍歷操作+模擬實(shí)現(xiàn)


代碼演示:

int main()
{
 string s("hello world");
 cout << "operator[] :";
 for (size_t i = 0; i < s.size(); i++)
  cout << s[i] ;
 cout << endl;
 //迭代器
 string::iterator it = s.begin();
 cout << "iterator :";
 while (it != s.end())
 {
  cout << *it ;
  ++it;
 }
 cout << endl;
 //范圍for
 cout << "范圍for :";
 for (auto ch : s)
 {
  cout << ch ;
 }
 cout << endl;
}

模擬實(shí)現(xiàn)

const char& operator[] (size_t pos) const

namespace cxy
{
 class string
 {
 public:
  const char& operator[](size_t pos)const
  {
   assert(pos < _size);
   return _str[pos];
  }
 private:
  size_t _size;
  size_t _capacity;
  char* _str;
 };
}

iterator begin()    iterator end()

namespace cxy
{
 class string
 {
 public:
  typedef char* iterator;  
  iterator begin()
  {
   return _str;
  }
  iterator end()
  {
   return _str+_size;
  }
 private:
  size_t _size;
  size_t _capacity;
  char* _str;
 };
}

C++11:范圍for

在這里不實(shí)現(xiàn),知道怎么用就行

2.4 string類對(duì)象的修改操作+模擬實(shí)現(xiàn)


代碼演示:

int main()
{
 string s("hello world");
 s.push_back('K');
 cout << s << endl;
 s.append("SSSSS");
 cout << s << endl;
 s += "FF";
 cout << s << endl;
 cout << s.find("KSS") << endl;
 s.erase(11, 8);
 cout << s << endl;
}

運(yùn)行結(jié)果:

模擬實(shí)現(xiàn):只實(shí)現(xiàn)了一些常用的接口

void push_back (char c)
在字符串后面插入字符c

namespace cxy
{
 class string
 {
 public:
  void push_back(char c)
  {
   if (_size == _capacity)
   {
    reserve(_capacity * 2);
   }
   _str[_size] = c;
   _str[_size+1] = '\0';
   _size++;
  }
 private:
  size_t _size;
  size_t _capacity;
  char* _str;
 };
}

string& append (const char*s)
在字符串后面追加字符串s

namespace cxy
{
 class string
 {
 public:
  string &append(const char*s)
  {
   size_t len = strlen(s)+_size;
   if (len > _capacity)
   {
    reserve(len);
   }
   strncpy(_str + _size, s, len - _size+1);
   _size = len;
   return *this;
  }
 private:
  size_t _size;
  size_t _capacity;
  char* _str;
 };
}

string& operator+= (const char* s)
在字符串后面追加字符串s

namespace cxy
{
 class string
 {
 public:
  string& operator+=(const char*s)
  {
   append(s);
   return *this;
  }
 private:
  size_t _size;
  size_t _capacity;
  char* _str;
 };
}

const char* c_str() const
返回c格式的字符串

namespace cxy
{
 class string
 {
 public:
  const char* c_str()const
  {
   return _str;
  }
 private:
  size_t _size;
  size_t _capacity;
  char* _str;
 };
}

size_t find (const char* s, size_t pos = 0) const
從字符串pos位置開始往后找字符串s,返回該字符串s在字符串中的位置

namespace cxy
{
 class string
 {
 public:
  size_t find(const char*s,size_t pos=0)const
  {
   char *str = _str+pos;
   while (*str)
   {
    char* str_s = str;
    const char* tmp = s;
    while (*str_s&&*tmp==*str_s)
    {
     tmp++;
     str_s++;
    }
    if (*tmp=='\0')
     return str - _str;
    else
     str++;
   }
   return -1;
  }
 private:
  size_t _size;
  size_t _capacity;
  char* _str;
 };
}

string& erase (size_t pos = 0, size_t len = npos)
擦除字符串的一部分,減少其長(zhǎng)度

static const size_t npos = 0;

namespace cxy
{
 class string
 {
 public:
  string &erase(size_t pos = 0, size_t len = npos)
  {
   assert(pos < _size);

   if (len+pos >= _size)
   {
    _str[pos] = '\0';
    _size = pos;
   }
   else
   {
    strcpy(_str + pos, _str + pos + len);
    _size -= len;

   }
   return *this;
  }
 private:
  size_t _size;
  size_t _capacity;
  char* _str;
 };
}

2.5 string類非成員函數(shù)+模擬實(shí)現(xiàn)

模擬實(shí)現(xiàn)

istream& operator>> (istream& is, string& str)

namespace cxy
{
 class string
 {
 public:
  
 private:
  size_t _size;
  size_t _capacity;
  char* _str;
 };
 
 istream& operator >> (istream& is, string& str)
 {
  str.clear();
  char ch;
  ch = is.get();
  while (ch != ' '&&ch != '\0')
  {
   str += ch;
   ch = is.get();
  }
  return is;
 }
}

說(shuō)明一下:這個(gè)函數(shù)實(shí)現(xiàn)放在全局,是因?yàn)樗膇s要和對(duì)象str搶第一個(gè)位置,如果放在string類里面實(shí)現(xiàn),那么第一個(gè)位置是this指針,也就是str對(duì)象,在用這個(gè)函數(shù)的時(shí)候就會(huì)很變扭。

ostream& operator<< (ostream& os, const string& str);

namespace cxy
{
 class string
 {
 public:
  
 private:
  size_t _size;
  size_t _capacity;
  char* _str;
 };
 
 ostream& operator<< (ostream& os, string& str)
 {
  for (auto ch:str)
  {
   os << ch;
  }
  return os;
 } 
}

istream& getline (istream& is, string& str)
獲取一行字符串

namespace cxy
{
 class string
 {
 public:
  
 private:
  size_t _size;
  size_t _capacity;
  char* _str;
 }; 
 istream&getline(istream&is ,string&s)
 {
  s.clear();
  char ch;
  ch = is.get();
  while (ch != '\0')
  {
   s += ch;
   ch = is.get();
  }
  return is;
 }
}

 到此這篇關(guān)于 關(guān)于C++STL string類的介紹及模擬實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)C++STL string類介紹及模擬實(shí)現(xiàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++實(shí)現(xiàn)屏幕截圖功能

    C++實(shí)現(xiàn)屏幕截圖功能

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)屏幕截圖功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • C/C++中抽象類詳解及其作用介紹

    C/C++中抽象類詳解及其作用介紹

    這篇文章主要介紹了C/C++中抽象類詳解及其作用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • 淺析C/C++中sort函數(shù)的用法

    淺析C/C++中sort函數(shù)的用法

    做項(xiàng)目的時(shí)候,排序是一種經(jīng)常要用到的操作。如果每次都自己寫個(gè)冒泡之類的O(n^2)排序,不但程序容易超時(shí),而且浪費(fèi)寶貴的時(shí)間,還很有可能寫錯(cuò)。STL里面有個(gè)sort函數(shù),可以直接對(duì)數(shù)組排序,復(fù)雜度為n*log2(n)。
    2014-09-09
  • 使用C語(yǔ)言實(shí)現(xiàn)模糊搜索功能

    使用C語(yǔ)言實(shí)現(xiàn)模糊搜索功能

    本文所提到的模糊搜索是指輸入不完整的關(guān)鍵詞即可查詢到對(duì)應(yīng)的全部準(zhǔn)確結(jié)果。下面小編通過(guò)實(shí)例代碼給大家分享使用C語(yǔ)言實(shí)現(xiàn)模糊搜索功能,感興趣的朋友一起看看吧
    2018-08-08
  • C++使用string的大數(shù)快速模冪運(yùn)算(6)

    C++使用string的大數(shù)快速模冪運(yùn)算(6)

    這篇文章主要為大家詳細(xì)介紹了C++使用string的大數(shù)快速模冪運(yùn)算,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • C語(yǔ)言中printf的兩種輸出對(duì)齊方式

    C語(yǔ)言中printf的兩種輸出對(duì)齊方式

    C語(yǔ)言中左對(duì)齊是C語(yǔ)言的默認(rèn)輸出方式,右對(duì)齊是一種特殊的輸出方式,左對(duì)齊和右對(duì)齊都對(duì)應(yīng)著一個(gè)已知的輸出寬度,輸出的字符串根據(jù)字符串的長(zhǎng)度在寬度上進(jìn)行補(bǔ)充,補(bǔ)充字符是空格,在使用printf函數(shù)輸出時(shí),需要在格式字符串中使用%-*s和%*s的格式來(lái)分別表示
    2024-02-02
  • 使用C語(yǔ)言實(shí)現(xiàn)貪吃蛇小游戲

    使用C語(yǔ)言實(shí)現(xiàn)貪吃蛇小游戲

    這篇文章主要為大家詳細(xì)介紹了使用C語(yǔ)言實(shí)現(xiàn)貪吃蛇小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • C語(yǔ)言用遞歸函數(shù)對(duì)素?cái)?shù)進(jìn)行判斷流程

    C語(yǔ)言用遞歸函數(shù)對(duì)素?cái)?shù)進(jìn)行判斷流程

    素?cái)?shù)判斷是編程語(yǔ)言學(xué)習(xí)過(guò)程中一個(gè)老生常談的話題,而它的實(shí)現(xiàn)也有多種算法,包括經(jīng)典的試除法(以及試除法的幾種優(yōu)化),進(jìn)階的素?cái)?shù)表篩選法,埃拉托斯特尼篩法和歐拉篩法(以及它們的優(yōu)化)等。對(duì)以上算法感興趣的朋友們,不妨搜索“素?cái)?shù)判斷的N種境界”來(lái)學(xué)習(xí)了解
    2022-09-09
  • C++語(yǔ)言 STL容器list總結(jié)

    C++語(yǔ)言 STL容器list總結(jié)

    這篇文章主要介紹了C++語(yǔ)言 STL容器list總結(jié)的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • 用C++實(shí)現(xiàn)單向循環(huán)鏈表的解決方法

    用C++實(shí)現(xiàn)單向循環(huán)鏈表的解決方法

    本篇文章是對(duì)用C++實(shí)現(xiàn)單向循環(huán)鏈表的解決方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05

最新評(píng)論