《数据结构》-堆串的表示和实现

#include <string.h>
#include <malloc.h>
#include <stdio.h>

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1

typedef int Status;  // Status是函数的类型,其值是函数结果状态代码,如OK等
typedef int Boolean; // Boolean是布尔类型,其值是TRUE或FALSE

// 串的堆分配存储
typedef struct HString
{
    char *ch;   // 若是非空串,则按串长分配存储区,否则ch为NULL
    int length; // 串长度
} HString;

// 串采用堆分配存储结构的基本操作(14个)。包括算法4.1、4.4

#define DestroyString ClearString // DestroyString()与ClearString()作用相同

void StrAssign(HString *T, char *chars)
{ // 生成一个其值等于串常量chars的串T
    int i, j;
    if (T->ch)
        free(T->ch);   // 释放T原有空间
    i = strlen(chars); // 求chars的长度i
    if (!i)
    { // chars的长度为0
        T->ch = NULL;
        T->length = 0;
    }
    else
    {                                             // chars的长度不为0
        T->ch = (char *)malloc(i * sizeof(char)); // 分配串空间
        if (!T->ch)                               // 分配串空间失败
            exit(-1);
        for (j = 0; j < i; j++) // 拷贝串
            T->ch[j] = chars[j];
        T->length = i;
    }
}

void StrCopy(HString *T, HString S)
{ // 初始条件:串S存在。操作结果:由串S复制得串T
    int i;
    if (T->ch)
        free(T->ch);                                 // 释放T原有空间
    T->ch = (char *)malloc(S.length * sizeof(char)); // 分配串空间
    if (!T->ch)                                      // 分配串空间失败
        exit(-1);
    for (i = 0; i < S.length; i++) // 拷贝串
        T->ch[i] = S.ch[i];
    T->length = S.length;
}

Status StrEmpty(HString S)
{ // 初始条件:串S存在。操作结果:若S为空串,则返回TRUE,否则返回FALSE
    if (S.length == 0 && S.ch == NULL)
        return TRUE;
    else
        return FALSE;
}

int StrCompare(HString S, HString T)
{ // 若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0
    int i;
    for (i = 0; i < S.length && i < T.length; ++i)
        if (S.ch[i] != T.ch[i])
            return S.ch[i] - T.ch[i];
    return S.length - T.length;
}

int StrLength(HString S)
{ // 返回S的元素个数,称为串的长度
    return S.length;
}

void ClearString(HString *S)
{ // 将S清为空串
    free(S->ch);
    S->ch = NULL;
    S->length = 0;
}

void Concat(HString *T, HString S1, HString S2)
{ // 用T返回由S1和S2联接而成的新串
    int i;
    if (T->ch)
        free(T->ch); // 释放旧空间
    T->length = S1.length + S2.length;
    T->ch = (char *)malloc(T->length * sizeof(char));
    if (!T->ch)
        exit(-1);
    for (i = 0; i < S1.length; i++)
        T->ch[i] = S1.ch[i];
    for (i = 0; i < S2.length; i++)
        T->ch[S1.length + i] = S2.ch[i];
}

Status SubString(HString *Sub, HString S, int pos, int len)
{ // 用Sub返回串S的第pos个字符起长度为len的子串。
    // 其中,1≤pos≤StrLength(S)且0≤len≤StrLength(S)-pos+1
    int i;
    if (pos < 1 || pos > S.length || len < 0 || len > S.length - pos + 1)
        return ERROR;
    if (Sub->ch)
        free(Sub->ch); // 释放旧空间
    if (!len)          // 空子串
    {
        Sub->ch = NULL;
        Sub->length = 0;
    }
    else
    { // 完整子串
        Sub->ch = (char *)malloc(len * sizeof(char));
        if (!Sub->ch)
            exit(-1);
        for (i = 0; i <= len - 1; i++)
            Sub->ch[i] = S.ch[pos - 1 + i];
        Sub->length = len;
    }
    return OK;
}

void InitString(HString *T)
{ // 初始化(产生空串)字符串T。另加
    T->length = 0;
    T->ch = NULL;
}

int Index(HString S, HString T, int pos) // 算法4.1
{                                        // T为非空串。若主串S中第pos个字符之后存在与T相等的子串,
    // 则返回第一个这样的子串在S中的位置,否则返回0
    int n, m, i;
    HString sub;
    InitString(&sub);
    if (pos > 0)
    {
        n = StrLength(S);
        m = StrLength(T);
        i = pos;
        while (i <= n - m + 1)
        {
            SubString(&sub, S, i, m);
            if (StrCompare(sub, T) != 0)
                ++i;
            else
                return i;
        }
    }
    return 0;
}

Status StrInsert(HString *S, int pos, HString T) // 算法4.4
{                                                // 1≤pos≤StrLength(S)+1。在串S的第pos个字符之前插入串T
    int i;
    if (pos < 1 || pos > S->length + 1) // pos不合法
        return ERROR;
    if (T.length) // T非空,则重新分配空间,插入T
    {
        S->ch = (char *)realloc(S->ch, (S->length + T.length) * sizeof(char));
        if (!S->ch)
            exit(-1);
        for (i = S->length - 1; i >= pos - 1; --i) // 为插入T而腾出位置
            S->ch[i + T.length] = S->ch[i];
        for (i = 0; i < T.length; i++)
            S->ch[pos - 1 + i] = T.ch[i]; // 插入T
        S->length += T.length;
    }
    return OK;
}

Status StrDelete(HString *S, int pos, int len)
{ // 从串S中删除第pos个字符起长度为len的子串
    int i;
    if (S->length < pos + len - 1)
        return ERROR;
    for (i = pos - 1; i <= S->length - len; i++)
        S->ch[i] = S->ch[i + len];
    S->length -= len;
    S->ch = (char *)realloc(S->ch, S->length * sizeof(char));
    return OK;
}

Status Replace(HString *S, HString T, HString V) // 此函数与串的存储结构无关
{                                                // 初始条件:串S,T和V存在,T是非空串
    // 操作结果:用V替换主串S中出现的所有与T相等的不重叠的子串
    int i = 1;       // 从串S的第一个字符起查找串T
    if (StrEmpty(T)) // T是空串
        return ERROR;
    do
    {
        i = Index(*S, T, i); // 结果i为从上一个i之后找到的子串T的位置
        if (i)               // 串S中存在串T
        {
            StrDelete(S, i, StrLength(T)); // 删除该串T
            StrInsert(S, i, V);            // 在原串T的位置插入串V
            i += StrLength(V);             // 在插入的串V后面继续查找串T
        }
    } while (i);
    return OK;
}

void StrPrint(HString T)
{ // 输出T字符串。另加
    int i;
    for (i = 0; i < T.length; i++)
        printf("%c", T.ch[i]);
    printf("\n");
}

void main(int argc, char *argv[])
{
    int i;
    char c, *p = "God bye!", *q = "God luck!";
    HString t, s, r;
    InitString(&t); // HString类型必须初始化
    InitString(&s);
    InitString(&r);
    StrAssign(&t, p);
    printf("string t is:");
    StrPrint(t);
    printf("string len is %d empty? %d(1 yes 0 no)\n", StrLength(t), StrEmpty(t));
    StrAssign(&s, q);
    printf("string s is:");
    StrPrint(s);
    i = StrCompare(s, t);
    if (i < 0)
        c = '<';
    else if (i == 0)
        c = '=';
    else
        c = '>';
    printf("string s %c string t\n", c);
    Concat(&r, t, s);
    printf("t cat s generate r is :");
    StrPrint(r);
    StrAssign(&s, "oo");
    printf("strint s is:");
    StrPrint(s);
    StrAssign(&t, "o");
    printf("strint t is:");
    StrPrint(t);
    Replace(&r, t, s);
    printf("r same t replace s s is:");
    StrPrint(r);
    ClearString(&s);
    printf("clear s len is %d empty ?%d(1 yes 0 no)\n", StrLength(s), StrEmpty(s));
    SubString(&s, r, 6, 4);
    printf("s r 6 4 %d  s", s.length);
    StrPrint(s);
    StrCopy(&t, r);
    printf("copy to r t is:");
    StrPrint(t);
    StrInsert(&t, 6, s);
    printf("t 6 s t ");
    StrPrint(t);
    StrDelete(&t, 1, 5);
    printf("t 1 5 t ");
    StrPrint(t);
    printf("%d t 1 s 1\n", Index(t, s, 1));
    printf("%d t 2 s 1\n", Index(t, s, 2));
    DestroyString(&t); // 销毁操作同清空
    while (1);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值