串
1.串的定义
串是由零个或多个字符组成的有限序列,又叫字符串。
一般记为:
s
=
“
a
1
a
2
⋅
⋅
⋅
⋅
⋅
⋅
a
n
”
(
n
>
=
0
)
s=“a~1a~2······a~n”(n>=0)
s=“a 1a 2⋅⋅⋅⋅⋅⋅a n”(n>=0)
其中,s为字符串的名称,双引号括起来的字符序列是串的值。串中的n为串的长度。
一些其他概念:
- **空串:**零个字符的串称为空串
- 空格串:只包含空格的串。空格串有内容有长度,空串没有内容长度为0.
- 字串与主串:串中任意个数的连续字符组成的子序列称为该串的子串,包含字串的串称为主串。
- **字串在主串中的位置:**字串的第一个字符在主串中的序号。
2.串的比较
计算机中字符串中的字符使用的是ASCII编码来实现的,即用8位二进制数(即一个字节)来标识一个字符,总共可以表示256个字符。串的比较是通过组成串的字符间的编码来进行的。
字符串的比较:
- 字符串相等的判断:必须是它们串的长度以及它们各个对应位置的字符都相等时,才算是相等。
如:s1="LeetCode",s2="LeetCode",s3=LeetCod,则s1与s2相等与s3不相等。
- **字符串不相等的情况下判断字符串大小的方法:**给定s=“a1a2·····an”,t=“b1b2…bm”.
1)n<m,且ai=bi时,s<t.因为t字符比s多
如:s="hap",t="happy",就有s<t
2)存在某个k≤min(m,n),使得ai=bi,ak<bk,则s<t.
如:s="happen",t="happy",前四个字符相同,但是s的第五个字符是e,其ASCII码是101,t第5个字符是y,其ASCII码是121,e<y,所以s<t.
字典就是用的这种排序方式。
3.串的抽象数据类型
串的逻辑结构和线性表很相似,但是线性表是数组中存放的数字,而字符串是数组中存放的字符。但是,线性表更关注的是单个元素的操作,如增、删、查找操作;但串中更多的是查找字串位置、替换字串等操作。
串的常用操作如下:
- 将s写入到输出流中:os<<s
- 从is中读取字符串赋值给s,字符串以空白分隔,返回is:is>>s
- 判断字符串是否为空:s.empty()
- 返回字符串中字符的个数:s.size()
- 返回s的第n个字符的引用:s[n]
- 返回s1和s2链接后的结果:s1+s2
- 用s2的副本代替s1中原来的字符
- 判断字符串是否相等:s1==s2
- 判断字符串大小:s1<s2
串的链式存储结构不如顺序存储结构灵活,性能也不如顺序存储结构好,因此,我们主要介绍串的顺序存储结构。
下面是顺序串的C++代码实现:
//String.h
#pragma once
#include<cstring>
#include<iostream>
using namespace std;
class String {
friend String operator+(String& lhs, const String& rhs);
friend ostream& operator<<(ostream& os, const String& rhs);
public:
String() :_capacity(0), _size(0), _str(nullptr) {}
String(const char* rhs) : _capacity(strlen(rhs) + 1), _size(strlen(rhs)), _str(nullptr) {
_str = new char[_capacity];
strcpy_s(_str, _capacity, rhs);
}
String(const String& rhs) : _capacity(rhs._capacity), _size(rhs._size), _str(nullptr) {
_str = new char[_capacity];
strcpy_s(_str, _capacity, rhs._str);
}
String& operator+=(const char*);
String& operator+=(const String& rhs);
String& operator=(const String&);
bool operator<(const String&);
~String() { delete[] _str; }
char& operator[](int index);
int capacity()const {return _capacity;}
int size()const {return _size;}
bool empty()const { return _size == 0;}
private:
int _capacity;
int _size;
char* _str;
};
//String.cpp
#include"String.h"
ostream& operator<<(ostream& os, const String& rhs) {
os << rhs._str;
return os;
}
String operator+(String& lhs, const String& rhs) {
lhs += rhs;
return lhs;
}
String& String::operator+=(const char *rhs) {
char* temp = _str;
int tempSize = _size;
_size += strlen(rhs);
_capacity = _size + 1;
_str = new char[_capacity];
strcpy_s(_str, tempSize+1, temp);
delete[] temp;
strcpy_s(_str + tempSize, strlen(rhs)+1, rhs);
return *this;
}
String& String::operator+=(const String& rhs) {
int tempSize = _size;
char* temp = _str;
_size += rhs._size;
_capacity = _size + 1;
_str = new char[_capacity];
strcpy_s(_str, tempSize+1, temp);
delete[] temp;
strcpy_s(_str + tempSize, rhs.capacity(), rhs._str);
return *this;
}
String& String::operator=(const String &rhs) {
_size = rhs._size;
_capacity = rhs._capacity;
delete[] _str;
_str = new char[_capacity];
strcpy_s(_str, _capacity, rhs._str);
return *this;
}
char& String::operator[](int index) {
return _str[index];
}
bool String::operator<(const String&rhs) {
return _str < rhs._str;
}
//main.cpp
#include"String.h"
#include<iostream>
int main() {
const String s("abc");
String s2(s);
s2 += "def";
s2 + s;
s2[3] = 'k';
cout <<s2 << " " << (s2 <s)<< endl;
system("pause");
return 0;
}
输出结果为: