String类的实现很好的体现了C++面向对象的一些特性,也是很多面试C++的时候一些面试官常用来考察被面试者的面向对象基础的一个方式。掌握String类的定义与实现能帮助我们很好的理解C++面向对象的三大特性,并能使我们更好的掌握String类型的使用。
//String.h
#ifndef STRING_H
#define STRING_H
#include <iostream>
using namespace std;
class String
{
public:
String(const char *s = NULL); //定义带默认值的构造函数
~String();
String &operator = (const char* s); //重载=运算符,char* 类型赋值
String &operator = (const String &s); //重载=运算符,String类型赋值
friend String &operator >> (istream &is, String &s); //重载>>运算符
friend String &operator << (ostream &os, String &s); //重载<<运算符
String &operator + (const String &s); //重载+运算符,与String类型相加
String &String::operator + (const char *s); //重载+=运算符,char* 类型相加
String &operator += (const String &s); //重载+=运算符,与String类型相加
String &String::operator += (const char *s);//重载+运算符,char* 类型相加
bool operator>(const String &s); //重载>运算符
bool operator<(const String &s);
bool operator>=(const String &s);
bool operator<=(const String &s);
bool operator!=(const String &s);
bool operator==(const String &s);
char &operator [](int a);
String substr(); //取出所有字符
String substr(int n); //返回从n往后的字符
String substr(int n1, int n); //取子串函数,从n1下标开始,取出n个字符
void swap(String &s); //与S交换字符串
int size()
{
return len;
}
int length()
{
return len;
}
int find(const String &s, int pos=0); //从pos开始查找字符c在当前字符串的位置
int find(char c, int pos=0);
int find(char *s, int pos, int n); //从pos开始查找字符串s中前n个字符在当前串中的位置
int find(char *s, int pos=0); //查找子串
int rfind(const String &s, int pos=0); //从pos开始从后向前查找字符c在当前字符串的位置
int rfind(char c, int pos=0);
int rfind(char *s, int pos, int n); //从pos开始从后向前查找字符串s中前n个字符在当前串中的位置
int rfind(char *s, int pos=0);
void replace(int n1, int n, String &s); //替换当前字符串中的字符,n1起始下标,n是替换掉的个数,s是用来替换的字符串
void insert(int n, char *s); //在当前串的下标位置之前,插入s串
void insert(int n1, String &s, int n2, int m);//在当前串的n1下标插入s串,n2是s串中要插入的起始下标,m是S串中插入的字符个数
String &append(char *s); //在尾部插入字符串
String &append(const String &s);
String &append(const String &s, int n1, int n); //把s字符串从n1开始,n个字符附到字符串中
String &append(char *s, int n); //把字符串S前n个字符附到字符串中
String &append(int n, char ch); //将n个ch赋给字符串
String &push_back(char s); //在尾部插入字符串
String &erase(int n); //从N开始往后删除字符
String &erase(int n1, int n); //删除字符,从n1开始删除n个字符
void clear(); //删除全部字符
int compare(String &s); //比较
bool empty();
char at(int n); //对元素包含的字符进行访问,病检查是否有效
String &assign(char *s); //赋值
String &assign(const String &s);
String &assign(const String &s, int n1, int n); //把s字符串从n1开始,n个字符附到字符串中
String &assign(char *s, int n); //把字符串S前n个字符附到字符串中
String &assign(int n, char ch); //将n个ch赋给字符串
private:
char *ptr;
int len;
};
#endif
//String.cpp
#include "String.h"
String::String(const char *s)
{
if (s == NULL)
{
len = 0;
ptr = new char[1];
*ptr = '\0';
}
else
{
len = strlen(s);
ptr = new char[len+1];
strcpy(ptr, s);
}
}
String::~String()
{
delete[] ptr;
ptr = NULL;
}
String &String::operator = (const char* s)
{
delete[] ptr;
len = strlen(s);
ptr = new char[len+1];
strcpy(ptr, s);
return *this;
}
String &String::operator = (const String &s)
{
delete[] ptr;
if (this == &s)
return *this;
len = s.len;
ptr = new char[len+1];
strcpy(ptr, s.ptr);
return *this;
}
String &operator >> (istream &is, String &s)
{
char temp[100];
int i=0;
do
{
char ch;
cin.get(ch);
temp[i] = ch;
i++;
}
while (temp[i-1] !='\n');
temp[i-1] = '\0';
s.len = i-1;
s.ptr = new char[s.len+1];
strcpy(s.ptr, temp);
return s;
}
String &operator << (ostream &os, String &s)
{
os << s.ptr;
return s;
}
String &String::operator + (const String &s)
{
char *temp = new char[len+1];
len = len + s.len;
strcpy(temp, ptr);
delete[] ptr;
ptr = new char[len+1];
strcpy(ptr, temp);
strcat(ptr, s.ptr); //字符串连接
delete[] temp;
temp = NULL;
return *this;
}
String &String::operator + (const char *s)
{
char *temp = new char[len+1];
len = len + strlen(s);
strcpy(temp, ptr);
delete[] ptr;
ptr = new char[len+1];
strcpy(ptr, temp);
strcat(ptr, s); //字符串连接
delete[] temp;
temp = NULL;
return *this;
}
String &String::operator += (const String &s)
{
char *temp = new char[len+1];
len = len + s.len;
strcpy(temp, ptr);
delete[] ptr;
ptr = new char[len+1];
strcpy(ptr, temp);
strcat(ptr, s.ptr); //字符串连接
delete[] temp;
temp = NULL;
return *this;
}
String &String::operator += (const char *s)
{
char *temp = new char[len+1];
len = len + strlen(s);
strcpy(temp, ptr);
delete[] ptr;
ptr = new char[len+1];
strcpy(ptr, temp);
strcat(ptr, s); //字符串连接
delete[] temp;
temp = NULL;
return *this;
}
bool String::operator > (const String &s)
{
for (int i=0; i<len; i++)
{
if (ptr[i] <= s.ptr[i])
return false;
}
if (s.len > len)
return false;
return true;
}
bool String::operator < (const String &s)
{
for (int i=0; i<len; i++)
{
if (ptr[i] >= s.ptr[i])
return false;
}
if (s.len < len)
return false;
return true;
}
bool String::operator >= (const String &s)
{
for (int i=0; i<len; i++)
{
if (ptr[i] < s.ptr[i])
return false;
}
if (s.len > len)
return false;
return true;
}
bool String::operator <= (const String &s)
{
for (int i=0; i<len; i++)
{
if (ptr[i] > s.ptr[i])
return false;
}
if (s.len < len)
return false;
return true;
}
bool String::operator == (const String &s)
{
if (s.len != len)
return false;
for (int i=0; i<len; i++)
{
if (ptr[i] != s.ptr[i])
return false;
}
return true;
}
bool String::operator != (const String &s)
{
if (s.len != len)
return true;
for (int i=0; i<len; i++)
{
if (ptr[i] != s.ptr[i])
return true;
}
return false;
}
char &String::operator [](int a)
{
return ptr[a];
}
String String::substr()
{
return *this;
}
String String::substr(int n)
{
String temp;
temp.ptr = new char[len-n+1];
temp.len = len-n;
for (int i=n; i<len; i++)
{
temp.ptr[i-n] = ptr[i];
}
temp.ptr[len-n] = '\0';
return temp;
}
String String::substr(int n1, int n)
{
String temp;
temp.ptr = new char[n+1];
temp.len = n;
for (int i=n1; i<n1+n; i++)
{
temp.ptr[i-n1] = ptr[i];
}
temp.ptr[n] = '\0';
return temp;
}
void String::swap(String &s)
{
char *temp = new char[len+1];
strcpy(temp, ptr);
if (*ptr)
delete[] ptr;
ptr = new char[s.len+1];
strcpy(ptr, s.ptr);
delete[] s.ptr;
s.ptr = new char[len+1];
strcpy(s.ptr, temp);
delete[] temp;
temp = NULL;
}
int String::find(const String &s, int pos)
{
char *ch = s.ptr;
int length = s.len;
int next[100];
unsigned int i=1, j=0; //i是每个位子,j是回退的位子
next[1]=0;
while(i<=length)
{
if(j==0 || ch[i-1]==ch[j-1])
{
i++;
j++;
next[i] = j;
}
else
j = next[j]; //用上一个的 回退关系
}
i=1; //i是主串中的位子
j=1; //j匹配串的位子
char *temp = new char[len-pos+1];
for (int k=0; k<len-pos; k++)
{
temp[k] = ptr[k+pos];
}
temp[len-pos] = '\0';
while (i<=len-pos && j<=length)
{
if(j==0 || temp[i-1]==ch[j-1])
{
i++;
j++;
}
else j=next[j];
}
delete[] temp;
temp = 0;
if(j > length)
return i-length-1+pos;
else
return 0;
}
int String::find(char c, int pos)
{
char *temp = new char[len-pos+1];
for (int k=0; k<len-pos; k++)
{
temp[k] = ptr[k+pos];
}
temp[len-pos] = '\0';
for (int i=0; i<len-pos; i++)
{
if (temp[i] == c)
return i;
}
delete[] temp;
temp = NULL;
cout << "未找到" << endl;
return 0;
}
int String::find(char *s, int pos)
{
int next[100];
unsigned int i=1,j=0; //i是每个位子,j是回退的位子
next[1]=0;
while(i<=strlen(s))
{
if(j==0||s[i-1]==s[j-1])
{
i++;
j++;
next[i]=j;
}
else j=next[j]; //用上一个的 回退关系
}
i=1; //i是主串中的位子
j=1; //j匹配串的位子
char *temp = new char[len-pos+1];
for (int k=0; k<len-pos; k++)
{
temp[k] = ptr[k+pos];
}
temp[len-pos] = '\0';
while(i<=strlen(temp)&&j<=strlen(s))
{
if(j==0||temp[i-1]==s[j-1])
{
i++;
j++;
}
else j=next[j];
}
delete[] temp;
temp = NULL;
if(j>strlen(s))
return i-strlen(s)-1+pos;
else
return 0;
}
int String::find(char *s, int pos, int n)
{
int next[100];
unsigned int i=1,j=0; //i是每个位子,j是回退的位子
next[1]=0;
char *temp1 = new char[n+1];
for (int i=0; i<n; i++)
{
temp1[i] = s[i];
}
temp1[n] = '\0';
while(i<=n)
{
if(j==0||s[i-1]==temp1[j-1])
{
i++;
j++;
next[i]=j;
}
else j=next[j]; //用上一个的 回退关系
}
i=1; //i是主串中的位子
j=1; //j匹配串的位子
char *temp = new char[len-pos+1];
for (int k=0; k<len-pos; k++)
{
temp[k] = ptr[k+pos];
}
temp[len-pos] = '\0';
while(i<=strlen(temp)&&j<=n)
{
if(j==0||temp[i-1]==temp1[j-1])
{
i++;
j++;
}
else j=next[j];
}
if(j > n)
return i-n-1+pos;
else
return 0;
}
int String::rfind(const String &s, int pos)
{
int length = s.len;
char *ch = new char[length+1];
for (int k=0; k<length; k++)
{
ch[length-k-1] = s.ptr[k];
}
int next[100];
unsigned int i=1,j=0; //i是每个位子,j是回退的位子
next[1]=0;
while(i<=length)
{
if(j==0||ch[i-1]==ch[j-1])
{
i++;
j++;
next[i] = j;
}
else
j = next[j]; //用上一个的 回退关系
}
i = 1; //i是主串中的位子
j = 1; //j匹配串的位子
char *ch1 = new char[pos + 1+1];
for (int i=0; i<pos+1; i++)
{
ch1[pos-i] = ptr[i];
}
ch1[pos] = '\0';
while (i<=len && j<=length)
{
if(j==0 || ch1[i-1]==ch[j-1])
{
i++;
j++;
}
else j = next[j];
}
delete[] ch;
ch = NULL;
delete[] ch1;
ch1 = NULL;
if(j > length)
return len-i+1;
else
return 0;
}
int String::rfind(char c, int pos)
{
char *ch1 = new char[pos + 1 + 1];
for (int i=0; i<pos + 1; i++)
{
ch1[pos-i] = ptr[i];
}
ch1[pos+1] = '\0';
for (int i=0; i<pos+1; i++)
{
if (ch1[i] == c)
return pos-i;
}
delete[] ch1;
ch1 = NULL;
cout << "未找到字符!" << endl;
return 0;
}
int String::rfind(char *s, int pos, int n)
{
int length = n;
char *ch = new char[length+1];
for (int k=0; k<length; k++)
{
ch[length-k-1] = s[k];
}
int next[100];
unsigned int i = 1,j = 0; //i是每个位子,j是回退的位子
next[1] = 0;
while(i<=length)
{
if(j==0 || ch[i-1]==ch[j-1])
{
i++;
j++;
next[i] = j;
}
else
j = next[j]; //用上一个的 回退关系
}
i = 1; //i是主串中的位子
j = 1; //j匹配串的位子
char *ch1 = new char[pos + 1+1];
for (int i=0; i<pos+1; i++)
{
ch1[pos-i] = ptr[i];
}
ch1[pos] = '\0';
while (i<=len && j<=length)
{
if(j==0 || ch1[i-1]==ch[j-1])
{
i++;
j++;
}
else j = next[j];
}
delete[] ch;
ch = NULL;
delete[] ch1;
ch1 = NULL;
if(j > length)
return len-i+1;
else
return 0;
}
int String::rfind(char *s, int pos)
{
int length = strlen(s);
char *ch = new char[length+1];
for (int k=0; k<length; k++)
{
ch[length-k-1] = s[k];
}
int next[100];
unsigned int i = 1, j = 0; //i是每个位子,j是回退的位子
next[1] = 0;
while(i<=length)
{
if(j==0 || ch[i-1]==ch[j-1])
{
i++;
j++;
next[i] = j;
}
else
j = next[j]; //用上一个的 回退关系
}
i = 1; //i是主串中的位子
j = 1; //j匹配串的位子
char *ch1 = new char[pos + 1+1];
for (int i=0; i<pos+1; i++)
{
ch1[pos-i] = ptr[i];
}
ch1[pos] = '\0';
while (i<=len && j<=length)
{
if(j==0 || ch1[i-1]==ch[j-1])
{
i++;
j++;
}
else j = next[j];
}
delete[] ch;
ch = NULL;
delete[] ch1;
ch1 = NULL;
if(j > length)
return len-i+1;
else
return 0;
}
void String::replace(int n1, int n, String &s)
{
char *temp = new char[len+1];
strcpy(temp, ptr);
delete[] ptr;
len = s.len + len - n;
ptr = new char[len+1];
for(int i=0; i<n1; i++)
{
ptr[i] = temp[i];
}
for (int i=n1; i<n1+s.len; i++)
{
ptr[i] = s.ptr[i-n1];
}
for (int i=n1+s.len; i<len; i++)
{
ptr[i] = temp[i-s.len+n];
}
ptr[len] = '\0';
delete[] temp;
temp = NULL;
}
void String::insert(int n, char *s)
{
int sLength = strlen(s);
char *temp = new char[len+1];
strcpy(temp, ptr);
delete[] ptr;
ptr = new char[sLength + len + 1];
for (int i=0; i<n; i++)
{
ptr[i] = temp[i];
}
for (int i=n; i<n+sLength; i++)
{
ptr[i] = s[i-n];
}
for (int i=n+sLength; i<sLength+len; i++)
{
ptr[i] = temp[i-sLength];
}
delete[] temp;
temp = NULL;
ptr[sLength + len] = '\0';
}
void String::insert(int n1, String &s, int n2, int m)
{
char *temp = new char[len+1];
strcpy(temp, ptr);
delete[] ptr;
ptr = new char[m + len + 1];
for (int i=0; i<n1; i++)
{
ptr[i] = temp[i];
}
for (int i=n1; i<n1+m; i++)
{
ptr[i] = s.ptr[i-n1+n2];
}
for (int i=n1+m; i<m+len; i++)
{
ptr[i] = temp[i-m];
}
delete[] temp;
temp = NULL;
ptr[m + len] = '\0';
}
String &String::append(char *s)
{
char *temp = new char[len+1];
len = len + strlen(s);
strcpy(temp, ptr);
delete[] ptr;
ptr = new char[len+1];
strcpy(ptr, temp);
strcat(ptr, s); //字符串连接
delete[] temp;
temp = NULL;
return *this;
}
String &String::append(const String &s)
{
char *temp = new char[len+1];
len = len + s.len;
strcpy(temp, ptr);
delete[] ptr;
ptr = new char[len+1];
strcpy(ptr, temp);
strcat(ptr, s.ptr); //字符串连接
delete[] temp;
temp = NULL;
return *this;
}
String &String::append(const String &s, int n1, int n)
{
char *temp = new char[len+1];
len = len + n;
strcpy(temp, ptr);
delete[] ptr;
ptr = new char[len+1];
strcpy(ptr, temp);
delete[] temp;
temp = NULL;
for (int i=0; i<n; i++)
{
ptr[i+len-n] = s.ptr[n1+i];
}
ptr[len] = '\0';
return *this;
}
String &String::append(char *s, int n)
{
char *temp = new char[len+1];
len = len + n;
strcpy(temp, ptr);
delete[] ptr;
ptr = new char[len+1];
strcpy(ptr, temp);
delete[] temp;
temp = NULL;
for (int i=0; i<n; i++)
{
ptr[i+len-n] = s[i];
}
ptr[len] = '\0';
return *this;
}
String &String::append(int n, char ch)
{
char *temp = new char[len+1];
len = len + n;
strcpy(temp, ptr);
delete[] ptr;
ptr = new char[len+1];
strcpy(ptr, temp);
delete[] temp;
temp = NULL;
for (int i=0; i<n; i++)
{
ptr[i+len-n] = ch;
}
ptr[len] = '\0';
return *this;
}
String &String::push_back(char s)
{
char *temp = new char[len+1];
len = len + 1;
strcpy(temp, ptr);
delete[] ptr;
ptr = new char[len+1];
strcpy(ptr, temp);
ptr[len-1] = s;
ptr[len] = '\0';
delete[] temp;
temp = NULL;
return *this;
}
String &String::erase(int n)
{
char *temp = new char[len+1];
strcpy(temp, ptr);
delete[] ptr;
len = n;
ptr = new char[len+1];
for (int i=0; i<n; i++)
{
ptr[i] = temp[i];
}
delete temp;
temp = NULL;
ptr[len] = '\0';
return *this;
}
String &String::erase(int n1, int n)
{
char *temp = new char[len+1];
strcpy(temp, ptr);
delete[] ptr;
len = len - n;
ptr = new char[len+1];
for (int i=0; i<n1; i++)
{
ptr[i] = temp[i];
}
for (int i=n1; i<len; i++)
{
ptr[i] = temp[i+n];
}
delete temp;
temp = NULL;
ptr[len] = '\0';
return *this;
}
void String::clear()
{
delete[] ptr;
ptr = NULL;
len = 0;
}
int String::compare(String &s)
{
if (ptr > s.ptr)
return 1;
else
{
if (ptr = s.ptr)
return 0;
return -1;
}
}
bool String::empty()
{
if (len = 0)
return true;
return false;
}
char String::at(int n)
{
if (n<len)
return ptr[n];
cout << "out of range!" << endl;
return ' ';
}
String &String::assign(char *s)
{
char *temp = new char[len+1];
len = len + strlen(s);
strcpy(temp, ptr);
delete[] ptr;
ptr = new char[len+1];
strcpy(ptr, temp);
strcat(ptr, s); //字符串连接
delete[] temp;
temp = NULL;
return *this;
}
String &String::assign(const String &s)
{
char *temp = new char[len+1];
len = len + s.len;
strcpy(temp, ptr);
delete[] ptr;
ptr = new char[len+1];
strcpy(ptr, temp);
strcat(ptr, s.ptr); //字符串连接
delete[] temp;
temp = NULL;
return *this;
}
String &String::assign(const String &s, int n1, int n)
{
char *temp = new char[len+1];
len = len + n;
strcpy(temp, ptr);
delete[] ptr;
ptr = new char[len+1];
strcpy(ptr, temp);
delete[] temp;
temp = NULL;
for (int i=0; i<n; i++)
{
ptr[i+len-n] = s.ptr[n1+i];
}
ptr[len] = '\0';
return *this;
}
String &String::assign(char *s, int n)
{
char *temp = new char[len+1];
len = len + n;
strcpy(temp, ptr);
delete[] ptr;
ptr = new char[len+1];
strcpy(ptr, temp);
delete[] temp;
temp = NULL;
for (int i=0; i<n; i++)
{
ptr[i+len-n] = s[i];
}
ptr[len] = '\0';
return *this;
}
String &String::assign(int n, char ch)
{
char *temp = new char[len+1];
len = len + n;
strcpy(temp, ptr);
delete[] ptr;
ptr = new char[len+1];
strcpy(ptr, temp);
delete[] temp;
temp = NULL;
for (int i=0; i<n; i++)
{
ptr[i+len-n] = ch;
}
ptr[len] = '\0';
return *this;
}