C++自定義String字元串類,支持子串搜索

来源:https://www.cnblogs.com/1Kasshole/archive/2018/07/28/9382828.html
-Advertisement-
Play Games

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;
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 代碼來源: 張戈博客 zhengge.net 詳細內容關註 "YUGE'S BLOG" "https://www.yugepower.com" ...
  • 5-1動態記憶體分配,分配的是堆記憶體的空間 分配記憶體函數 (都集中在庫函數 stdlib.h 中) 在使用動態分配之前,首先要判斷是否分配成功。 記憶體的釋放函數原型: 記憶體釋放後建議把指針指向NULL 5-2隊列(初始化,入隊,出隊,判斷空,判斷滿) 單向隊列 迴圈隊列 (隊頭和隊尾有兩種情況會指向同 ...
  • 就其本質而言,正則表達式(或 RE)是一種小型的、高度專業化的編程語言,(在Python中)它內嵌在Python中,並通過 re 模塊實現。正則表達式模式被編譯成一系列的位元組碼,然後由用 C 編寫的匹配引擎執行。 字元匹配(普通字元,元字元): 1 普通字元:大多數字元和字母都會和自身匹配 >>> ...
  • 1、np.vstack() :垂直合併 2、np.hstack():水平合併 3、np.newaxis():轉置 4、np.concatenate():針對多個矩陣或序列的合併操作 ...
  • 問題:使用IDEA創建Maven工程時提示"...xxx/pom.xml already exists in VFS",怎麼辦? 解決:如果只是刪除工程,還會有這樣的提示。說到底,刪除工程後,還要清理IDEA的緩存。 1、在IDEA中任意打開一個工程 2、在菜單中依次找到"File > Invali ...
  • HashMap實現原理 HashMap的底層使用數組+鏈表/紅黑樹實現。 這表示HashMap是Node數組構成,其中Node類的實現如下,可以看出這其實就是個鏈表,鏈表的每個結點是一個映射。 HashMap的每個下標都存放了一條鏈表。 常量/變數定義 關於modCount的作用見 "這篇blog" ...
  • 本文為原創,轉載請註明出處:https://www.cnblogs.com/Tom-shushu/p/9383066.html 本篇內容主要介紹:通過Servlet,JSP,Bootstrap框架以及MySQL等知識實現一個簡單地對資料庫信息進行:增,刪,改,查,分頁的操作; <一>設計資料庫 這裡 ...
  • try:將有可能導致出現異常的語句放到try塊中,如果使用了try語句後,後面的程式必須至少要跟一個except或者finally,否則程式會報錯 except:捕獲try塊中可能出現的異常 finally:不管程式是否有無異常,都會最終執行該語句 for example as below: 結果如 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...