当前位置: 首页 > news >正文

营销型网站建设都具有哪些优势綦江在线

营销型网站建设都具有哪些优势,綦江在线,上海中高风险地区名单,网页站点不安全文章目录 string类的模拟实现string基本框架的实现operator的实现string常用函数的实现 string类的模拟实现 前文对于string的常用函数做了讲解#xff0c;由于string是一个面试官常考的点#xff0c;总喜欢让模拟实现string类#xff0c;下面来模拟实现一下string#xf… 文章目录 string类的模拟实现string基本框架的实现operator的实现string常用函数的实现 string类的模拟实现 前文对于string的常用函数做了讲解由于string是一个面试官常考的点总喜欢让模拟实现string类下面来模拟实现一下string赋予基本的功能且逐步完善函数实现方式。 string基本框架的实现 string类的基本框架比如构造函数拷贝构造析构函数成员变量起码的push_back等一些能正常使得string运行的函数的实现。 namespace String {class string {public://迭代器 string中的迭代器实际上就是指针typedef char* iterator;typedef const char* const_iterator;iterator begin(){//begin 表示的是string的首元素地址return _str;}iterator end(){//end 返回string最后一个元素的下一个位置也就是\0return _str _size;}const_iterator begin() const{//begin 表示的是string的首元素地址return _str;}const_iterator end() const{//end 返回string最后一个元素的下一个位置也就是\0return _str _size;}//默认构造和带参构造合并使用缺省参数string(const char* str ) //字符串自带\0:_str(new char[strlen(str) 1]), _size(strlen(str)), _capacity(strlen(str)){//存储字符串strcpy(_str, str);}//拷贝构造//string(const string s)//{// //深拷贝就是创建一个大小一样的空间// _str new char[s._capacity 1];// strcpy(_str, s._str);// _size s._size;// _capacity s._capacity;//}string(const string s){_str new char[s._capacity 1];memcpy(_str, s._str, s._size 1);_size s._size;_capacity s._capacity;}//析构函数~string(){delete[] _str;_str nullptr;_size _capacity 0;}void Print() {cout _str \t _size \t _capacity endl;}//reserve 保留容量 可以扩容void reserve(size_t n) //只是改变capacity 不改变size{if (n _capacity){//新建一个字符数组cout reserve- n endl;char* new_str new char[n 1];//更改容量//strcpy(new_str, _str);memcpy(new_str, _str, _size 1);delete[] _str;_str new_str;_capacity n;}}//push_back void push_back(char ch){if (_size _capacity){reserve(_capacity 0 ? 4 : _capacity * 2);}//加入字符_str[_size] ch;_size;_str[_size] \0;}void append(const char* str){if (_size strlen(str) _capacity){reserve(_size strlen(str));//至少保留_size strlen(str)}//加入字符串memcpy(_str _size, str, strlen(str) 1);//在\0位置就是_str末尾str_size strlen(str);}//实现 也是使用push_back 和append函数string operator(char ch){push_back(ch);return *this;}string operator(const char* str){append(str);return *this;}//返回sizesize_t size() const //const表示修饰this指针也就是说只读如果是const对象也可以访问普通用户相当于权限的缩小也可也访问{return _size;}size_t capacity(){return _capacity;}private:char* _str;int _size;int _capacity;}; }构造函数和拷贝构造 默认构造函数和带参构造函数合并使用缺省参数 拷贝构造函数我们要使用深拷贝因为如果是浅拷贝仅仅是将数值传给新的string对象但是两者对应一个地址一个空间当析构一个string对象后另一个对象再次析构就会报错。 string(const char* str ) //字符串自带\0:_str(new char[strlen(str) 1]) //因为我们底层用的数组所以一定要多开一位空间存放\0, _size(strlen(str)), _capacity(strlen(str)) {//存储字符串strcpy(_str, str); //传入字符串的时候一般都是结尾为\0中间有\0的都是我们为string对象增加的。所以这个地方还是使用strcpy即可 }//拷贝构造 string(const string s) {//深拷贝就是创建一个大小一样的空间_str new char[s._capacity 1];strcpy(_str, s._str);_size s._size;_capacity s._capacity; }push_back和append的实现 想要实现push_back和append函数都要在底层中考虑是否需要扩容那么我们就顺势要写出reserve函数让其来判断是否需要扩容。 //reserve 保留容量 可以扩容 void reserve(size_t n) //只是改变capacity 不改变size {if (n _capacity){//新建一个字符数组cout reserve- n endl;char* new_str new char[n 1];//更改容量//strcpy(new_str, _str);memcpy(new_str, _str, _size 1);delete[] _str;_str new_str;_capacity n;} } void push_back(char ch) {if (_size _capacity){reserve(_capacity 0 ? 4 : _capacity * 2);}//加入字符_str[_size] ch;_size;_str[_size] \0; } void append(const char* str) {if (_size strlen(str) _capacity){reserve(_size strlen(str));//至少保留_size strlen(str)}//加入字符串memcpy(_str _size, str, strlen(str) 1);//在\0位置就是_str末尾str_size strlen(str); }注意为什么拷贝字符串内容的时候用memcpy而不是strcpy这是因为string中可能中间会有\0memcpy是根据第三个参数来定要拷贝的字符长度而strcmpy是根据要拷贝的字符串的\0出现的位置所以使用memcpy更加合适。 strcpy和memcpy的对比 char * strcpy ( char * destination, const char * source );void * memcpy ( void * destination, const void * source, size_t num ); operator的实现 我们实现了push_back和append之后就可以直接复用这两个函数实现operator string operator(char ch) {push_back(ch); //插入一个字符的时候return *this; } string operator(const char* str) {append(str); //插入字符串的时候return *this; }//因为string对象在该函数之后不会释放空间所以传引用返回提高效率string常用函数的实现 下面主要是对于insert、find、erase、substr、resize、一系列重载运算符等的实现 insert的实现 我们主要实现两种insert函数 1.在pos位置上插入n个字符c 2.在pos位置上插入字符串str string insert(size_t pos, size_t n, char c) {//1.先判定pos是否正确assert(pos _size);//2.扩容reserve(_size n);//3.在pos位置上开始挪动n个字符size_t end _size;//因为如果pos为0的时候无符号整型0减去1end pos比较 为一个巨大值使得该循环无法停止//npos是static变量定义为-1;while (end pos end ! npos){_str[end n] _str[end];--end;}//4.添加n个字符for (int i 0; i n; i){_str[pos i] c;}_size n;return *this; } string insert(size_t pos, const char*str) {//1.pos的判定assert(pos _size);//2.扩容int len strlen(str);reserve(_size len);//3.在pos位置上移动len个字符size_t end _size;while (end pos end ! npos){_str[end len] _str[end];--end;}//4.将str字符串的字符依次输入for (int i 0; i len; i){_str[pos i] str[i];}//5.最后_size增加_size len;return *this; } 注意npos的使用是为了防止size_t无符号整型在于整型pos比较时候的强制转换整型提升得到一个巨大值造成无限循环。 erase的实现 主要就是判断len是否等于npos或者poslen_size分两种情况是否从pos删除完实际上就是在pos位置上加上\0即可反之就是间隔len个距离向前移动字符直到poslen_size最后_size-len string erase(size_t pos 0, size_t len npos) {assert(pos _size);if (len npos || pos len _size){//表示从pos位置删完_str[pos] \0;_size pos;}else {//从pos位置删除len个字符//向前挪动size_t end pos;while (endlen _size) {_str[end] _str[end len];end;}//此时end_size//_str[end] \0;_size - len;}return *this; }find的实现 find的实现就是遍历找到符合条件的下标并返回 size_t find(char ch, size_t pos 0) const {assert(pos _size);for (size_t i pos; i _size; i){if (_str[i] ch){return i;}}return npos; //没有找到返回-1 } size_t find(const char* s, size_t pos 0) const {//使用strstrassert(pos _size);const char* str strstr(_strpos, s); //使用str函数进行比较是否有对应的字符串if (str){return str-_str;//两个指针相减得到的是地址的偏移量}else {return npos;} }substr的实现 substr的实现就是判断要解决的n的数值然后新建一个string字符串将从pos位置开始的n个字符依次添加到这个新字符串中最后返回新字符串 //substr的实现 string substr(size_t pos 0, size_t len npos) {assert(pos _size);size_t n len;//如果缺省lennpos 或者是截取的范围大于_sizeif (len npos || pos len _size){n _size - pos; }//创建一个新的字符数组string new_str;new_str.reserve(n);for (size_t i pos; i n pos; i){new_str _str[i];}return new_str; }resize的实现 resize底层是有reserve的即需要判断是否需要扩容满足_size_capacity //实现resize void resize(size_t n, char ch \0) {//两种情况1.n_size 直接赋值\0 2.判断是否扩容 if (n _size){_size n;_str[_size] \0;}else{reserve(n);//让reserve来判断是否是需要扩容for (size_t i _size; i n; i){_str[i] ch;}_size n;_str[_size] \0;} }opeartor重载运算符 重载运算符只要实现一两个就能实现其他下面我们实现的是operator 和operator 然后通过调用这两个函数来实现其他operator //字符串比较按照ascii比较//bool operator(const string s)//{// int nummemcmp(_str, s._str, _size s._size?s._size : _size);// //如果在最小长度下前面数值小于后者 num返回的是负数// // return num 0 ? _size s._size : num 0;// //如果如果num为0说明等于且前者长度小于后者返回真值反之返回//} bool operator(const string s) {size_t i1 0;size_t i2 0;int num _size s._size ? s._size : _size; //得到两者最小的长度while (i1 num i2 num){if (_str[i1] s._str[i2]) //只要不相等就返回{return true;}else if(_str[i1] s._str[i2]) {return false;}else{i1; //该字符相当那么继续i2;}}return _size s._size; //现在退出循环说明前num个字符都相等如果此时_sizes._size 那么返回真反之返回假 } bool operator(const string s) {return _size s._size memcmp(_str, s._str, _size s._size ? s._size : _size) 0; //两者字符长度相等且通过memcpy返回值是否为0来判断函数返回值 } //我们把 _size s._size 放在前面那么后面只需要memcpy(_str,s._str,_size)0即可 bool operator(const string s) {return *this s || *this s; } bool operator(const string s) {return !(*this s); } bool operator(const string s) {return !(*this s); } //访问指定下标的字符 //operator[]的实现 // char operator[](size_t pos) {//可读写 pos表示下标assert(pos _size);return _str[pos]; //返回的是单个字符所以用char 且_str变量离开该函数依旧存在可以使用返回 } string operator(const string s) {if (this ! s){//调用拷贝构造函数 将s的数据给tmpstring tmp(s);std::swap(_str, tmp._str);std::swap(_size, tmp._size);std::swap(_capacity, tmp._capacity);//进行交换交换之后tmp在函数结束之后就会释放空间但是其通过拷贝构造函数生成的新的string对象中的数值留给了*this对象}return *this; }流插入和流提取 //流提取 ostream operator(ostream out, const String::string s) {//就是将s字符串中的每一个字符都加载到out中for (auto ch : s){out ch;}return out; } //流插入 istream operator(istream in, String::string s) {//判断一个字符是否结束 按照空格或者\0来判断s.clear();char buff [128];char ch in.get();//get 字符int i 0;while (ch || ch \n){ch in.get(); //处理缓冲区前面的空格和换行}while (ch ! ch ! \n){buff[i] ch;//如果输入的数值在127之外if (i 127) //先i 相当于从1到127{//留出来一个空间给\0 所以只能这样buff[i] \0;s buff;i 0;//要重置i}ch in.get();}if (i ! 0){//如果i不0的话那就是说数值长度在127之内 直接扩容buff[i] \0;s buff;}return in; }总结 有关于插入以及添加字符、字符串的函数都需要考虑容量的问题所以底层会有reserve比如push_back、append、resize、insert、等函数find的实现就是遍历以及使用strstr函数快速方便的得到下标erase、insert等函数都会涉及到移动数组元素erase向前移动insert向后移动重载运算符的实现可以方便我们使用string类 最后附上完整模拟实现string类的代码 #define _CRT_SECURE_NO_WARNINGS #includeiostream #includeassert.h #includemath.h //模拟实现string namespace String {class string {public://迭代器 string中的迭代器实际上就是指针typedef char* iterator;typedef const char* const_iterator;iterator begin(){//begin 表示的是string的首元素地址return _str;}iterator end(){//end 返回string最后一个元素的下一个位置也就是\0return _str _size;}const_iterator begin() const{//begin 表示的是string的首元素地址return _str;}const_iterator end() const{//end 返回string最后一个元素的下一个位置也就是\0return _str _size;}//默认构造函数//string() // :_str(new char[1])// ,size(0)// ,capacity(0)//{// _str[0] \0;//}//带参构造函数 字符串//string(const char* str)// :_str(new char[strlen(str)])// ,size(strlen(str))// ,capacity(strlen(str))//{// //存储字符串// strcpy(_str, str);//}//默认构造和带参构造合并使用缺省参数string(const char* str) //字符串自带\0:_str(new char[strlen(str)1]), _size(strlen(str)), _capacity(strlen(str)){//存储字符串strcpy(_str, str);}//拷贝构造//string(const string s)//{// //深拷贝就是创建一个大小一样的空间// _str new char[s._capacity 1];// strcpy(_str, s._str);// _size s._size;// _capacity s._capacity;//}string(const string s){_str new char[s._capacity 1];memcpy(_str, s._str,s._size 1);_size s._size;_capacity s._capacity;}//析构函数~string(){delete[] _str;_str nullptr;_size _capacity 0;}void Print() {cout _str \t _size \t _capacity endl;}//size_t 无符号整型const char* c_str(){return _str;}//返回sizesize_t size() const //const表示修饰this指针也就是说只读如果是const对象也可以访问普通用户相当于权限的缩小也可也访问{return _size;}//operator[]的实现// char operator[](size_t pos){//可读写 pos表示下标assert(pos _size);return _str[pos]; //返回的是单个字符所以用char 且_str变量离开该函数依旧存在可以使用返回}//对于const对象const char operator[](size_t pos) const //修饰const对象前面const修饰的话表示不可以被修改后面const对象就修饰this指针 const String::string* this{//只读assert(pos _size);return _str[pos];}//reserve 保留容量 可以扩容void reserve(size_t n) //只是改变capacity 不改变size{if (n _capacity){//新建一个字符数组cout reserve- n endl;char* new_str new char[n 1];//更改容量//strcpy(new_str, _str);memcpy(new_str, _str, _size 1);delete[] _str;_str new_str;_capacity n;}}//push_back void push_back(char ch){if (_size _capacity){reserve(_capacity 0 ? 4 : _capacity * 2);}//加入字符_str[_size] ch;_size;_str[_size] \0;}void append(const char* str){if (_size strlen(str) _capacity){reserve(_size strlen(str));//至少保留_size strlen(str)}//加入字符串memcpy(_str _size, str, strlen(str)1);//在\0位置就是_str末尾str_size strlen(str);}//实现 也是使用push_back 和append函数string operator(char ch){push_back(ch);return *this;}string operator(const char* str){append(str);return *this;}string insert(size_t pos, size_t n, char c){//1.先判定pos是否正确assert(pos _size);//2.扩容reserve(_size n);//3.在pos位置上开始挪动n个字符size_t end _size;//因为如果pos为0的时候无符号整型0减去1end pos比较 为一个巨大值使得该循环无法停止//npos是static变量定义为-1;while (end pos end ! npos){_str[end n] _str[end];--end;}//4.添加n个字符for (int i 0; i n; i){_str[pos i] c;}_size n;return *this;}string insert(size_t pos, const char*str){//1.pos的判定assert(pos _size);//2.扩容int len strlen(str);reserve(_size len);//3.在pos位置上移动len个字符size_t end _size;while (end pos end ! npos){_str[end len] _str[end];--end;}//4.将str字符串的字符依次输入for (int i 0; i len; i){_str[pos i] str[i];}//5.最后_size增加_size len;return *this;}//从pos位置开始删除len长度字符string erase(size_t pos 0, size_t len npos){assert(pos _size);if (len npos || pos len _size){//表示从pos位置删完_str[pos] \0;_size pos;}else {//从pos位置删除len个字符//向前挪动size_t end pos;while (endlen _size) {_str[end] _str[end len];end;}//此时endlen_size//_str[end] \0;_size - len;}return *this;}//findsize_t find(char ch, size_t pos 0) const{assert(pos _size);for (size_t i pos; i _size; i){if (_str[i] ch){return i;}}return npos; //没有找到返回-1}size_t find(const char* s, size_t pos 0) const{//使用strstrassert(pos _size);const char* str strstr(_strpos, s);if (str){return str-_str;//两个指针相减得到的是地址的偏移量}else {return npos;}}//substr的实现string substr(size_t pos 0, size_t len npos){assert(pos _size);size_t n len;//如果缺省lennpos 或者是截取的范围大于_sizeif (len npos || pos len _size){n _size - pos; }//创建一个新的字符数组string new_str;new_str.reserve(n);for (size_t i pos; i n pos; i){new_str _str[i];}return new_str;}void clear(){_str[0] \0;_size 0;}//实现resizevoid resize(size_t n, char ch \0){//两种情况1.n_size 直接赋值\0 2.判断是否扩容 if (n _size){_size n;_str[_size] \0;}else{reserve(n);//让reserve来判断是否是需要扩容for (size_t i _size; i n; i){_str[i] ch;}_size n;_str[_size] \0;}}//字符串比较按照ascii比较//bool operator(const string s)//{// int nummemcmp(_str, s._str, _size s._size?s._size : _size);// //如果在最小长度下前面数值小于后者 num返回的是负数// // return num 0 ? _size s._size : num 0;// //如果如果num为0说明等于且前者长度小于后者返回真值反之返回//}bool operator(const string s){size_t i1 0;size_t i2 0;int num _size s._size ? s._size : _size;while (i1 num i2 num){if (_str[i1] s._str[i2]){return true;}else if(_str[i1] s._str[i2]) {return false;}else{i1;i2;}}return _size s._size;}bool operator(const string s){return _size s._size memcmp(_str, s._str, _size) 0;}bool operator(const string s){return *this s || *this s;}bool operator(const string s){return !(*this s);}bool operator(const string s) {return !(*this s);}//string operator(const string s)//{// if (this ! s)// {// //如果不是同一个string// //深拷贝// char* new_str new char[s._capacity 1];// memcpy(new_str, s._str, s._size);// //删除原来地址// delete[] _str;// //新指向一个new_str// _str new_str;// //更改容量和size// _capacity s._capacity;// _size s._size;// }// return *this;//}string operator(const string s){if (this ! s){//调用拷贝构造函数 将s的数据给tmpstring tmp(s);std::swap(_str, tmp._str);std::swap(_size, tmp._size);std::swap(_capacity, tmp._capacity);//进行交换交换之后tmp在函数结束之后就会释放空间但是其通过拷贝构造函数生成的新的string对象中的数值留给了*this对象}return *this;}size_t capacity(){return _capacity;}size_t size(){return _size;}//无穷递归的问题反复调用堆栈// std::swap(*this,tmp)//定义属性private:char* _str;int _size;int _capacity;public:const static size_t npos;};const size_t string::npos -1; } //流提取 ostream operator(ostream out, const String::string s) {//就是将s字符串中的每一个字符都加载到out中for (auto ch : s){out ch;}return out; } //流插入 istream operator(istream in, String::string s) {//判断一个字符是否结束 按照空格或者\0来判断s.clear();char buff [128];char ch in.get();//get 字符int i 0;while (ch || ch \n){ch in.get(); //处理缓冲区前面的空格和换行}while (ch ! ch ! \n){buff[i] ch;//如果输入的数值在127之外if (i 127) //先i 相当于从1到127{//留出来一个空间给\0 所以只能这样buff[i] \0;s buff;i 0;//要重置i}ch in.get();}if (i ! 0){//如果i不0的话那就是说数值长度在127之内 直接扩容buff[i] \0;s buff;}return in; }
http://www.zqtcl.cn/news/375734/

相关文章:

  • 石嘴山北京网站建设h5网站建设
  • 滨州区建设局网站中国建行官网首页
  • 网站建设服务网站网站建设销售实习
  • 网站注册都需要什么给装修公司做推广的网站
  • me域名的网站wordpress 扩展字段
  • 新开三端互通传奇网站企业推广方式有哪些
  • 怎么制作网站页面做理论的网站
  • 哪家公司做跳转网站wordpress 网页缩放
  • 小说网站建设的支柱深圳建设发展集团有限公司
  • 陕西高速公路建设网站做网站不用编程
  • wordpress网站秒开网站建设设计理念
  • html5 网站模板永久免费的仓库管理软件
  • 贵州网站seo厦门网站设计多少钱
  • 哈市哪里网站做的好合作网站seo
  • 找苏州网站建设网站维护提醒php文件
  • 哪些网站做推广效果好与市场营销有关的网站
  • 有什么网站可以做设计赚钱吗专业vi设计公司哪家强
  • 一般的网站是由什么语言做的网站建设怎么问问题
  • 开源系统 网站阿里云虚拟主机网站
  • 摄影师作品网站网站怎么做搜素引擎
  • 做网站定金是多少钱开网站建设公司心得
  • 网站不备案怎么做网页淘宝客电子商务的网站建设的可用性
  • 傻瓜自助建站软件怎样进网站空间服务器
  • 黑龙江网站建站建设wordpress 邮件
  • 免费发布信息网站有哪些豆芽网站建设
  • 无锡做网站优化公司互动营销用在哪些推广上面
  • 每一个网站都是响应式吗销售渠道策略
  • 凡科平台网站怎么建设广州网站建设信科网络
  • 网站建设公司的服务特点seo实战密码电子书
  • 网站开发保密协议范本北京市建设工程信息网查询