本文介绍
本文章不使用string.h库来实现串类。
实现了运算符+,=,+=,==,[]的重载。
串类的初始化支持常量字符串,字符串数组,自定义的String类
但是运算符只支持String对象之间(因为懒)
String.h 头文件的实现
#pragma once
#include<iostream>
using namespace std;
/*
此String
构造可以由String 或者自带的char*类型字符串构造
但是运算只满足String之间的运算,与内置类型的运算没写,懒
*/
//String 有个注意点,len中没有计算\0
class String {
friend ostream& operator<<(ostream& cout, String& str);
friend istream& operator>>(istream& cin, String& str);
public:
String();//默认构造
String(char* ch);//构造 面对字符串变量
String(const char arr[]);//构造 面对常量字符串
String(const String& str);//构造 面对String类
~String();//析构函数
String& operator+(const String& str) const; //重载+
String& operator=(const String& str); //重载=
String& operator+=(const String& str); //重载+= cout的时候要加括号
bool operator==(const String& str) const; //重载==
char& operator[](int index) const; //重载[]
int strlen();
int strstr(String& sub, int pos);//kmp 算法查找子串 从pos下标开始查找子串sub
void getNext(int* next);
private:
char* elem;
int len;
};
String.cpp的实现
#include"String.h"
String::String() {
this->elem = NULL;
this->len = 0;
}
String::String(char* ch) {
//获取长度
if (!ch) {
this->len = 0;
this->elem = NULL;
return;
}
int num = 0;
while ('\0' != ch[num]) num++;
this->len = num;
if (0 != this->len)
{
this->elem = new char[num + 1];
for (int i = 0; i < num + 1; i++) {
this->elem[i] = ch[i];
}
}
else
{
this->elem = new char[1];
this->elem[0] = '\0';
this->len = 0;
}
}
String::String(const char ch[]) {
//获取长度
if (!ch) {
this->elem = NULL;
this->len = 0;
return;
}
int num = 0;
while ('\0' != ch[num]) num++;
this->len = num;
if (0 != this->len)
{
this->elem = new char[num + 1];
for (int i = 0; i < num + 1; i++) {
this->elem[i] = ch[i];
}
}
else
{
this->elem = new char[1];
this->elem[0] = '\0';
this->elem = 0;
}
}
String::String(const String& str) {
//获取长度
if (NULL == str.elem) {
this->elem = NULL;
this->len = 0;
return;
}
if (0 != str.len)
{
this->len = str.len;
this->elem = new char[str.len + 1];
for (int i = 0; i < str.len + 1; i++) {
this->elem[i] = str.elem[i];
}
}
else
{
this->elem = new char[1];
this->elem[0] = '\0';
this->elem = 0;
}
}
String::~String() {
if (!this->elem) {
delete[]this->elem;
this->len = 0;
}
}
String& String::operator+(const String& str) const {
char* temp = new char[this->len + str.len + 1];
for (int i = 0; i < this->len; i++) {
temp[i] = this->elem[i];
}
for (int i = this->len; i < this->len + str.len; i++) {
temp[i] = str.elem[i - this->len];
}
temp[this->len + str.len] = '\0';
String newString(temp);
return newString;
}
String& String::operator=(const String& str) {
//置0
if (NULL != this->elem) {
delete[]this->elem;
}
this->elem = NULL;
this->len = 0;
if (NULL == str.elem) {
this->elem = NULL;
this->len = 0;
return *this;
}
if (0 != str.len)
{
this->len = str.len;
this->elem = new char[str.len + 1];
for (int i = 0; i < str.len + 1; i++) {
this->elem[i] = str.elem[i];
}
}
else
{
this->elem = new char[1];
this->elem[0] = '\0';
this->elem = 0;
}
return *this;
}
String& String::operator+=(const String& str) {
char* temp = new char[this->len + str.len + 1];
for (int i = 0; i < this->len; i++) {
temp[i] = this->elem[i];
}
for (int i = this->len; i < this->len + str.len; i++) {
temp[i] = str.elem[i - this->len];
}
temp[this->len + str.len] = '\0';
String newString(temp);
*this = newString;
return *this;
}
bool String::operator==(const String& str) const {
//长度不等直接不等
if (this->len != str.len) return false;
//长度相等时候的处理
bool find = true;
for (int i = 0; i < this->len; i++) {
if (this->elem[i] != str.elem[i]) {
find = false;
break;
}
}
return find;
}
char& String::operator[](int index) const {
if (index >= this->len || index < 0) {
cout << "error: index out of range!" << endl;
exit;
}
return this->elem[index];
}
int String::strlen() {
return this->len;
}
istream& operator>>(istream& cin, String& str) {
char temp[1000];
cin >> temp;
String newString(temp);
str = newString;
return cin;
}
ostream& operator<<(ostream& cout, String& str) {
cout << str.elem;
return cout;
}
int String::strstr(String& sub, int pos) {
int lenStr = this->len;
int lenSub = sub.len;
if (0 == lenStr || 0 == lenSub)return -1;
if (pos < 0 || pos >= lenStr)return -1;
int* next = new int[lenSub];
sub.getNext(next);
int i = pos;//遍历主串
int j = 0;//遍历子串
while (i < lenStr && j < lenSub)
{
if (-1 == j || this->elem[i] == sub[j]) {
i++;
j++;
}
else {
j = next[j];
}
}
//释放内存
delete[] next;
if (j >= lenSub)return i - j;
return -1;
}
void String::getNext(int* next) {
int lenSub = this->len;
next[0] = -1;
next[1] = 0;
int i = 2;//当前i下标
int k = 0;//前一项k
while (i < lenSub)
{
if (-1 == k || this->elem[i - 1] == this->elem[k]) {
next[i] = k + 1;
i++;
k++;
}
else {
k = next[k];
}
}
}