1.字符串的定义
字符串由若干个字符按照一定的顺序组合而成,如果把单个字符看作成一个元素,则可把字符串看成是一个字符类型的线性表。更加确切的说,字符串是由零个或多个字符组成的有限序列。
字符串的基本操作有:
- 求字符串中的字符的个数length(s)
- 字符数的输出disp(s)
- 判断两个字符串是否相等equal(s1, s2), 大于greater(s1, s2), 大于等于greaterEqual(s1, s2), 小于less(s1, s2) ,小于等于lessEqual(s1, s2)
- 字符串赋值copy(s1, s2), 将s2的值赋给s1
- 字符串的连接cat(s1, s2)
- 取子串subStr(s, start, len)
- 字符串插入insert(s1, start, s2)
- 删除子串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;
}