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

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

下面是基本操作的头文件

#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语言用‘\0‘,本人用NULL。。其实在C++的最新标准中C++11,是不推荐这种风格的。而且不推荐用字符数组来表示字符串,而是用string

时间: 2024-12-18 21:44:47

堆分配存储表示的串其基本操作的实现的相关文章

堆分配存储的串的表示和实现

串的堆分配存储结构 struct HString { char * ch;//若是非空串,则按串长分配存储区:否则ch为NULL int length;//串长度 }; 堆分配存储的串的12个基本操作 #define DestroyString ClearString//DestroyString()和ClearString()作用相同 void InitString(HString &S){ S.length = 0; S.ch = NULL; } void ClearString(HStri

串的堆分配存储表示与实现--自己写数据结构

本次实现的数据结构是关于串的表示与实现,首先讲串的堆分配存储表示与实现,后面的博客将贴出串的另外数据结构的表示和实现 heapstring.h文件存放数据结构体,如下 #ifndef _HEAPSRING_H_ #define _HEAPSRING_H_ typedef struct _HString { char *ch; int length; }HString,*pHString; pHString init_null_string(void); pHString init_heap_st

数据结构-串的堆分配存储

串的堆分配存储表示的特点是,仍以一组地址连续的存储单元存放串值字符序列,但它们的存储空间是在程序执行过程中动态分配的.使用动态分配函数malloc()和函数free()来管理存储空间的大小. 串的堆分配存储方法具有顺序存储的特点,又弥补了定长存储的大小限制,多以多被采用. 1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 5 typedef int Status; 6 #define O

C语言实现数据结构串(堆分配存储表示法)

-------------------------------------------- 堆分配存储表示法 -------------------------------------------- 存储结构: 构建堆来存储字符串,本质上是顺序表 -------------------------------------------- 实现代码: 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h>

串的堆分配存储结构

串的堆分配存储,其具体实现方式是采用动态数组存储字符串. 通常,编程语言会将程序占有的内存空间分成多个不同的区域,程序包含的数据会被分们别类并存储到对应的区域.拿C语言来说,程序会将内存分为4个区域,分别为堆区.栈区.数据区和代码区.其中的堆分配 与其他区域不同,堆区的内存空间需要程序员手动使用malloc函数申请,并且在不用后要手动通过free函数将其释放 代码: #include <stdio.h>#include <stdlib.h>#include <string.h

【数据结构】串的堆分配表示与实现

采用堆分配存储表示的串被称为堆串,与顺序串相比,地址空间仍是连续,但空间是在程序执行时动态分配的. 程序中会使用到的realloc函数: //realloc : (void *)reelloc (void *ptr,unsigned newsize); //使用 : char *str; //   str = (char *)realloc(str,20); 代码实现如下: <span style="font-size:18px;">#pragma once #includ

c语言描述-串的基本操作

串的定长顺序存储(部分代码) 连接两个串: 串的第一个空间存储串长 #define MIXSIZE 100 typedef int Status; typedef char SString[MIXSIZE+1]; Status Concat(SString *s3,SString s1,SString s2) { if(s1[0]+s2[0]<=MIXSIZE) { printf("fgsd\n"); for(int i=1;i<=s1[0];i++) { *s3[i]=s

23、蛤蟆的数据结构笔记之二十三串的堆分配实现

23.蛤蟆的数据结构笔记之二十三串的堆分配实现 本篇名言:"人的价值是由自己决定的." 接下去是看下如何用C实现串. 欢迎转载,转载请标明出处: 1.  定义 定义结构体如下,一种字符数组,一个表示数组的长度.以一组地址连续的存储单元存放串值字符序列,但是他们的存储空间是在程序执行过程中动态分配而得. typedefstruct { charch[MAXLEN]; intlen; }SString; 2.  复制 将一个串内容复制到另一个结构体中区. SString StrCopy(S

数据结构—串的堆分配

#include<stdio.h> #include<stdlib.h> typedef struct { char *ch; int length; }HString; void StrAssign(HString &T,char *chars); void StrLength(HString S); void StrCompare(HString S,HString T); void ClearString(HString &S); void Concat(HS