字符串

1.字符串的定义

字符串由若干个字符按照一定的顺序组合而成,如果把单个字符看作成一个元素,则可把字符串看成是一个字符类型的线性表。更加确切的说,字符串是由零个或多个字符组成的有限序列。

字符串的基本操作有:

  1. 求字符串中的字符的个数length(s)
  2. 字符数的输出disp(s)
  3. 判断两个字符串是否相等equal(s1, s2), 大于greater(s1, s2), 大于等于greaterEqual(s1, s2),  小于less(s1, s2) ,小于等于lessEqual(s1, s2)
  4. 字符串赋值copy(s1, s2), 将s2的值赋给s1
  5. 字符串的连接cat(s1, s2)
  6. 取子串subStr(s, start, len)
  7. 字符串插入insert(s1, start, s2)
  8. 删除子串remove(s, start, len)

 

2.字符串的顺序实现

#pragma once
#include <iostream>
using namespace std;
class seqString
{
    friend seqString operator+(const seqString &s1, const seqString &s2);
    friend bool operator==(const seqString &s1, const seqString &s2);
    friend bool operator!=(const seqString &s1, const seqString &s2);
    friend bool operator>(const seqString &s1, const seqString &s2);
    friend bool operator>=(const seqString &s1, const seqString &s2);
    friend bool operator<=(const seqString &s1, const seqString &s2);
    friend bool operator<(const seqString &s1, const seqString &s2);
    friend ostream &operator<<(ostream &os, const seqString &s);
    char *data;
    int len;

public:
    seqString(const char *s = "");
    seqString(const seqString &other);
    ~seqString();
    int length() const;
    seqString &operator=(const seqString &other);
    seqString subStr(int start, int num) const;
    void insert(int start, const seqString &s);
    void remove(int start, int num);
};

/**
 * 构造函数
 */
seqString::seqString(const char *s)
{
    for (len = 0; s[len] != '\0'; ++len)
        ;
    data = new char[len + 1];
    for (len = 0; s[len] != '\0'; ++len)
        data[len] = s[len];
    data[len] = '\0';
}

/**
 * 复制构造函数
 */
seqString::seqString(const seqString &other)
{
    data = new char[other.len + 1];
    for (len = 0; len <= other.len; ++len)
        data[len] = other.data[len];
}

/**
 * 析构函数
 */
seqString::~seqString()
{
    delete data;
}

/**
 * length 函数 获取字符串的长度
 */
int seqString::length() const
{
    return len;
}

/**
 * 赋值重载
 */
seqString &seqString::operator=(const seqString &other)
{
    if (this == &other)
        return *this;
    delete data;
    data = new char[other.len + 1];
    for (len = 0; len <= other.len; len++)
        data[len] = other.data[len];
    return *this;
}

/**
 * subStr 函数 取子串
 */
seqString seqString::subStr(int start, int num) const
{
    if (start >= len - 1 || start < 0)
        return "";
    seqString tmp;
    tmp.len = (start + num > len) ? len - start : num;
    delete tmp.data;
    tmp.data = new char[tmp.len + 1];
    for (int i = 0; i < tmp.len; i++)
        tmp.data[i] = data[start + i];
    tmp.data[tmp.len] = '\0';
    return tmp;
}

/**
 * insert 函数 插入字符串
 */
void seqString::insert(int start, const seqString &s)
{
    char *tmp = data;
    int i;
    if (start > len || start < 0)
        return;
    len += s.len;
    data = new char[len + 1];
    for (i = 0; i < start; i++)
        data[i] = tmp[i];
    for (i = 0; i < s.len; ++i)
        data[i + start] = s.data[i];
    for (i = start; tmp[i] != '\0'; ++i)
        data[i + s.len] = tmp[i];
    data[i + s.len] = '\0';
    delete tmp;
}

/**
 * remove 函数 删除字子符串
 */
void seqString::remove(int start, int num)
{
    if (start < 0 || start > len)
        return;
    if (start + num >= len)
    {
        data[start] = '\0';
        len = start;
    }
    else
    {
        for (len = start; data[len + num] != '\0'; ++len)
            data[len] = data[len + num];
        data[len] = '\0';
    }
}

/**
 * 加号重载
 */
seqString operator+(const seqString &s1, const seqString &s2)
{
    seqString tmp;
    int i;
    tmp.len = s1.len + s2.len;
    delete tmp.data;
    tmp.data = new char[tmp.len + 1];
    for (i = 0; i < s1.len; i++)
        tmp.data[i] = s1.data[i];
    for (i = 0; i < s2.len; i++)
        tmp.data[i + s1.len] = s2.data[i];
    tmp.data[s1.len + s2.len] = '\0';
    return tmp;
}

/**
 * 重载等号
 */
bool operator==(const seqString &s1, const seqString &s2)
{
    if (s1.len != s2.len)
        return false;
    for (int i = 0; i < s1.len; ++i)
        if (s1.data[i] != s2.data[i])
            return false;
    return true;
}

/**
 * 重载不等号
 */
bool operator!=(const seqString &s1, const seqString &s2)
{
    return !(s1 == s2);
}

/**
 * 重载大于号
 */
bool operator>(const seqString &s1, const seqString &s2)
{
    for (int i = 0; i < s1.len; i++)
    
        if (s1.data[i] > s2.data[i])
            return true;
        else if (s1.data[i] < s2.data[i])
            return false;
        return false;
    
}


/**
 * 重载大于等于号
 */
bool operator>=(const seqString&s1, const seqString&s2){
    return(s1==s2||s1>s2);
}

/**
 * 重载小于号
 */
bool operator<(const seqString&s1, const seqString&s2){
    return !(s1>=s2);
}


/**
 * 重载小于等于号
 */
bool operator<=(const seqString&s1, const seqString&s2){
    return !(s1>s2);
}


/**
 * 重载输出
 */
ostream &operator<<(ostream&os, const seqString&s){
    os<<s.data;
    return os;
}


 

3.字符串的链接实现

#pragma once 
#include <iostream>
#include <cmath>
using namespace std;
class linkString
{
	friend linkString operator+(const linkString& s1, const linkString& s2);
	friend bool operator==(const linkString& s1, const linkString& s2);
	friend bool operator>(const linkString& s1, const linkString& s2);
	friend bool operator>=(const linkString& s1, const linkString& s2);
	friend bool operator<(const linkString& s1, const linkString& s2);
	friend bool operator<=(const linkString& s1, const linkString& s2);
	friend bool operator!=(const linkString& s1, const linkString& s2);
	friend ostream& operator<<(ostream& os, const linkString& s2);

	struct node
	{
		int size;
		char* data;
		node* next;
		node(int s = 1, node * n = nullptr)
		{
			size = s;
			data = new char[s];
			next = n;
		}
	};

	node* head;
	int len;
	int nodeSize;
	void clear();
	void findPos(int start, int& pos, node*& p) const;
	void split(node* p, int pos);
	void merge(node* p);

public:
	linkString(const char* s = "");
	linkString(const linkString& other);
	~linkString();
	int length() const;
	linkString& operator=(const linkString& other);
	linkString subStr(int start, int num) const;
	void insert(int start, const linkString& s);
	void remove(int start, int num);
};

/**
 * 构造函数
 */
linkString::linkString(const char* s)
{
	node* p;
	for (len = 0; s[len] != '\0'; ++len);
		nodeSize = sqrt(len);
	p = head = new node(1);
	while (*s)
	{
		p = p->next = new node(nodeSize);
		for (int i = 0; i < nodeSize && *s; ++s, ++i) {
			p->data[i] = s[0];
		}
				
	}
}

/**
 * 复制构造函数
 */
linkString::linkString(const linkString& other)
{
	node* p, * otherp = other.head->next;

	p = head = new node(1);
	len = other.len;
	nodeSize = other.nodeSize;
	while (otherp)
	{
		p = p->next = new node(nodeSize);
		for (int i=0; i< otherp->size; ++i)
			p->data[i] = otherp->data[i];
		otherp = otherp->next;
	}
}

/**
 * clear 函数 清除所有的值
 */
void linkString::clear()
{
	node* p = head->next;
	node* nextp;
	while (p)
	{
		nextp = p->next;
		delete p;
		p = nextp;
	}
}

/**
 * 析构函数
 */
linkString::~linkString()
{
	clear();
	delete head;
}

/**
 * length 函数 获得字符串的长度
 */
int linkString::length() const
{
	return len;
}

/**
 * 复制构造函数
 */
linkString& linkString::operator=(const linkString& other)
{
	node* p = head->next;
	node* otherp = other.head->next;
	if (this == &other)
		return *this;
	clear();
	len = other.len;
	nodeSize = other.nodeSize;
	while (otherp)
	{
		p = p->next = new node(nodeSize);
		for (int i = 0; i < otherp->size; ++i) {
			p->data[i] = otherp->data[i];
			cout << p->data[i] << endl;
		}
		otherp = otherp->next;
	}
	return *this;
}

/**
 * findPos 函数 查找起始位置
 */
void linkString::findPos(int start, int& pos, node*& p) const
{
	int count = 0;
	p = head->next;
	while (count <= start)
	{
		if (count + p->size < start)
		{
			count += p->size;
			p = p->next;
		}
		else
		{
			pos = start - count;
			return;
		}
	}
}

/**
 * subStr 函数 取子串
 */

linkString linkString::subStr(int start, int num) const
{
	linkString tmp;
	int count = 0, pos;
	node* p, * tp = tmp.head;
	if (start < 0 || start > len)
		return tmp;
	num = (start + num) > len ? len - start : num;
	tmp.len = num;
	tmp.nodeSize = sqrt(num);
	findPos(start, pos, p);

	for (int i = 0; i < tmp.len;)
	{
		tp = tp->next = new node(tmp.nodeSize);
		for (int j=0; j < tmp.nodeSize && i < tmp.len; ++i, ++j)
		{
			if (pos == p->size)
			{
				p = p->next;
				pos = 0;
			}
			tp->data[j] = p->data[pos++];
		}
	}
	return tmp;
}

/**
 * split 函数 分裂结点
 */
void linkString::split(node* p, int pos)
{
	p->next = new node(nodeSize, p->next);
	int i;
	for (i = pos; i < p->size; ++i)
		p->next->data[i - pos] = p->data[pos];
	p->next->size = i - pos;
	p->size = pos;
}

/**
 * merge 函数 合并结点
 */
void linkString::merge(node* p)
{
	node* nextp = p->next;
	if (p->size + nextp->size <= nodeSize)
	{
		for (int pos = 0; pos < nextp->size; ++pos, ++p->size)
			p->data[p->size] = nextp->data[pos];
		p->next = nextp->next;
		delete nextp;
	}
}

/**
 * insert 函数,插入字符串
 */
void linkString::insert(int start, const linkString& s)
{
	node* p, * nextp, * tmp;
	int pos;
	if (start < 0 || start > len)
		return;
	findPos(start, pos, p);
	split(p, pos);
	nextp = p->next;
	tmp = s.head->next;
	while (tmp)
	{
		for (pos = 0; pos < tmp->size; ++pos)
		{
			if (p->size == nodeSize)
				p = p->next = new node(nodeSize);
			p->data[p->size] = tmp->data[pos];
			++p->size;
		}
		tmp = tmp->next;
	}
	len += s.len;
	p->next = nextp;
	merge(p);
}

/**
 * remove 函数 删除字符串
 */
void linkString::remove(int start, int num)
{
	if (start < 0 || start > len)
		return;
	node* startp;
	int pos;
	findPos(start, pos, startp);
	split(startp, pos);
	if (start + num >= len)
	{
		num = len - start;
		len = start;
	}
	else
		len -= num;
	while (true)
	{
		node* nextp = startp->next;
		if (num > nextp->size)
		{
			num -= nextp->size;
			startp->next = nextp->next;
			delete nextp;
		}
		else
		{
			split(nextp, num);
			startp->next = nextp->next;
			delete nextp;
			break;
		}
	}
	merge(startp);
}

/**
 * 重载加号运算符
 */
linkString operator+(const linkString& s1, const linkString& s2)
{
	char* tmp = new char[s1.len + s2.len + 1];
	linkString::node* p;
	int count = 0;

	for (p = s1.head->next; p != nullptr; p = p->next)
		for (int i = 0; i < p->size; ++i)
			tmp[count++] = p->data[i];
	for (p = s2.head->next; p != nullptr; p = p->next)
		for (int i = 0; i < p->size; i++)
			tmp[count++] = p->data[i];
	tmp[count] = '\0';
	linkString returnValue(tmp);
	delete tmp;
	return returnValue;
}

/**
 * 重载== 运算符
 */
bool operator==(const linkString& s1, const linkString& s2)
{
	linkString::node* p1 = s1.head->next;
	linkString::node* p2 = s2.head->next;

	int pos1 = 0, pos2 = 0;

	if (s1.len != s2.len)
		return false;
	while (p1 && p2)
	{
		if (p1->data[pos1] != p2->data[pos2])
			return false;
		if (++pos1 == p1->size)
		{
			p1 = p1->next;
			pos1 = 0;
		}
		if (++pos2 == p2->size)
		{
			p2 = p2->next;
			pos2 = 0;
		}
	}
	return true;
}

/**
 * 重载运算符 !=
 */
bool operator!=(const linkString& s1, const linkString& s2)
{
	return !(s1 == s2);
}

/**
 * 重载运算符 >
 */
bool operator>(const linkString& s1, const linkString& s2)
{
	linkString::node* p1 = s1.head->next;
	linkString::node* p2 = s2.head->next;
	int pos1 = 0, pos2 = 0;
	while (p1)
	{
		if (p2 == nullptr)
			return true;
		if (p1->data[pos1] > p2->data[pos2])
			return true;
		if (p1->data[pos1] > p2->data[pos2])
			return false;
		if (++pos1 == p1->size)
		{
			p1 = p1->next;
			pos1 = 0;
		}
		if (++pos2 == p2->size)
		{
			p2 = p2->next;
			pos2 = 0;
		}
	}
	return false;
}

/**
 * 重载运算符 >=
 */
bool operator>=(const linkString& s1, const linkString& s2)
{
	return (s1 == s2 || s1 > s2);
}

/**
 * 重载运算符 <
 */

bool operator<(const linkString& s1, const linkString& s2)
{
	return !(s1 >= s2);
}

/**
 * 重载运算符 <=
 */
bool operator<=(const linkString& s1, const linkString& s2)
{
	return !(s1 > s2);
}

/**
 * 重载运算符 <<
 */
ostream& operator<<(ostream& os, const linkString& s)
{
	linkString::node* p = s.head->next;
	int pos;
	while (p)
	{
		for (pos = 0; pos < p->size; pos++)
		{
			os << p->data[pos];
		}
		p = p->next;
	}
	return os;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值