#include <iostream>
#include <String>
#include<assert.h>
#pragma warning(disable:4996)
using namespace std;
namespace bit
{
class string
{
friend ostream& operator<<(ostream& out, const string& s);
friend istream& operator>>(istream& in, string& s);
public:
static const size_t npos = -1;
public:
string(const char* s = "") :m_str(nullptr)
{
m_capacity = m_size = strlen(s);
m_str = new char[m_capacity + 1];
strcpy(m_str, s);
}
string(const string& s) :m_str(nullptr), m_size(0), m_capacity(0)
{
string tmp(s.m_str);
_swap(tmp, *this);
}
string& operator=(const string& s)
{
if (this != &s)
{
string tmp(s);
_swap(tmp, *this);
}
return *this;
}
~string()
{
if (m_str)
{
delete[]m_str;
m_str = nullptr;
}
m_size = 0;
m_capacity = 0;
}
public:
int size()const
{
return m_size;
}
int capacity()const
{
return m_capacity;
}
bool empty()const
{
return m_size == 0;
}
void clear()
{
m_size = 0;
m_str[0] = '\0';//第一个下标填入结束标志符
}
const char* c_str() const
{
return m_str;
}
public:
typedef char* iterator; //模拟迭代器
iterator begin()
{
return m_str;
}
iterator end()
{
return m_str + m_size;
}
public:
void push_back(char x)
{
if (m_size >= m_capacity)
{
reserve(m_capacity * 2);
}
m_str[m_size++] = x;
m_str[m_size] = '\0';
}
void reserve(int new_cpy)
{
if (new_cpy > m_capacity)//新容量>目前容量才会扩容
{
//扩容之后,m_str之前所存的内容仍要存在
char* new_str = new char[new_cpy + 1];
memcpy(new_str, m_str, m_size + 1);
//mecpy(目标,要复制的数据源,要复制的大小个数(包括\0,所以加一));
m_capacity = new_cpy;
delete[]m_str; //m_str[0]='\0';
m_str = new_str;
}
}
public:
string& operator+=(char c) //追加一个字符
{
push_back(c); //插入一个字符
return *this;
}
void append(const char* str) //追加字符串
{
int str_len = strlen(str);
if (m_size + str_len > m_capacity)//容量不够追加时,扩容
{
reserve((m_size + str_len) * 2);
}
memcpy(m_str + m_size, str, sizeof(str));
m_size = m_size + str_len;
m_str[m_size] = '\0';
}
string& operator+=(const char* str)
{
append(str);
return *this;
}
void resize(int newSize, char c = '\0')//调整大小为newSize,且填充字符c
{
if (newSize > m_size) //调整后的大小>原大小时:
{
if (newSize > m_capacity) //(1)调整后的大小>容量时,需扩容
{
reserve(newSize * 2);
}
//将调整后相较于原大小多出的空间将其填充字符c,用memset进行初始化即可
//memset(起始位置,字符c,size) :从起始位置开始初始化为字符c,共初始化size个大小
memset(m_str + m_size, c, newSize - m_size);
}
m_size = newSize;
m_str[m_size] = '\0';
}
char& operator[](int i)
{
assert(i < m_size && i >= 0);
return m_str[i];
}
const char& operator[](int i)const
{
assert(i >= 0 && i < m_size);
return m_str[i];
}
bool operator<(const string& s)
{
return (strcmp(m_str, s.m_str) < 0);
}
bool operator>(const string& s)
{
return (strcmp(m_str, s.m_str) > 0);
}
bool operator<=(const string& s)
{
return !(*this > s);
}
bool operator>=(const string& s)
{
return !(*this < s);
}
bool operator==(const string& s)
{
return (strcmp(m_str, s.m_str) == 0);
}
bool operator!=(const string& s)
{
return !(*this == s);
}
public:
// 返回c在string中第一次出现的位置
size_t find(char c, size_t pos = 0) const
{
for (size_t i = pos; i < m_size; i++)
{
if (m_str[i] == c)
{
return i;
}
}
return npos;
}
// 返回子串s在string中第一次出现的位置
size_t find(const char* s, size_t pos = 0) const
{
size_t i = pos, j = 0, s_len = strlen(s);
while (i < m_size && j < s_len)
{
if (m_str[i] == s[j])
{
i++;
j++;
}
else
{
i = i - j + 1; //回溯到查找的下一个位置
j = 0;
}
}
if (j >= s_len)
{
return i - j; //返回的是子串在主串中的第一个字符位置
}
return npos;
}
// 在pos位置上插入字符c/字符串str,并返回该字符的位置
string& insert(size_t pos, char c)
{
if (m_size + 1 > m_capacity)
reserve((m_size + 1) * 2);
for (size_t i = m_size; i > pos; i--)
{
m_str[i] = m_str[i - 1];//右移
}
m_str[pos] = c;
m_size = m_size + 1;
m_str[m_size] = '\0';
return *this;
}
// 删除从pos位置起的len个元素,并返回该元素的下一个位置
string& erase(size_t pos, size_t len = 1)
{
for (size_t i = pos + len; i < m_size; i++)
{
m_str[i - len] = m_str[i]; //左移
}
m_size -= len;
m_str[m_size] = '\0';
return *this;
}
protected:
static void _swap(string& s1, string& s2) //交换要用引用or指针!!!
{
std::swap(s1.m_str, s2.m_str);
std::swap(s1.m_capacity, s2.m_capacity);
std::swap(s1.m_size, s2.m_size);
}
private:
char* m_str;
int m_size;
int m_capacity;
};
ostream& operator<<(ostream& out, const string& s)
{
out << s.m_str;
return out;
}
istream& operator>>(istream& in, string& s)
{
static size_t default_buf_size = 5; //默认开辟大小为5的空间存放,当超过大小后自动增长
int count = 0;//存入的字符数,
int capacity = default_buf_size;
char* str = (char*)malloc(sizeof(char) * capacity);
char* buf = str;
//getchar()获取一个字符,获取完会自动走向下一个、
while((*buf = getchar()) == ' ' || *buf == '\n');//跳过最开始的空格和换行符
for (;;)
{
if (*buf == ' ' || *buf == '\n')
{
*buf = '\0';
break;
}
else if (count+1>= capacity)//当输入的字符数超过默认大小时,自动增长空间
//由于先加加指针才存入内容,故当buf指针指向最后一个位置时,此时再想存入字符时,buf仍要先++,但此时越界
//且当前count=capacity-1;所以当count+1>=capapcity时要扩容
{
capacity *= 2;
str = (char*)realloc(str, capacity);//在str追加开辟capacity空间
buf = str + count ;//重新定位buf位置
}
++buf;//先加加指针,
*buf = getchar();//再存入字符
count++;
}
s.m_capacity = capacity;
s.m_size = count;
delete[]s.m_str;
s.m_str = str;
return in;
}
}
int main()
{
bit::string s1;
cout << "构造函数s1:" << s1 << endl;
bit::string s2("C+");
cout << "构造函数s2:" << s2 << endl;
bit::string s3(s2);
cout << "拷贝构造s3:";
for (int i = 0; i < s3.size(); i++)
cout << s3[i];
cout << endl;
const char* str = s3.c_str();
bit::string s4;
s4 = s3;
cout << "赋值函数s4:" << s4 << endl;
bit::string::iterator it = s4.begin();
cout << "迭代器打印s4:";
while (it != s4.end() - 1)
{
cout << *it;
it++;
}
cout << endl;
s4.clear();
cout << "清理s4:" << s4 << endl;
if (s4.empty())
{
cout << "s4为空" << endl;
}
else
{
cout << "s4不空" << endl;
}
s4.push_back('x');
s4.push_back('t');
s4.push_back('t');
cout << "插入3个元素:" << s4 << " s4.m_capacity:" << s4.capacity() << " s4.m_size:" << s4.size() << endl;
s4.reserve(5);
cout << s4 << " s4.m_capacity:" << s4.capacity() << " s4.m_size:" << s4.size() << endl;
s4.append("123");
cout << "追加s4:" << s4 << " s4.m_capacity:" << s4.capacity() << " s4.m_size:" << s4.size() << endl;
s4 += "56";
cout << "+=(字符串) s4:" << s4 << " s4.m_capacity:" << s4.capacity() << " s4.m_size:" << s4.size() << endl;
s4.resize(13, 'o');
cout << "调整大小 s4:" << s4 << " s4.m_capacity:" << s4.capacity() << " s4.m_size:" << s4.size() << endl;
bit::string s5 = ("helhlo");
bit::string s6 = ("hellohel");
if (s5 > s6)
cout << "s5>s6" << endl;
else if (s5 < s6)
cout << "s5<s6" << endl;
else
cout << "s5==s6" << endl;
size_t pos = s5.find('h', 1);
cout << "查找字符 s5:" << pos << endl;
size_t pos1 = s6.find("hel", 6);
cout << "查找字符串(模式匹配) s6:" << pos1 << endl;
bit::string s7 = "1234";
cout << s7 << " s7.m_capacity: " << s7.capacity() << " s7.m_size:" << s7.size() << endl;
s7.insert(0, '5');
cout << "按位置插入1个字符 s7: " << s7 << " s7.m_capacity: " << s7.capacity() << " s7.m_size:" << s7.size() << endl;
s7.erase(0, 2);
cout << "按位置删除len个字符 s7: " << s7 << " s7.m_capacity: " << s7.capacity() << " s7.m_size:" << s7.size() << endl;
bit::string s8;
cin >> s8;
cout <<"cin s8: "<< s8 << endl;
return 0;
}
//=====================================================================================================================
//现代写法模拟string类
利用了临时对象的思想,进行原有空间的释放
/*class String
{
friend ostream& operator<<(ostream& out, const String& s);
public:
String(const char* s = "")
{
m_str = new char[strlen(s) + 1];
strcpy(m_str, s);
}
String(const String &s):m_str(nullptr)//拷贝构造先把要拷贝的初始化
{
String tmp(s.m_str);
//申请一个临时类空间,由字符串(要复制的类的字符串指针)构造类tmp,
//然后把要复制的类内容与这个临时类内容交换,
//拿到复制内容与临时类的地址,这是为了防止多次释放同一空间所造成运行崩溃
std::swap(tmp.m_str, m_str);
}
String& operator=(const String s)
{
if (&s != this) //判断两个类是否相等,可判断首地址是否相等
{
String tmp(s);
std::swap(tmp.m_str, m_str);
}
return *this;
}
~String()
{
if (m_str != nullptr)
{
delete[]m_str;
m_str = nullptr;
}
}
private:
char* m_str;
};
ostream& operator<<(ostream& out, const String& s)
{
out << s.m_str;
return out;
}
int main()
{
String s1="123"; //由字符串创建对象,即用构造函数
cout << s1 << endl;
String s2("hello"); //由字符串创建对象,即用构造函数
cout << s2 << endl;
String s3(s2); //调用拷贝构造创建对象
cout << s3 << endl;
String s4 = s3; //调用拷贝构造创建对象
cout << s4 << endl;
String s5;
s5 = s4; //调用赋值函数
cout << s5 << endl;
return 0;
}*/
//====================================================================================================================
//传统模拟string类
/*class String
{
public:
friend ostream& operator<<(ostream &out,const String &s);
public:
String(const char* str = " ")
{
m_str = new char[strlen(str) + 1];//加一加的是最后的/0
strcpy(m_str, str);
}
String& operator=(String s)
{
if (this != &s)
{
char* p = new char[strlen(s.m_str) + 1];
//重新申请一块空间复制s,这是为了防止浅赋值所造成的对一块空间多次释放的问题。
strcpy(p, s.m_str);
delete[]m_str;
m_str = p;
}
return *this;
}
String(const String& s)
{
m_str = (new char[strlen(s.m_str) + 1]);
strcpy(m_str, s.m_str);
}
~String()
{
delete[]m_str;
m_str = nullptr;
}
private:
char* m_str;
};
ostream& operator<<(ostream& out, const String &s)
{
out << s.m_str;
return out;
}
int main()
{
String s1="hello";
cout << s1 << endl;
String s2(s1);
cout << s2 << endl;
String s3=s2;
cout << s3 << endl;
return 0;
}*/
/*---------------------------------------------------------------------------------------------------------------------/*
int main()
{
String str = "Hello Bit.";
String::iterator it = str.begin();
while (it != str.end())
{
if (*it != ' ')
cout << *it;
else
str.erase(it);
it++;
}*/
/*String strText = "How are you?";
String strSeparator = " ";
String strResult;
int size_pos = 0;
int size_prev_pos = 0;
while ((size_pos = strText.find_first_of(strSeparator, size_pos)) != String::npos)
{
strResult = strText.substr(size_prev_pos, size_pos - size_prev_pos);
cout << strResult << " ";
size_prev_pos = ++size_pos;
}
if (size_prev_pos != strText.size())
{
strResult = strText.substr(size_prev_pos, size_pos - size_prev_pos);
cout << strResult << " ";
}
cout << endl;*/
/*String a = "hello world";
String b = a;
if (a.c_str() == b.c_str())
{
cout << "true" << endl;
}
else
cout << "false" << endl;
String c = b;
c = "";
if (a.c_str() == b.c_str())
{
cout << "true" << endl;
}
else
cout << "false" << endl;
a = "";
if (a.c_str() == b.c_str())
{
cout << "true" << endl;
}
else
cout << "false" << endl;
return 0;
}*/
c++ string类(模拟实现)
最新推荐文章于 2024-10-02 15:47:04 发布