• 堆分配存储表示的串其基本操作的实现


    以一组地址连续的存储单元存放串值字符序列,但它们的存储空间是在程序执行过程中动态分配而得。

    下面是基本操作的头文件

    #define TRUE 1
    #define FALSE 0
    #define OK 1
    #define ERROR 0
    #define INFEASIBLE -1
    #define MYOVERFLOW -2
    typedef int Status;
    
    
    //-------串的堆分配存储表示---------
    typedef struct{
        char *ch;   //若是非空串,则按串长分配存储区,否则ch为NULL
        int length; //串长度
    }HString;
    
    //------基本操作的函数原型说明--------
    
    Status StrAssign(HString &T, char *chars);//生成一个其值等于串常量chars的串T
    
    int StrLength(HString S);//返回S的元素个数,称为串的长度
    
    int StrCompare(HString S, HString T);//若S>T,则返回值>0;若S==T,则返回值为0,若S<T,则返回值<0
    
    Status ClearString(HString &S);//将S清为空串,并释放S所占空间
    
    Status Concat(HString &T, HString S1, HString S2);//用串T返回由S1和S2联接而成的新串
    
    Status SubString(HString &Sub,HString S, int pos, int len);
    //1<=pos<<StrLength(S)且0<=len<=StrLength(S)-pos+1
    //返回串S的第pos个字符起长度为len的子串
    
    Status StrCopy(HString &T, HString S);//串S存在,由串S复制得到串T
    
    Status StrEmpty(HString S);//串S存在,若S为空串,则返回TRUE,否则返回FALSE
    
    int Index(HString S, HString T, int pos);
    //串S和串T存在,T是非空串,1<=pos<<Strlength(s).若主串S中存在和串T值相同的子串,则返回
    //它在主串S中第pos个字符之后第一次出现的位置;否则函数值为0;
    
    Status Replace(HString &S, HString T, HString V);
    //串S,T和V存在,T是非空串
    //用V替换主串S中出现的所有与T相等的不重叠的子串
    
    Status StrInsert(HString &S, int pos, HString T);
    //串S和T存在,1<=pos<<Strlength(S)+1.在串S的第pos个字符之前插入串T
    
    Status StrDelete(HString &S, int pos, int len);
    //串S存在,1<=pos<<Strlength(S)-len+1。从串S中删除第pos个字符起长度为len的子串
    
    Status DestroyString(HString &S);
    //串S存在,串S被销毁
                                       

    上述基本操作的实现:

    #include"stdafx.h"
    
    Status StrAssign(HString &T, char *chars)//生成一个其值等于串常量chars的串T
    {
        if (T.length > 0)delete T.ch;//如果T存在值,则删除T以前所占空间
        int i = 0;
        for (char *c = chars; *c; ++c, ++i){}//求chars的长度
        if (!i){ T.ch = NULL; T.length = 0; }
        else{
            if (!(T.ch = (char *)malloc((i+1)*sizeof(char))))//为T分配i+1个空间,最后一个空间储存NULL是为了操作方便
                exit(MYOVERFLOW);
            for (int j = 0; j < i; j++)//将chars[]的值传给T
                T.ch[j] = chars[j];
            T.ch[i] = NULL;
            T.length = i;        //T.length=i;
        }
        return OK;
    } 
    
    int StrLength(HString S)//返回S的元素个数,称为串的长度
    {
        return S.length;
    }
    
    int StrCompare(HString S, HString T)//若S>T,则返回值>0;若S==T,则返回值为0,若S<T,则返回值<0
    {
        for(int i=0;i<S.length&&i<T.length;i++)
        if (*(S.ch+i) != *(T.ch+i))//如果在未达到其中一个字符串的末端就有不等的,则返回第一个不相等的两字符之差
        return *(S.ch) - *(T.ch);
    
        return S.length - T.length;//如果全部相等,则返回字符串长度之差
    }
    
    Status ClearString(HString &S)//将S清为空串,并释放S所占空间
    {
        if (S.length)
        delete S.ch;//删除S所占空间
        S.ch = NULL;
        S.length = 0;
        return OK;
    }
    
    Status Concat(HString &T, HString S1, HString S2)//用串T返回由S1和S2联接而成的新串
    {
        if (T.length > 0)delete T.ch;
        T.ch = (char *)malloc((S1.length + S2.length+1)*sizeof(char));//为T分配空间,最后一个空间储存NULL是为了操作方便
        if (!T.ch)exit(MYOVERFLOW);
        int i = 0;
        for (; i < S1.length; i++)//将S1的值传给T
            T.ch[i] = S1.ch[i];
        for (int j = 0; i < S1.length + S2.length; i++, j++)//将S2的值传给T
            T.ch[i] = S2.ch[j];
        T.ch[i] = NULL;
        T.length = S1.length + S2.length;
        return OK;
    }
    
    Status SubString(HString &sub, HString S, int pos, int len)
    //1<=pos<<StrLength(S)且0<=len<=StrLength(S)-pos+1
    //返回串S的第pos个字符起长度为len的子串
    {
        if (sub.length > 0)delete sub.ch;
        if (len == 0){
            sub.ch = NULL;
            sub.length = len;
        }
        else{
            
            if (pos >= 1 && pos <= S.length&&len > 0 && len <= S.length - pos + 1)
            {
                sub.ch = (char *)malloc(len+1*sizeof(char));//为子串分配空间
                if (!sub.ch)exit(MYOVERFLOW);
                for (int i = 0; i < len; i++, pos++)//将相对应的字符传给子串
                    sub.ch[i] = S.ch[pos-1];
                sub.ch[len] = NULL;
                sub.length = len;
                return OK;
            }
        }
         return ERROR;
    }
    
    Status StrCopy(HString &T, HString S)//串S存在,由串S复制得到串T
    {
        if (T.length > 0)delete T.ch;
        if (S.length < 0)return ERROR;
        else{
            if (S.length == 0){
                T.ch = NULL;
                T.length = 0;
                return OK;
            }
            T.ch = (char *)malloc((S.length + 1)*sizeof(char));//为T分配空间
            for (int i = 0; i <= S.length; i++)//将S的值传给T
                T.ch[i] = S.ch[i];
            T.length = S.length;
            return OK;
        }
    }
    
    Status StrEmpty(HString S)//串S存在,若S为空串,则返回TRUE,否则返回FALSE
    {
        if (S.length == 0)return FALSE;
        else return TRUE;
    }
    
    int Index(HString S, HString T, int pos)
    //串S和串T存在,T是非空串,1<=pos<<Strlength(s).若主串S中存在和串T值相同的子串,则返回
    //它在主串S中第pos个字符之后第一次出现的位置;否则函数值为0;
    {
        if (T.length == 0)return 0;
        pos++;
        for (; pos + T.length-1 <= S.length; pos++)
        {
            HString sub;
            SubString(sub, S, pos, T.length);//求长度相等的子串
            if (StrCompare(T, sub) == 0)return pos;//如果该子串与T相等,则返回第一次出现的位置
        }
        return 0;
    }
    
    Status Replace(HString &S, HString T, HString V)
    //串S,T和V存在,T是非空串
    //用V替换主串S中出现的所有与T相等的不重叠的子串
    {
        if (T.length <= 0)return ERROR;
        for (int i = 0; i <= S.length - T.length; ){
            int j = 0;
            if (j = Index(S, T, i)){//如果S中存在于T相等的子串,则用V替换T
                HString sub1,sub2,temp;
                SubString(sub1, S, 1, j - 1);//求T之前的子串
                Concat(temp, sub1, V);       //将前子串与V相连保存在temp中
                if (SubString(sub2, S, j + T.length, S.length - T.length - j + 1))//求T之后的子串,如果T恰好在S的末尾,则不执行下面的操作
                {
                    Concat(S, temp, sub2);//将temp和后子串相连
                    i = j + V.length - 1;//因为不重叠,所以要将i的值移到j+V.length-1的位置上
                }
                else {                   //如果没有后子串则直接将temp拷贝给S
                    StrCopy(S, temp);
                    break;
                }
            }
            else break;
        }
        return OK;
    }
    
    Status StrInsert(HString &S, int pos, HString T)
    //串S和T存在,1<=pos<=Strlength(S)+1.在串S的第pos个字符之前插入串T
    {
        if (S.length >= 0 && T.length >= 0 && 1 <= pos&&pos <= S.length + 1){
            if (pos == S.length + 1){//如果是在S之后插入T
                HString temp;
                Concat(temp, S, T);//将S和T连接
                StrCopy(S, temp);//将S和T连接的值传给S
                return OK;
            }
            HString sub1, sub2,temp;//如果是在S中间插入T
            SubString(sub1, S, 1, pos - 1);//求前子串
            SubString(sub2, S, pos, S.length - pos + 1);//求后子串
            Concat(temp, sub1, T);//前子串与T相连保存在temp中
            Concat(S, temp, sub2);//后子串与temp相连传给S
            return OK;
        }
        else return ERROR;
    }
    
    Status StrDelete(HString &S, int pos, int len)
    //串S存在,1<=pos<<Strlength(S)-len+1。从串S中删除第pos个字符起长度为len的子串
    {
        if (1 <= pos&&pos <= S.length - len + 1){
            HString str1, str2;
            SubString(str1, S, 1, pos - 1);//求删除子串前的子串
            SubString(str2, S, pos + len, S.length - pos - len + 1);//求删除子串后的子串
            Concat(S, str1, str2);//将前子串和后子串相连
            return OK;
        }
        else return ERROR;
    }
    
    Status DestroyString(HString &S)
    //串S存在,串S被销毁
    {
        if (S.length>0){
            delete S.ch;
            S.length = 0;
            return OK;
        }
        else return ERROR;
    }

    主函数:

    // HString.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        HString str1, str2,str3;
        char ch[] = "lidanldan";
        StrAssign(str1, ch);
        char ch1[] = "dan";
        StrAssign(str2, ch1);
        char ch2[] = "dd";
        StrAssign(str3, ch2);
        Replace(str1, str2, str3);//验证替换
        cout << str1.ch << endl;
        StrInsert(str2, 2, str3);//验证插入
        cout << str2.ch << endl;
        StrDelete(str2, 2, 2);   //验证删除
        cout << str2.ch << endl;
        return 0;
    }

    结果:

    这是延续了C语言的风格,在字符串末尾加上一个结束字符。。C语言用'',本人用NULL。。其实在C++的最新标准中C++11,是不推荐这种风格的。而且不推荐用字符数组来表示字符串,而是用string

  • 相关阅读:
    HTML 常见标签part1
    HTML 初始
    jenkins远程执行脚本不退出
    jenkins 持续集成工具安装
    jenkins 杀掉衍生进程解决办法
    日志分割工具-crononlog
    可视化库 pygal 生成png中文乱码
    可视化库 pygal 无法保存成本地文件
    一个很好用的ORM库--peewee
    3 种进度条 -- 记录
  • 原文地址:https://www.cnblogs.com/csudanli/p/4818097.html
Copyright © 2020-2023  润新知