字符串String类
String.h
#ifndef __STRING_H__
#define __STRING_H__
#include <iostream>
/**
* @brief 自己写的字符串类
* 末尾没有\0,用{ len }记录长度
*
*/
class String {
private:
char* str;
int len;
public:
/**
* @brief Construct a new String object
*
*/
String() : str(nullptr), len(0) {}
/**
* @brief Construct a new String object
*
* @param s 字符串
*/
String(const char* s);
/**
* @brief Construct a new String object
*
* @param s 字符串
* @param n 长度(不包括\0)
*/
String(const char* s, int n);
/**
* @brief Construct a new String object
*
* @param s 字符串
* @param start 开始(包括)
* @param end 结束(不包括)
*/
String(const char* s, int start, int end);
/**
* @brief 判断字符串是否为空
*
* @return true
* @return false
*/
bool isEmpty() { return len == 0; }
/**
* @brief 获取字符串长度
*
* @return int
*/
int length() { return this->len; }
/**
* @brief 字符串比较
*
* @param t 字符串
* @return int 正数 str>t
* @return int 0 str==t
* @return int 负数 str<t
*/
int compareTo(String& t);
/**
* @brief 字符串深拷贝
*
* @return String&
*/
String& deepCopy() { return *new String(str, len); }
/**
* @brief 将字符串连接并返回
*
* @param s 字符串
* @param t 字符串
* @return String& 新字符串
*/
static String& connect(String& s, String& t);
/**
* @brief 将字符串t连接到str后面
*
* @param t 字符串
* @return String& 连接后的原字符串
*/
String& join(String& t);
/**
* @brief 获取子串,原字符串不变
*
* @param start 起始位置(包括)
* @param end 结束位置(不包括)
* @return String& 子串
*/
String& substring(int start, int end);
/**
* @brief 使用kmp算法的字符串查找
*
* @param pat 模式串
* @return int 首地址下标
*/
int indexOf(String& pat);
/**
* @brief 使用bf算法的逆序字符串查找
*
* @param pat 模式串
* @return int 首地址下标
*/
int lastIndexOf(String& pat);
/**
* @brief (静态方法)使用kmp算法的字符串查找
*
* @param str 字符串
* @param pat 模式串
* @return int 首地址下标
* @return int -1 不存在
*/
static int indexOf(String& str, String& pat);
/**
* @brief 在i处插入t
*
* @param t 字符串
* @param i 下标
* @return String& 源字符串
*/
String& insert(String& t, int i);
/**
* @brief 在s的i处插入t
*
* @param s 字符串ed
* @param t 字符串
* @param i 下标ed
* @return String& 新字符串
*/
static String& insert(String& s, String& t, int i);
/**
* @brief 删除一个区间,原字符串不做改动,返回新字符串
*
* @param start 起始(包括)
* @param end 结束(不包括)
* @return String& 新字符串
*/
String& deleted(int start, int end);
/**
* @brief 删除一个区间
*
* @param start 起始(包括)
* @param end 结束(不包括)
* @return String& 原字符串
*/
String& del(int start, int end);
/**
* @brief Destroy the String object
*
*/
~String();
friend std::ostream& operator<<(std::ostream& os, const String& s);
char operator[](int i) { return str[i]; }
};
String::String(const char* s) {
len = -1;
while (s[++len])
;
str = new char[len];
for (int i = 0; i < len; ++i)
str[i] = s[i];
}
String::String(const char* s, int n) {
len = n;
str = new char[n];
for (int i = 0; i < n; ++i)
str[i] = s[i];
}
String::String(const char* s, int start, int end) {
len = end - start + 1;
str = new char[len];
for (int i = start; i < end; ++i)
str[i] = s[i];
}
int String::compareTo(String& t) {
int l = std::min(t.length(), len);
int ret = 0;
for (int i = 0; i < l; ++i) {
if (str[i] != t[i])
return str[i] - t[i];
}
return len == t.length() ? 0 : len == l ? -1
: 1;
}
String& String::connect(String& s, String& t) {
int newLength = s.length() + t.length();
char* ret = new char[newLength];
int i = 0;
for (int j = 0; j < s.length(); ++j)
ret[i++] = s[j];
for (int j = 0; j < t.length(); ++j)
ret[i++] = t[j];
return *new String(ret, newLength);
}
String& String::join(String& t) {
int newLength = len + t.length();
char* ret = new char[newLength];
int i = 0;
for (int j = 0; j < len; ++j)
ret[i++] = str[j];
for (int j = 0; j < t.length(); ++j)
ret[i++] = t[j];
char* p = str;
str = ret;
delete[] p;
return *this;
}
String& String::substring(int start, int end) {
int l = std::max(start, 0);
int r = std::min(end, len);
int nl = r - l, i = 0;
char* s = new char[nl];
while (l < r)
s[i++] = str[l++];
return *new String(s, nl);
}
int String::indexOf(String& pat) {
const int l = pat.length();
if (l == 0) // 空串
return 0;
int next[l];
next[0] = -1;
for (int k = -1, q = 1; q <= l; ++q) {
while (k > -1 && pat[k + 1] != pat[q])
k = next[k];
if (pat[k + 1] == pat[q])
++k;
next[q] = k;
}
for (int i = 0, k = -1; i <= len; i++) {
while (k > -1 && pat[k + 1] != str[i])
k = next[k];
if (pat[k + 1] == str[i])
++k;
if (k + 1 == l)
return i - l + 1;
}
return -1;
}
int String::indexOf(String& str, String& pat) {
const int m = str.length();
const int l = pat.length();
int next[l];
next[0] = -1;
for (int j = -1, i = 1; i < l; ++i) {
while (j > -1 && pat[j + 1] != pat[i])
j = next[j];
if (pat[j + 1] == pat[i])
++j;
next[i] = j;
}
for (int i = 0, j = -1; i < m; i++) {
while (j > -1 && pat[j + 1] != str[i])
j = next[j];
if (pat[j + 1] == str[i])
++j;
if (j + 1 == l)
return i - l + 1;
}
return -1;
}
int String::lastIndexOf(String& pat) {
int l = pat.length() - 1;
for (int i = len - 1; i >= 0; --i) {
int j = l, k = i;
while (j >= 0 && str[k--] == pat[j--])
;
if (j = -1)
return i - l + 1;
}
return -1;
}
String& String::insert(String& t, int i) {
int l = t.length();
char* s = new char[len + l];
int k = 0;
for (int j = 0; j < i; ++j)
s[k++] = str[j];
for (int j = 0; j < l; ++j)
s[k++] = t[j];
for (; i < len; ++i)
s[k++] = str[i];
len += l;
char* p = str;
str = s;
delete[] p;
return *this;
}
String& String::insert(String& s, String& t, int i) {
int m = s.length();
int l = t.length();
char* r = new char[m + l];
int k = 0;
for (int j = 0; j < i; ++j)
r[k++] = s[j];
for (int j = 0; j < l; ++j)
r[k++] = t[j];
for (; i < m; ++i)
r[k++] = s[i];
return *new String(r, m + l);
}
String& String::deleted(int start, int end) {
int d = end - start, k = 0;
if (end <= 0)
return *new String("");
char* s = new char[len - d];
for (int i = 0; i < start; ++i)
s[k++] = str[i];
for (int i = end; i < len; ++i)
s[k++] = str[i];
return *new String(s, len - d);
}
String& String::del(int start, int end) {
int d = end - start, k = 0;
if (end <= 0)
return *new String("");
char* s = new char[len - d];
for (int i = 0; i < start; ++i)
s[k++] = str[i];
for (int i = end; i < len; ++i)
s[k++] = str[i];
char* p = str;
str = s;
len -= d;
delete[] p;
return *this;
}
String::~String() {
delete[] str;
str = nullptr;
len = 0;
}
std::ostream& operator<<(std::ostream& os, const String& s) {
if (s.str == nullptr)
return os;
for (int i = 0; i < s.len; ++i) {
os << s.str[i];
}
return os;
}
#endif
StringTest.cpp
#include <iostream>
#include "String.h"
using std::cout;
String s("tatatangtang");
String t("quanwei");
String r("tatang");
String u("");
void test_properitise() {
cout << "\n- <<输出测试 -\n";
cout << "s: " << s << '\n';
cout << "t: " << t << '\n';
cout << "r: " << r << '\n';
cout << "u: " << u << '\n';
cout << "\n- 长度测试 -\n";
cout << "s.length() = " << s.length() << '\n';
cout << "t.length() = " << t.length() << '\n';
cout << "r.length() = " << r.length() << '\n';
cout << "u.length() = " << u.length() << '\n';
cout << "\n- 空串测试 -\n";
cout << "s.isEmpty() = " << (s.isEmpty() ? "true" : "false") << '\n';
cout << "t.isEmpty() = " << (t.isEmpty() ? "true" : "false") << '\n';
cout << "r.isEmpty() = " << (r.isEmpty() ? "true" : "false") << '\n';
cout << "u.isEmpty() = " << (u.isEmpty() ? "true" : "false") << '\n';
cout << "\n- 比较测试 -\n";
cout << "s.compareTo(s) = " << s.compareTo(s) << '\n';
cout << "s.compareTo(t) = " << s.compareTo(t) << '\n';
cout << "s.compareTo(r) = " << s.compareTo(r) << '\n';
cout << "s.compareTo(u) = " << s.compareTo(u) << '\n';
cout << "\n- 深拷贝测试 -\n";
cout << "s.deepCopy() = " << s.deepCopy() << '\n';
}
void test_connect() {
cout << "\n- 字符串连接测试 -\n";
cout << "String::connect(t,u) = " << String::connect(t, r) << '\n';
cout << "t = " << t << ", r= " << r << '\n';
cout << "t.join(r) = " << t.join(r) << '\n';
cout << "t = " << t << '\n';
}
void test_substring() {
cout << "\n- 子串测试 -\n";
cout << "s.substring(1,6)" << s.substring(1, 6) << '\n';
}
void test_indexOf() {
cout << "\n- 子串查找测试 -\n";
cout << "s.indexOf(t) = " << s.indexOf(t) << '\n';
cout << "s.indexOf(r) = " << s.indexOf(r) << '\n';
cout << "s.indexOf(u) = " << s.indexOf(u) << '\n';
cout << "\n- 子串查找<静态方法>测试 -\n";
cout << "String::indexOf(s,t) = " << String::indexOf(s, t) << '\n';
cout << "String::indexOf(s,r) = " << String::indexOf(s, r) << '\n';
cout << "\n- 子串查找<逆序>测试 -\n";
cout << "s.lastIndexOf(u) = " << s.lastIndexOf(u) << '\n';
cout << "s.lastIndexOf(u) = " << s.lastIndexOf(r) << '\n';
}
void test_insert_delete() {
cout << "\n- 插入测试 -\n";
cout << "String::insert(r, t, 3) = " << String::insert(r, t, 3) << '\n';
cout << "t = " << t << ", r= " << r << '\n';
cout << "r.insert(t,3) = " << r.insert(t, 3) << '\n';
cout << "t = " << t << ", r= " << r << '\n';
cout << "\n- 删除测试 -\n";
cout << "r.deleted(3, 6) = " << r.deleted(3, 6) << '\n';
cout << "t = " << t << ", r= " << r << '\n';
cout << "r.del(3, 6) = " << r.del(3, 6) << '\n';
cout << "t = " << t << ", r= " << r << '\n';
}
int main() {
test_properitise();
test_connect();
test_substring();
test_indexOf();
test_insert_delete();
return 0;
}