數據結構:字符串的基本操作

字符串(string)是由0個或多個字符組成的有限序列。一般使用順序存儲結構,末尾以’\0’表示結束,但不計入字符串的長度。
這裏寫圖片描述
示例程序:(改編自《大話數據結構》

#include<iostream>
using namespace std;

#define MAXSIZE 20
typedef char String[MAXSIZE + 1]; //以'\0'結尾
/* 生成一個串*/
bool StrAssign(String Dest, char *ptr)
{
    cout << "Assign Str ..." << endl;
    int i;
    for (i = 0; ptr[i] != '\0' && i < MAXSIZE; i++)
        Dest[i] = ptr[i];
    Dest[i] = '\0';
    return true;
}
/* 拷貝一個字符串 */
bool StrCopy(String Dest, String Src)
{
    cout << "Copy Str ..." << endl;
    int i;
    for (i = 0; Src[i] != '\0' && i < MAXSIZE; i++)
        Dest[i] = Src[i];
    Dest[i] = '\0';
    return true;
}

int StrLength(String Src)
{
    int i = 0;
    while (Src[i] != '\0')
        i++;
    return i;
}

bool StrEmpty(String Src)
{
    if (StrLength(Src) == 0)
        return true;
    else
        return false;

}
/* 若Str1>Str2,則返回值>0;若Str1=Str2,則返回值=0;若Str1<Str2,則返回值<0 */
int StrCompare(String Str1, String Str2)
{
    int len1 = StrLength(Str1);
    int len2 = StrLength(Str2);
    for (int i = 0; i < len1 && i < len2; i++)
        if (Str1[i] != Str2[i])
            return Str1[i] - Str2[i];
    return len1 - len2;
}

bool ClearString(String Src)
{
    for (int i = 0; Src[i] != '\0'; i++)
        Src[i] = '\0';
    return true;
}
/* 用Dest返回Str1和Str2聯接而成的新串。若未截斷,則返回TRUE,否則FALSE */
bool StrConcate(String Dest, String Str1, String Str2)
{
    cout << "Concate String ..." << endl;
    if (StrLength(Str1) + StrLength(Str2) <= MAXSIZE)
    {
        /*  未截斷 */
        int i, j;
        for (i = 0; Str1[i] != '\0'; i++)
            Dest[i] = Str1[i];
        j = i;
        for (i = 0; Str2[i] != '\0'; i++, j++)
            Dest[j] = Str2[i];
        Dest[j] = '\0';
        return true;
    }
    else //截斷Str2
    {
        int i, j;
        for (i = 0; Str1[i] != '\0'; i++)
            Dest[i] = Str1[i];
        j = i;
        for (i = 0; Str2[i] != '\0' && j <= MAXSIZE - 1; i++, j++)
            Dest[j] = Str2[i];
        Dest[j] = '\0';
        return false;
    }

}
/* 用Sub返回串Src的第pos個字符起長度爲len的子串。 */
bool SubString(String Sub, String Src, int pos, int len)
{
    /*cout<<"Get SubString ..."<<endl;*/
    if (pos < 1 || pos > StrLength(Src) ||
            len < 0 || len > StrLength(Src) - pos + 1)
        return false;
    int i;
    for (i = 0; i <= len - 1; i++)
        Sub[i] = Src[i + pos - 1];
    Sub[i] = '\0';
    return true;
}
/* 返回子串Sub在主串Src中第pos個字符之後的位置。若不存在,則函數返回值爲0。 */
int Index1(String Src, String Sub, int pos)
{
    int len1 = StrLength(Src);
    int len2 = StrLength(Sub);
    int i = pos;
    String sub;
    if (pos > 0)
    {
        while (i <= len1 - len2 + 1)
        {
            SubString(sub, Src, i, len2);
            /* 如果兩串相等 , 則返回i值 */
            if (StrCompare(Sub, sub) == 0)
                return i;
            else/* 如果兩串不相等,前進位置 */
                i++;
        }
    }
    return 0;
}

int Index2(String Src, String Sub, int pos)
{
    int i = pos - 1;
    int j = 0;
    int len1 = StrLength(Src);
    int len2 = StrLength(Sub);
    while (i <= len1 - 1 && j <= len2 - 1)
    {
        if (Src[i] == Sub[j])/* 兩字母相等則繼續 */
        {
            ++i;
            ++j;
        }
        else
        {
            /* i退回到上次匹配首位的下一位 */
            i = i - j + 1;
            j = 0;/* j退回到子串Sub的首位 */
        }
    }

    if (j == len2) //子串已經遍歷完畢
        return i - len2 + 1;
    else
        return 0;
}
/* 在串Src的第pos個字符之前插入串In。完全插入返回TRUE,部分插入返回FALSE */
bool StrInsert(String Src, int pos, String In)
{
    int i;
    int len1 = StrLength(Src);
    int len2 = StrLength(In);
    if (pos < 1 || pos > len1 + 1)
        return false;

    if (len1 + len2 <= MAXSIZE)
    {
        /*  完全插入 */
        for (i = len1; i >= pos - 1; i--)
            Src[i + len2] = Src[i];
        for (i = pos - 1; i < pos + len2 - 1; i++)
            Src[i] = In[i - pos + 1];
        if (pos == len1 + 1) //末尾插入,最後添加'\0'
            Src[i] = '\0';
        return true;
    }

    else
    {
        /*  部分插入,In截斷 */
        for (i = MAXSIZE; i > pos; i--)
            Src[i] = Src[pos + i - MAXSIZE];

        for (i = 0; i < MAXSIZE - pos; i++)
            Src[pos - 1 + i] = In[i];
        return false;
    }
}
/* 從串Src中刪除第pos個字符起長度爲len的子串 */
bool StrDelete(String Src, int pos, int len)
{
    int i;
    if (pos < 1 || pos > StrLength(Src) - len + 1 || len < 0)
        return false;
    for (i = pos + len - 1; i <= StrLength(Src); i++)
        Src[i - len] = Src[i];
    return true;
}
/* 用Re替換主串Src中出現的所有與Sub相等的不重疊的子串 */
bool StrReplace(String Src, String Sub, String Re)
{
    int i = 1;/*  從串Src的第一個字符起查找串Sub */
    if (StrEmpty(Sub))
        return false;
    do
    {
        i = Index1(Src, Sub, i);/*  結果i爲從上一個i之後找到的子串Sub的位置 */

        if (i)
        {
            StrDelete(Src, i, StrLength(Sub));/*  刪除該串Sub */
            StrInsert(Src, i, Re); /*  在原串Sub的位置插入串Re */
            i += StrLength(Re);/*  在插入的串Re後面繼續查找串Sub */
        }

    }
    while (i);

    return true;
}

void StrPrint(String Src)
{
    cout << "Print Str ..." << endl;
    for (int i = 0; Src[i] != '\0'; i++)
        cout << Src[i];
    cout << endl;

}

int main(void)
{
    String Str1;
    StrAssign(Str1, "ILOVEYOU");
    StrPrint(Str1);

    String Str2;
    StrCopy(Str2, Str1);
    StrPrint(Str2);

    if (!StrEmpty(Str1))
        cout << "Str1's Length : " << StrLength(Str1) << endl;

    String Str3;
    StrAssign(Str3, "ILOVEyou");

    if (StrCompare(Str1, Str3) > 0)
        cout << "Str1 > Str3" << endl;
    else if (StrCompare(Str1, Str3) == 0)
        cout << "Str1 = Str3" << endl;
    else
        cout << "Str1 < Str3" << endl;

    String Str4, Str5;
    StrAssign(Str4, " HLZ");
    StrConcate(Str5, Str1, Str4);
    StrPrint(Str5);

    String Str6;
    cout << "Get SubString ..." << endl;
    SubString(Str6, Str5, 1, 8);
    StrPrint(Str6);

    cout << "Index of (Str5, Str4) " << Index2(Str5, Str4, 2) << endl;

    StrInsert(Str6, 9, " HLZ");
    StrPrint(Str6);
    StrInsert(Str6, 8, " HLZ");
    StrPrint(Str6);

    StrDelete(Str5, 2, 4);
    StrPrint(Str5);

    String Str7, Str8;
    StrAssign(Str7, "ILOVEJDWSOVEDSOVEde");
    StrAssign(Str8, "OVE");
    StrReplace(Str7, Str8, "ove");
    StrPrint(Str7);

    return 0;
}

輸出爲:
這裏寫圖片描述
對於字符串的鏈式存儲結構來說,一個節點存放多少個字符才合適顯得很重要,這會直接影響字符串處理的效率,需要根據實際情況做出選擇。但字符串的鏈式存儲結構除了在連接串與串操作時有一定方便之外,總的來說不如順序存儲靈活,性能也不如順序存儲結構好。

轉載自:http://blog.csdn.net/jnu_simba/article/details/8849135

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章