欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C++自定义String字符串类,支持子串搜索

程序员文章站 2022-10-05 09:30:26
C++自定义String字符串类 实现了各种基本操作,包括重载+号实现String的拼接 findSubStr函数,也就是寻找目标串在String中的位置,用到了KMP字符串搜索算法。 include include using namespace std; class String; class ......

C++自定义String字符串类

实现了各种基本操作,包括重载+号实现String的拼接

findSubStr函数,也就是寻找目标串在String中的位置,用到了KMP字符串搜索算法。

#include <iostream>
#include <cstring>
using namespace std;

class String;

class Data{                                                                     // 抽象基类Data
public:
    virtual const int compareTo(const String& target) const = 0;                // virtual比较函数
};

class String: public Data{                                                      // String类。继承自Data
public:
    static int num_strings;                                                     // 程序周期内创建的String对象个数
    static const int CINLIM = 80;                                               // 限制字符长度
    String();                                                                   // 默认构造函数
    String(unsigned int capacity);                                              // 以大小为capacity来初始化
    String(unsigned int capacity, char ch);                                     // 填充字符为ch,大小为capacity
    String(const char* target);                                                 // 以一个c风格字符串初始化
    String(const String& st);                                                   // 拷贝构造函数
    ~String(){ delete ptr; }                                                    // 析构函数
    const int       findSubStr(const char* substr) const;                       // 找出子串位置
    const int       findChar(char target) const;                                // 找出字符第一次出现位置
    const int       length() const;                                             // 返回字符串大小
    static int      howManyExit();                                              // 返回程序周期内创建的String对象个数
    const int       compareTo(const String& target) const override;             // 与其它String对象比较大小
    String&         operator=(const String&);                                   // 重载赋值操作符
    String&         operator=(const char*);                                     // 重载赋值操作符
    friend String   operator+(const String&,const String&)      ;               // 重载加号
    char&           operator[](int i);                                          // 重载[]
    const char&     operator[](int i) const;                                    // 重载[]
    friend bool     operator>(const String& st1,const String& st2);             // 重载>
    friend bool     operator<(const String& st1,const String& st2);             // 重载<
    friend bool     operator==(const String& st1,const String& st2);            // 重载==
    friend ostream& operator<<(ostream& os,const String& st);                   // 重载<<
    friend istream& operator>>(istream& is,String& st);                         // 重载>>
private:
    char* ptr;                                                                  // 内置char数组指针
    unsigned int len;                                                           // 当前String长度
};

int String::num_strings = 0;                                                    // 静态变量初始化

String::String() { ptr = new char[10]; len = 10; }

String::String(unsigned int capacity){
    ptr = new char[capacity]; len = capacity;
    ++ num_strings;
}

String::String(unsigned int capacity, char ch){
    ptr = new char[capacity]; len = capacity;
    for(int i=0;i<len;i++)
        ptr[i] = ch;
    ++ num_strings;
}

String::String(const char* target){
    int tmp = (int)strlen(target);
    len = (unsigned)tmp;
    ptr = new char[len];
    strcpy(ptr,target);
    ++ num_strings;
}

String::String(const String& st){
    int tmp = (int)strlen(st.ptr);
    len = (unsigned)tmp;
    ptr = new char[len];
    strcpy(ptr,st.ptr);
    ++ num_strings;
}

const int String::findSubStr(const char* substr) const{
    int next[100];
    next[0] = -1;
    int i=0,j=-1;
    int lenP = (int)strlen(substr);
    while(i<lenP){
        if(j==-1||substr[i]==substr[j]){
            ++i; ++j;
            next[i] = j;
        }else
            j = next[j];
    }
    i = 0,j = 0;
    while(i<len&&j<lenP){
        if(j==-1|ptr[i]==substr[j]){
            ++i; ++j;
        }else
            j = next[j];
    }
    if(j==lenP) return len - j;
    return -1;
}

const int String::findChar(char target) const{
    for(int i=0;i<len;i++)
        if(ptr[i] == target) return i;
    return -1;
}

const int String::length() const{
    return this->len;
}

int String::howManyExit(){
    return num_strings;
}

const int String::compareTo(const String& target) const{
    if(target.ptr == nullptr || strcmp(ptr,target.ptr)>0)
        return 1;
    else if(strcmp(ptr,target.ptr)==0)
        return 0;
    else
        return -1;
}

String& String::operator=(const String& str){
    if(this == &str)
        return *this;
    delete ptr;
    len = (int)strlen(str.ptr);
    ptr = new char[len];
    strcpy(ptr,str.ptr);
    return *this;
}

String& String::operator=(const char* str){
    delete[] ptr;
    len = (int)strlen(str);
    ptr = new char[len+1];
    strcpy(ptr,str);
    return *this;
}

String operator+(const String& st1,const String& st2){
    int lenSt2 = (int)strlen(st2.ptr);
    int lenSt1 = (int)strlen(st1.ptr);
    char* temp = new char[lenSt1+lenSt2+1];
    strcpy(temp,st1.ptr);
    for(int i=lenSt1;i<lenSt1+lenSt2;i++)
        temp[i] = st2.ptr[i-lenSt1];
    return String(temp);
}

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

bool operator<(const String& st1,const String& st2){
    return (std::strcmp(st1.ptr,st2.ptr)<0);
}
bool operator>(const String& st1,const String& st2){
    return (std::strcmp(st1.ptr,st2.ptr)>0);
}
bool operator==(const String& st1,const String& st2){
    return (std::strcmp(st1.ptr,st2.ptr)==0);
}
ostream& operator<<(ostream& os,const String& st){
    os<<st.ptr;
    return os;
}
istream& operator>>(istream& is,String& st){
    char temp[String::CINLIM];
    is.get(temp,String::CINLIM);
    if(is)
        st = temp; //在此处" = "已被重载过了
    while(is && is.get()!='\n')
        continue;
    return is;
}
int main()
{
    String A = "abcd";
    String B = "efgh";
    String C = A + B;
    cout << C << endl;
}