zoukankan      html  css  js  c++  java
  • C++自定义String字符串类,支持子串搜索

    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()!='
    ')
            continue;
        return is;
    }
    int main()
    {
        String A = "abcd";
        String B = "efgh";
        String C = A + B;
        cout << C << endl;
    }
    
  • 相关阅读:
    ORACLE 计算时间相减间隔
    oracle中游标详细用法
    oracle中计算某月的天数
    Unity3D导出的EXE不用显示分辨率选择界面
    Unity3D 之暂停和继续的实现
    double的值太大,以及补0
    Unity3D鼠标点击物体产生事件
    java POi excel 写入大批量数据
    Unity3D 判断鼠标是否按在UGUI上
    Unity3D 之UGUI 滚动条
  • 原文地址:https://www.cnblogs.com/1Kasshole/p/9382828.html
Copyright © 2011-2022 走看看