数据结构五: 串

描述各种信息的文字符号序列称为字符串,简称串。在计算机上的非数值处理一般都是字符串数据。

1. 串类型的定义

串(string)是由零个或多个字符构成的有限序列,通常记为:

s="a0a1an,n0" s =" a 0 a 1 ⋯ a n , n ≥ 0 "

其中,s是串名,用双引号圈起来的部分(不包含双引号)称为串值,每个 ai(0in) a i ( 0 ≤ i ≤ n ) 为字符。长度为0的串称为空串。各个字符全是空格字符的串称为空格串。
串中任何连续字符组成的子序列称为此串的子串,包含子串的串相应的称为主串。串中某个字符在串中出现的位置称为该字符在串中的位置,子串中第0个字符在主串中的位置称为子串在主串中 的位置。
串之间大小关系的定义:
设有两个串:str1 和 str2
str1="a0a1an1",str2="b0b1bm1" str1 =" a 0 a 1 ⋯ a n − 1 " , str2 =" b 0 b 1 ⋯ b m − 1 "

str1和str2之间的大小关系定义如下:
(1) 如果 m=n m = n ai=bi,i=1,2,,n1 a − i = b i , i = 1 , 2 , ⋯ , n − 1 则称str1 = str2;
(2) 如果下面两个条件中有一个满足条件,则称str1 < < <script type="math/tex" id="MathJax-Element-8"><</script> str2:
   (a).m < < <script type="math/tex" id="MathJax-Element-9"><</script> n,且 ai=bi,i=0,1,2,,m1 a i = b i , i = 0 , 1 , 2 , ⋯ , m − 1
   (b).存在某个 0kmin(m,n) 0 ≤ k ≤ min ( m , n ) 使得 ai=bi,i=0,1,2,,k1,akbk a i = b i , i = 0 , 1 , 2 , ⋯ , k − 1 , a k ≤ b k
(3)不满足条件(1)(2)时,则称 str1 str2。

2. 字符串的实现

在C++语言中,提供了两种字符串的实现。其中一种是比较原始的C风格的串这种串的类型为char*,字符串以字符‘\0’结束,这种形式的串在应用时容易出问题,当 char* = NULL时,许多字符串库函数将会崩溃。另外一种是C++已经包装好的string类。这里我们做一个类似于string类的一个String类。

//头文件
#pragma once

#pragma warning( disable : 4996)
#include <cstring>
#include <iostream>
// 串类
class String
{
protected:
    //  串实现的数据成员:
    char *strVal;       // 串值
    int length;         // 串长   
public:
    //  抽象数据类型方法声明及重载编译系统默认方法声明:
    String();           // 构造函数 
    virtual ~String();     // 析构函数
    String(const String &copy); // 复制构造函数
    String(const char *copy);   // 从C风格串转换的构造函数
    //String(LinkList<char> &copy);// 从线性表转换的构造函数

    int getLength() const;  // 求串长度
    bool isEmpty() const;   // 判断串是否为空

    String &operator =(const String &copy);
    // 赋值语句重载
    const char *CStr() const;// 将串转换成C风格串
    const char & operator [](int i) const;
    // 重载下标运算符
};



//串相关操作

// 输出串
//void Write(const String &s);      

// 将串addOn连接到addTo串的后面
void Concat(String &addTo, const String &addOn);

// 将串original复制到串copy
void Copy(String &copy, const String &original);

// 将串original复制n个字符到串copy 
void Copy(String &copy, const String &original, int n);

// 查找模式串pattern第一次在目标串target中从第 pos个字符开始出现的位置
int Index(const String &target, const String &pattern,int pos = 0);

// 求串s的第pos个字符开始的长度为len的子串
String& SubString(const String &s, int pos, int len);

// 重载关系运算符==
bool operator ==(const String &first,const String &second);

// 重载关系运算符<
bool operator <(const String &first,const String &second);  

// 重载关系运算符>
bool operator >(const String &first,const String &second);  

// 重载关系运算符<=
bool operator <=(const String &first,const String &second); 

// 重载关系运算符>=
bool operator >=(const String &first,const String &second); 

// 重载关系运算符!=
bool operator !=(const String &first,const String &second); 

void write(String &S);
//cpp文件
#include "String.h"

using namespace std;
String::String()
{
    length = 0;
    strVal = NULL;
}

String::String(const String &copy)
{
    if (&copy != this)
    {
        length = copy.length;
        strVal = new char[length + 1];  // 分配存储空间 
        strcpy(strVal, copy.strVal);
    }
}

String::~String()
{
    delete[] strVal;
}

String::String(const char *inString)
// 操作结果:从C风格串转换构造新串——转换构造函数
{
    length = strlen(inString);      // 串长
    strVal = new char[length + 1];  // 分配存储空间 
    strcpy(strVal, inString);       // 复制串值
}

int String::getLength() const
{
    return length;
}

bool String::isEmpty() const
{
    return length == 0;
}

String & String::operator =(const String &copy)
{
    if (copy.isEmpty())
    {
        length = 0;
        strVal = NULL;
    }
    else
    {
        length = copy.length;
        strVal = new char[length + 1];  // 分配存储空间 
        strcpy(strVal, copy.strVal);
    }
    return *this;
}

const char *String::CStr() const
// 操作结果:将串转换成C风格串
{
    return (const char *)strVal;// 串值类型转换
}

const char& String::operator [](int i) const
{
    return strVal[i];
}


void Concat(String &addTo, const String &addOn)
{
    const char* cFirst = addTo.CStr();//指向第一个串
    const char* cSecond = addOn.CStr();//指向第二个串
    char* copy = new char[addOn.getLength() + addTo.getLength() + 1];//分配空间
    strcpy(copy, cFirst);
    strcat(copy, cSecond);

    addTo = copy;//注意这里
    delete[] copy;

}


void Copy(String &copy, const String &original)
{
    copy = original;
}

void Copy(String &copy, const String &original, int n)
{
    char* temp = new char[n + 1];
    for (int i = 0; i < n; i++ )
    {
        temp[i] = original[i];
    }
    temp[n] = '\0';
    copy = temp;
    delete[] temp;
}

int Index(const String &target, const String &pattern, int pos)
{
    const char* cTarget = target.CStr();
    const char* cPattern = pattern.CStr();
    const char* ptr = strstr(cTarget + pos, cPattern);//strstr函数,strchr函数
    if (ptr == NULL)
    {
        return -1;
    }
    else
    {
        return ptr - cTarget;
    }
}

String& SubString(const String &s, int pos, int len)
{
    char* temp = new char[len + 1];
    temp[len] = '\0';
    int count = 0;
    for (int i = pos; i < pos + len; i++)
    {
        temp[count] = s[i];
        count++;
    }
    String stemp(temp);
    delete[] temp;
    return stemp;

}


bool operator ==(const String &first, const String &second)
{
    return strcmp(first.CStr(), second.CStr()) == 0;
}

bool operator <(const String &first, const String &second)
{
    return strcmp(first.CStr(), second.CStr()) < 0;
}


bool operator >(const String &first, const String &second)
{
    return strcmp(first.CStr(), second.CStr()) > 0;
}

bool operator <=(const String &first, const String &second)
{
    return strcmp(first.CStr(), second.CStr()) <= 0;
}

bool operator >=(const String &first, const String &second)
{
    return strcmp(first.CStr(), second.CStr()) >= 0;
}


bool operator !=(const String &first, const String &second)
{
    return strcmp(first.CStr(), second.CStr()) != 0;
}

void write(String &S)
{
    for (int i = 0; i < S.getLength(); i++)
    {
        cout << S[i]<<endl;
    }

}
//测试文件
#include "String.hpp"

using namespace std;
int main(int argc, char* argv[])
{
    char a[5] = "abcd";
    char a2[3] = "cd";
    String s(a);
    write(s);
    String s2(s);
    write(s2);

    String s3(a2);
    Concat(s, s2);
    write(s);

    cout << Index(s, s3) << endl;
    getchar();
    return 0;
}

之后有时间将增加字符串匹配的常用算法

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值