《串---堆存储结构》

//堆分配存储表示
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
typedef struct
{
    char *ch;    //若是非空串,则按串长分配存储区,否则ch为NULL
    int length;    //串长度
}HString;

//初始化产生空串T
void InitString(HString &T)
{
    T.ch = NULL;
    T.length = 0;
}
//若S为空串,则返回OK,否则返回ERROR
Status StrEmpty(HString T)
{
    if((T.length==0) && (T.ch = NULL))
        return OK;
    else
        return ERROR;
}
//生成一个其值等于串常量chars的串T
Status StrAssign(HString &T,char *chars)
{
    int i,j;
    if(T.ch)    free(T.ch);        //释放T原有空间
    i = strlen(chars);            //求chars的长度
    if(!i)
    {//chars的长度为0
        T.ch = NULL;
        T.length = 0;
    }
    else
    {//chars的长度不为0
        T.ch = (char *)malloc(i*sizeof(char));    //分配串空间
        if(!T.ch)    exit(OVERFLOW);                //分配串空间失败
        for(j = 0;j<i;j++)                        //拷贝串
            T.ch[j] = chars[j];
        T.length = i;
    }
    return OK;
}
//求串的长度
int StrLength(HString S)
{
    return S.length;
}
//输出字符串
void StrPrint(HString T)
{
    int i;
    for(i=0;i<T.length;i++)
        printf("%c",T.ch[i]);
    printf("\n");
}
//串比较
int StrCompare(HString S,HString T)
{
    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 StrCopy(HString &T,HString S)
{
    int i;
    if(T.ch)
        free(T.ch);    //释放T原有空间
    T.ch = (char *)malloc(S.length*sizeof(char));    //分配串空间
    if(!T.ch)
        exit(0);    //分配串空间失败
    for(i=0;i<S.length;i++)
        T.ch[i] = S.ch[i];
    T.length = S.length;
    return OK;
}
//将S清空为空串
Status ClearString(HString &S)
{
    if(S.ch)
    {
        free(S.ch);
        S.ch = NULL;
    }
    S.length = 0;
    return OK;
}
//用T返回由S1和S2连接而成的新串
Status Concat(HString &T,HString S1,HString S2)
{
    int i;
    if(T.ch)    free(T.ch);        //释放T原有的空间
    T.length = S1.length+S2.length;
    T.ch = (char*)malloc(T.length*sizeof(char));
    if(!T.ch)    exit(OVERFLOW);
    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];
    return OK;
}
//求子串
Status SubString(HString &Sub,HString S,int pos,int len)
{
    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(OVERFLOW);        //子串空间分配失败
        for(i=0;i<len;i++)
            Sub.ch[i] = S.ch[pos-1+i];
        Sub.length = len;
    }
    return OK;
}
//算法4.1
//T为非空串,若主串S中第pos个字符之后存在于T相等的子串
//则返回第一个这样的子串在S中的位置,否则返回0
int Index(HString S,HString T,int pos)
{
    int m,n,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;
}
//串插入操作
//在串S的第pos个字符之前插入串T
Status StrInsert(HString &S,int pos,HString T)
{
    int i;
    if(pos<1 || pos>S.length+1)
        return ERROR;
    if(T.length)
    {//T非空,则重新分配空间,插入T
        if(!(S.ch=(char *)realloc(S.ch,(S.length+T.length)+sizeof(char))))
            exit(OVERFLOW);
        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];
        S.length+=T.length;
    }
    return OK;
}
//从串S中删除第pos个字符起长度为len的子串
int StrDelete(HString &S,int pos,int len)
{
    int i;
    if(S.length<pos+len-1)
        exit(0);
    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;
}
//用V替换主串S中出现的所有与T相等的不重叠的子串
int Replace(HString &S,HString T,HString V)
{
    int i = 1;    //从串S的第一个字符起查找串T
    if(StrEmpty(T))    //T是空串
        return ERROR;
    do
    {
        i = Index(S,T,i);
        if(i)    //串S中存在串T
        {
            StrDelete(S,i,StrLength(T));    //删除该串T
            StrInsert(S,i,V);    //在原串T的位置插入串V
            i+=StrLength(V);
        }
    }while(i);
        return OK;
}

int main()
{
    int i;
    char c,*p="God bye!",*q = "God luck!";
    HString t,s,r;

    InitString(t);
    InitString(s);
    InitString(r);

    StrAssign(t,p);
    printf("串t为:");
    StrPrint(t);
    printf("串长为%d 串空否?%d(1:空 0:否)\n",StrLength(t),StrEmpty(t));
    StrAssign(s,q);
    printf("串s为:");
    StrPrint(s);
    i = StrCompare(s,t);
    if(i<0)
        c=‘<‘;
    else if(i==0)
        c=‘=‘;
    else
        c=‘>‘;
    printf("串s%c串t\n",c);
    Concat(r,t,s);
    printf("串t连接串s产生的串r为:");
    StrPrint(r);
    StrAssign(s,"oo");
    printf("串s为:");
    StrPrint(s);
    StrAssign(t,"o");
    printf("串t为:");
    StrPrint(t);
    Replace(r,t,s);
    printf("把串r中和串t中相同的子串用s代替后,串r为:\n");
    StrPrint(r);
    ClearString(s);
    printf("串s清空后,串长为%d 空否?%d(1:空 0:否)\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("复制串t为串r,串t为:");
    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));
    system("pause");
    return 0;
}
时间: 2024-10-14 19:02:04

《串---堆存储结构》的相关文章

CI框架源码阅读笔记3 全局函数Common.php

从本篇开始,将深入CI框架的内部,一步步去探索这个框架的实现.结构和设计. Common.php文件定义了一系列的全局函数(一般来说,全局函数具有最高的加载优先权,因此大多数的框架中BootStrap引导文件都会最先引入全局函数,以便于之后的处理工作). 打开Common.php中,第一行代码就非常诡异: if ( ! defined('BASEPATH')) exit('No direct script access allowed'); 上一篇(CI框架源码阅读笔记2 一切的入口 index

IOS测试框架之:athrun的InstrumentDriver源码阅读笔记

athrun的InstrumentDriver源码阅读笔记 作者:唯一 athrun是淘宝的开源测试项目,InstrumentDriver是ios端的实现,之前在公司项目中用过这个框架,没有深入了解,现在回来记录下. 官方介绍:http://code.taobao.org/p/athrun/wiki/instrumentDriver/ 优点:这个框架是对UIAutomation的java实现,在代码提示.用例维护方面比UIAutomation强多了,借junit4的光,我们可以通过junit4的

Yii源码阅读笔记 - 日志组件

?使用 Yii框架为开发者提供两个静态方法进行日志记录: Yii::log($message, $level, $category);Yii::trace($message, $category); 两者的区别在于后者依赖于应用开启调试模式,即定义常量YII_DEBUG: defined('YII_DEBUG') or define('YII_DEBUG', true); Yii::log方法的调用需要指定message的level和category.category是格式为“xxx.yyy.z

源码阅读笔记 - 1 MSVC2015中的std::sort

大约寒假开始的时候我就已经把std::sort的源码阅读完毕并理解其中的做法了,到了寒假结尾,姑且把它写出来 这是我的第一篇源码阅读笔记,以后会发更多的,包括算法和库实现,源码会按照我自己的代码风格格式化,去掉或者展开用于条件编译或者debug检查的宏,依重要程度重新排序函数,但是不会改变命名方式(虽然MSVC的STL命名实在是我不能接受的那种),对于代码块的解释会在代码块前(上面)用注释标明. template<class _RanIt, class _Diff, class _Pr> in

CI框架源码阅读笔记5 基准测试 BenchMark.php

上一篇博客(CI框架源码阅读笔记4 引导文件CodeIgniter.php)中,我们已经看到:CI中核心流程的核心功能都是由不同的组件来完成的.这些组件类似于一个一个单独的模块,不同的模块完成不同的功能,各模块之间可以相互调用,共同构成了CI的核心骨架. 从本篇开始,将进一步去分析各组件的实现细节,深入CI核心的黑盒内部(研究之后,其实就应该是白盒了,仅仅对于应用来说,它应该算是黑盒),从而更好的去认识.把握这个框架. 按照惯例,在开始之前,我们贴上CI中不完全的核心组件图: 由于BenchMa

CI框架源码阅读笔记2 一切的入口 index.php

上一节(CI框架源码阅读笔记1 - 环境准备.基本术语和框架流程)中,我们提到了CI框架的基本流程,这里这次贴出流程图,以备参考: 作为CI框架的入口文件,源码阅读,自然由此开始.在源码阅读的过程中,我们并不会逐行进行解释,而只解释核心的功能和实现. 1.       设置应用程序环境 define('ENVIRONMENT', 'development'); 这里的development可以是任何你喜欢的环境名称(比如dev,再如test),相对应的,你要在下面的switch case代码块中

Apache Storm源码阅读笔记

欢迎转载,转载请注明出处. 楔子 自从建了Spark交流的QQ群之后,热情加入的同学不少,大家不仅对Spark很热衷对于Storm也是充满好奇.大家都提到一个问题就是有关storm内部实现机理的资料比较少,理解起来非常费劲. 尽管自己也陆续对storm的源码走读发表了一些博文,当时写的时候比较匆忙,有时候衔接的不是太好,此番做了一些整理,主要是针对TridentTopology部分,修改过的内容采用pdf格式发布,方便打印. 文章中有些内容的理解得益于徐明明和fxjwind两位的指点,非常感谢.

CI框架源码阅读笔记4 引导文件CodeIgniter.php

到了这里,终于进入CI框架的核心了.既然是"引导"文件,那么就是对用户的请求.参数等做相应的导向,让用户请求和数据流按照正确的线路各就各位.例如,用户的请求url: http://you.host.com/usr/reg 经过引导文件,实际上会交给Application中的UsrController控制器的reg方法去处理. 这之中,CodeIgniter.php做了哪些工作?我们一步步来看. 1.    导入预定义常量.框架环境初始化 之前的一篇博客(CI框架源码阅读笔记2 一切的入

jdk源码阅读笔记之java集合框架(二)(ArrayList)

关于ArrayList的分析,会从且仅从其添加(add)与删除(remove)方法入手. ArrayList类定义: p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Monaco } span.s1 { color: #931a68 } public class ArrayList<E> extends AbstractList<E> implements List<E> ArrayList基本属性: /** *

dubbo源码阅读笔记--服务调用时序

上接dubbo源码阅读笔记--暴露服务时序,继续梳理服务调用时序,下图右面红线流程. 整理了调用时序图 分为3步,connect,decode,invoke. 连接 AllChannelHandler.connected(Channel) line: 38 HeartbeatHandler.connected(Channel) line: 47 MultiMessageHandler(AbstractChannelHandlerDelegate).connected(Channel) line: