字符串String类

本文详细介绍了自定义的字符串类String,包含构造函数、成员函数如长度获取、比较、拷贝、连接、子串处理、查找算法(KMP和BF)等,以及插入和删除操作。通过实际例子展示了如何使用这些功能进行字符串操作。
摘要由CSDN通过智能技术生成

字符串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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SVIP_Quanw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值