zoukankan      html  css  js  c++  java
  • 数据结构05堆串20205106009郭睿玥

    /*郭睿玥第五次算法实验作业*/
    
    /*实验原理
         串的堆存储结构,与定长顺序串的存储结构类似,都是用一维数组地址连续的存储单元存储串
     的字符序列,不同的是堆串的存储空间是在程序执行过程中动态分配的。
         在系统中存在一个称为“堆”的自由存储区,每当建立一个新串时,可以通过动态分配函数从
     这个空间中分配一块实际串所需的存储空间,来存储新的串值。只要空间能分配成功,则在操作的
     过程中就不会发生“截断”的情况。C语言采用malloc()、free()等函数完成动态存储管理。
    */
    
    /*实验环境
    CodeBlocks*/
    
    
    /*实验目的
    1. 了解顺序串的结构特点及有关概念;
    2. 理解顺序串的存储结构;
    3. 掌握顺序串的基本操作算法。
    */
    
    
    
    /*实验内容
       建立顺序串,完成顺序串的基本操作:初始化、求串长、串赋值、串连接、求子串、串比较、字串定位、串插入、子串删除、串替换、串清空、串输出等。
    */
    
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #define MAXSIZE  100
    typedef int Status;// 定义函数返回值类型
    typedef char ElemType; // 定义每条数据的结构体类型
    typedef  struct{//定义串
       char  *stri;//若不是空串则按照串长度分配空间,否则为NULL
       int  length;//串长
    }string;//别名
    
    
    Status insitstring(string * SS){//初始化
        SS->stri =NULL;//空串不分配空间
        SS->length = 0;//空串串长为0
        return 1;
    }
    
    Status lengthstring(string * SS)//求串长
    {
        return SS->length;//返回SS的元素个数,串长度包含在数据结构中因此直接返回即可
    }
    
    void StrAssign(string *SS,char str1[])//串赋值
    {
       int i,j;
       if (SS->length)//如果不是空串则清空需要赋值的串
         free(SS);    //清空操作
       for(i=0;str1[i]!=NULL;i++)//循环查找所要赋值的字符数组,直到字符数组的某个元素为空,循环次数就是串长度
        {
            ;
       }
       SS->length=i;//串长度赋值
       if(i){
        SS->stri=(char*)malloc(SS->length*sizeof(char*));//根据串长度申请空间
        if(!SS->stri)//如果分配失败则结束
            exit(-1);//退出
        for(j=0;j<SS->length;j++)//通过循环逐个元素赋值,j表示循环次数,也表示被赋值的元素下标
        {
            SS->stri[j]=str1[j];//赋值操作
        }
       }
       else {//如果输入的字符数组不合理则重新输入
        printf("请重新输入\n");//提示
        char ch1[MAXSIZE];//新建数组
        gets(ch1);//输入
        StrAssign(SS,ch1);//递归调用赋值函数
       }
        return 0;//程序结束返回
    }
    
    
    void printstring(string T)//串输出
    {
        int i;
        for(i=0;i<T.length;i++)//通过循环逐个元素输出,i表示循环次数,也表示被赋值的元素下标
            printf("%c",T.stri[i]);//输出元素的值
         printf("\n");//换行
    }
    
    Status constring(string *SS,string *S)//串连接
    {
       int i,j;
       SS->stri=(char*)realloc(SS->stri,(SS->length+S->length )*sizeof(char));//根据需要连接的两个穿分配空间
        if(!SS->stri)//如果分配失败则结束
        {
            printf("分配空间失败");//提示
            exit(-1);//退出
        }
        else{//如果成功,则通过循环,按照顺序一个个把S的元素增加到SS内,i表示S下标,j表示SS下标
            for(i=0,j=SS->length;i<S->length;i++,j++)//循环,一共执行S->length次
                SS->stri[j]=S->stri[i];//赋值
            SS->length+=S->length;//改变串长
           }
      return 1;//返回
    }
    
    
    Status comparestring(string * SS,string *S)//串比较
    {
        int i,j;
        if(SS->length!=S->length)//首先比较串长,如果两个串的串长不一致比较无意义,故不进行比较
        {
            printf("两个串的长度不一致无法比较\n");//提示
            return 5;//返回
        }
        for(i=0;i<SS->length;i++)//通过循环,按照顺序逐个比较知道找到第一个两个串不一样的元素
        {
            if(SS->stri[i]>S->stri[i])//如果SS的第i个元素大,则返回1
                return 1;
            if(SS->stri[i]<S->stri[i])//如果S的第i个元素大,则返回
                    return -1;
                                      //如果两个一样大则循环继续
        }
        return 0;
    }
    
    void clearstring(string * SS)//串清空
    {
        if (SS->stri)//如果不是空串则清空需要赋值的串
         free(SS);//清空操作
        insitstring(SS);//调用初始化函数
        printf("清空成功");//提示
            return 0;//返回
    }
    
    Status emptystring(string * SS)//串判空
    {
        if (SS->length = 0) //空串的串长为0可以直接判断
            return 0; //空串返回0
        return 1;//非空串返回1
    }
    
    Status insertstring(string * SS,string * S,int pos)//串插入
    {
        if(pos < 0||pos-1>SS->length)//判断插入位置是否合法
        {
            printf("插入位置不正确\n");//提示
            return 0;//由于插入的位置不合法故函数无法进行
        }
        int i=SS->length-1,j=i+S->length,k;
        SS->stri=(char*)realloc(SS->stri,(SS->length+S->length )*sizeof(char));//根据需要连接的两个穿分配空间
        if(!SS->stri)//如果分配失败则结束
        {
            printf("内存分配失败");//提示
            exit(-1);//退出
        }
        for(k=0;k<SS->length-pos+1;i--,j--,k++)//通过循环,从后往前一直到要插入的位置的串元素依次后移
            SS->stri[j]=SS->stri[i];//后移操作
        for(i=0,j=pos-1;i<S->length;i++,j++)//通过循环,从要插入串的位置开始,依次赋值
            SS->stri[j]=S->stri[i];//赋值
        SS->length=SS->length+S->length;//改变串长
        printf("插入后的串为");//提示
        printstring(*SS);//调用输出函数输出插入后的串
        return 0;
    }
    
    Status findstring(string * substr,string  SS,int pos,int len)//截取子串
    {
        int i;
        if(!substr->stri)//如果不是空串则清空串
            free(substr->stri);//清空操作
        else
        {
           substr->stri=(char*)malloc(len*sizeof(char));//为子串分配空间
            if(!substr->stri)//如果分配失败则结束
            {
                printf("存储分配失败");//提示
                exit(-1);//退出
            }
            for(i=0;i<len;i++)//通过循环,从需要截取子串的位置开始,按照参数中的len截取子串
              substr->stri[i]=SS.stri[i+pos-1];//逐个元素截取
           substr->length=len;//子串长度就是参数中的len
            return 1;//返回
        }
    }
    
    Status searchsub(string * SS,string substr)//子串定位
    {
        int i=1,j=0,k;
        do{
            if(substr.stri[0]==SS->stri[j])//如果SS中存在子串则substr的第一个元素一定和ss的某个元素相等,如果相等往下比较,不相等ss后移
            {
                k=j+1;
                while(i<substr.length)//通过循环判断串的第i+1到第i+1+substr.length个元素的值是不是都和substr串一致
                {
                     if(substr.stri[i]!=SS->stri[k])//如果当前元素和子串的元素不一致则跳出循环
                       {
                           i=1;//返回初始状态方便下一次判断
                           j++;//j后移
                           break;//跳出循环
                        }
                    else {//如果一直接着判断下一个元素
                            i++;
                            k++;
                    }
                }
                if(i==substr.length)//判断是否进行完毕
                            break;//循环结束
            }
           else
                    j++;//如果SS中的第j个元素和子串中第0个元素不等则j后移
          }while(j<SS->length);//循环条件
          if(j==SS->length)//如果j能等于SS的串长则没有这个子串
            {
                printf("没有这个子串");//提示
                return -1;//返回
            }
    
            printf("字串位于第%d\n",j+1);//输出子串位置
            return j+1;//返回子串位置
    }
    
    void deletesub(string* SS,string substr,int pos)//子串删除
    {
        int i,len;
        char *p;//定义一个指针
        len=substr.length;
        if(pos<0||len<0||pos+len-1>SS->length)//判断删除位置是否合法
        {
            printf("删除位置不正确\n");//提示
            return 0;//由于删除的位置不合法故函数无法进行
        }
         p=(char*)malloc(SS->length-len);//根据需要删除的子串分配空间
        if(!p)//如果分配失败则结束
            exit(-1);//退出
        for(i=0;i<pos-1;i++)//将串第pos位置之前的字符复制到p中
            p[i]=SS->stri[i];
        for(i = pos-1;i < SS->length-len;i++)//将串第pos+len位置以后的字符复制到p中
           p[i] = SS->stri[i+len];//逐个元素复制
        SS->length=SS->length-len;//修改串的长度
        free(SS->stri);//释放原来的串S的内存空间
        SS->stri=p;//将串的str指向p字符串
        return 1;//返回
    }
    
    void repalcesub(string * SS,string substr,string*S)//串替换,用S替换串SS中的所有子串substr
    {
        int i=0,j;
        if(substr.length==0)//判断要替换的串是否是空串
            return 0;//返回
           do{//通过循环替换所有子串
            i=searchsub(SS,substr);//通过调用定位函数找到子串位置
            if(i==-1)//如果没有这个子串结束
                 return 0;//返回
            insertstring(SS,S,i);//在找到的位置里插入要替换的子串
            j=i+S->length;//j表示要被替换子串当前的位置
            deletesub(SS,substr,j);//根据位置删除要被替换的子串
            printf("现在s1为");//提示
            printstring(*SS);//输出替换后的SS
            }while(i!=-1);
    }
    
    int main()
    {
        char ch[MAXSIZE];
        string S1,S2,sub;//建立两个串
        int postion,length;//位置和长度
        printf("请输入S1\n");//提示
        gets(ch);//输入S1的串数据
        insitstring(&S1);//初始化S1
        StrAssign(&S1,ch);//用输入的字符数组为S1赋值
        printf("请输入S2\n");//提示
        gets(ch);//输入S2的串数据
        insitstring(&S2);//初始化S2
        StrAssign(&S2,ch);//用输入的字符数组为S1赋值
        printf("s1为");//提示
        printstring(S1);//输出S1
        printf(",长度为%d\n",lengthstring(&S1));//输出S1长度
        printf("s2为");//提示
        printstring(S2);//输出S2
        printf(",长度为%d\n",lengthstring(&S2));//输出S2长度
        if(comparestring(&S1,&S2)==0)//通过比较函数的返回值比较S1,S2是否相等
            printf("两者相等\n");//提示
        if(comparestring(&S1,&S2)==1)//通过比较函数的返回值比较S1,S2是否相等
            printf("s1大\n");//提示
        if(comparestring(&S1,&S2)==-1)//通过比较函数的返回值比较S1,S2是否相等
            printf("s2大\n");//提示
                                      //有关插入的一系列操作
        printf("请输入你想插入的位置\n");//提示
        scanf("%d",&postion);//输入位置
        insertstring(&S1,&S2,postion);//调用插入函数
                                    //有关连接的一系列操作
        constring(&S1,&S2);//调用连接函数
        printf("连接后的子串为");//提示
        printstring(S1);//输出S1
        printf(",长度为%d\n",lengthstring(&S1));//输出S1现在长度
                                   //有关截取子串的一系列操作
        printf("截取子串\n");//提示
        printf("请输入截取子串的位置\n");//提示
        scanf("%d",&postion);//输入要截取的起始位置
        printf("请输出字串长度\n");//提示
        scanf("%d",&length);//输入要截取的长度
        while(postion<0||length<0||postion+length-1>S1.length)//判断截取的子串是否合法
        {
            printf("无法插入请重新输入\n");//提示
            printf("请输入截取子串的位置\n");//提示
            scanf("%d",postion);//重新输入位置
            printf("请输出字串长度\n");//提示
            scanf("%d",length);//重新输入长度
        }
        findstring(&S2,S1,postion,length);//调用截取子串函数
        printf("该字串为");//提示
        printstring(S2);
                                   //有关子串删除的一系列操作
        printf("字串删除\n");//提示
        printf("首先,字串定位\n");//提示
        postion=searchsub(&S1,S2);//调用函数寻找第一个子串位置
        deletesub(&S1,S2,postion);//根据刚才的位置删除子串
        printf("现在s1为");//提示
        printstring(S1);//输出现在的S1
                                   //有关子串替换的一系列操作
        printf("把S1的子串替换为\n");//提示
        gets(ch);//输入要替换的数据
        insitstring(&sub);//初始化sub
        StrAssign(&sub,ch);//赋值
        printf("替换为\n");//提示
        printstring(sub);//打印子串
    
        repalcesub(&S1,S2,&sub);//调用替换子串函数
    
        return 0;
    }
    /*实验结果
    
    请输入S1
    ILIKECHINA
    请输入S2
    CHINA
    s1为ILIKECHINA
    ,长度为10
    s2为CHINA
    ,长度为5
    两个串的长度不一致无法比较
    两个串的长度不一致无法比较
    两个串的长度不一致无法比较
    请输入你想插入的位置
    4
    插入后的串为ILICHINAKECHINA
    连接后的子串为ILICHINAKECHINACHINA
    ,长度为20
    截取子串
    请输入截取子串的位置
    4
    请输出字串长度
    4
    该字串为CHIN
    字串删除
    首先,字串定位
    字串位于第4
    现在s1为ILIAKECHINACHINA
    把S1的子串替换为
    请重新输入
    abc
    替换为
    abc
    字串位于第7
    插入后的串为ILIAKEabcCHINACHINA
    现在s1为ILIAKEabcACHINA
    字串位于第11
    插入后的串为ILIAKEabcAabcCHINA
    现在s1为ILIAKEabcAabcA
    没有这个子串
    */
    
  • 相关阅读:
    现阶段学习窘境总结(2013年6月21日-至今)
    MvcPager 分页控件
    JS 实现PDF文件打印
    json和Jsonp 使用总结(1)
    实战篇之存储过程的使用
    ASP.NET MVC5 之 客户端实现文件的下载
    WMI 技术
    PowerDesigner 的使用教程
    Rose
    对路径 obj 文件夹访问被拒绝
  • 原文地址:https://www.cnblogs.com/ztguang/p/15731637.html
Copyright © 2011-2022 走看看