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

 更新时间:2020年4月25日 17:30  点击:1442

堆分配存储表示法

存储结构:

构建堆来存储字符串,本质上是顺序表

实现代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -2
#define STR_INIT_SIZE 100
#define STRINCREMENT 10
typedef int Status;
typedef struct
{
  char *ch; //空串时指向NULL,非空串时按串长分配存储区
  int length;
} HString;
Status InitString(HString *T) //初始化字符串
{
  //指针指向NULL,长度为0即可
  //p.s.申请内存空间的过程在赋值中完成
  T->ch = NULL;
  T->length = 0;
  return OK;
}
Status StrAssign(HString *T, char *p) //字符串赋值
{
  //1.判断T是否已有内容,有则释放
  //2.判断赋值的内容是否为空,为空则不赋值
  //3.根据长度向内存申请空间,遍历赋值给T,长度等于字符串长度
  //p.s.在这里赋值不赋\0,在打印时通过长度来判断字符串结尾
  int i, len = strlen(p);
  if (T->ch)
    free(T->ch);
  if (!len)
  {
    T->ch = NULL;
    T->length = 0;
    return ERROR;
  }
  else
  {
    T->ch = (char *)malloc(len * sizeof(char));
    if(!T->ch)
      exit(OVERFLOW);
    for (i = 0; i < len; ++i)
      T->ch[i] = p[i];
    T->length = len;
    return OK;
  }
}
Status StrPrint(HString T) //打印字符串
{
  //通过长度判断打印的字符数
  int i;
  for (i = 0; i < T.length; ++i)
    printf("%c", T.ch[i]);
  printf("\n");
}
Status StrLength(HString T) //字符串长度
{
  return T.length;
}
Status StrEmpty(HString T) //字符串判空
{
  if (T.length == 0)
    return TRUE;
  else
    return FALSE;
}
Status Concat(HString *T, HString S1, HString S2) //字符串联接
{
  //1.申请长度为S1和S2之和的字符串空间
  //2.先将S1的元素逐个赋值到T中
  //3.再将S2的元素逐个赋值到T中
  int i;
  if (T->ch)
    free(T->ch);
  T->ch = (char *)malloc((S1.length + S2.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[i + S1.length] = S2.ch[i];
  T->length = S1.length + S2.length;
  return OK;
}
Status StrDelete(HString *T, int pos, int len) //删除字符串中某个位置固定长度的子串
{
  //pos是字符串中的位置,删除包括pos的len长度
  int i;
  if (pos >= T->length)
    return ERROR;
  else if(pos + len > T->length)
    len = T->length - pos + 1;
  for (i = pos - 1; i < T->length - len; ++i)
    T->ch[i] = T->ch[i + len];
  T->length -= len;
  T->ch = (char *)realloc(T->ch, T->length * sizeof(char));
  if (!T->ch)
    exit(OVERFLOW);
  return OK;
}
Status StrInsert(HString *S, int pos, HString T)
{
  //pos是字符串中的位置,插入时原来的元素(包括pos位)后移
  int i, len;
  --pos;
  len = StrLength(T);
  S->ch = (char *)realloc(S->ch, (S->length + len) * sizeof(char));
  if (pos > S->length)
    pos = S->length;
  for (i = S->length - 1; i > pos - 1; --i)
    S->ch[i + len] = S->ch[i];
  for (i = 0; i < len; ++i)
    S->ch[i + pos] = T.ch[i];
  S->length += len;
  if (!S->ch)
    exit(OVERFLOW);
  return OK;
}
Status Index(HString S, HString T, int pos) //在字符串S中索引位置pos之后的子串t
{
  //同定长顺序存储表示法
  //p.s.传入的pos是字符串的位置,从1开始
  //p.s.初始状态下T为非空串
  if (StrEmpty(T))
    return ERROR;
  int i = pos - 1, j = 0;
  while(i < S.length && j < T.length)
  {
    if (S.ch[i] == T.ch[j])
    {
      ++i;
      ++j;
    }
    else
    {
      i = i - j + 1;
      j = 0;
    }
  }
  if (j >= T.length)
    return i - j + 1;
  else
    return 0;
}
Status Replace(HString *T, HString S1, HString S2) //将字符串T中等于S1的子串替换成为S2
{
  //循环索引子串S1在字符串T中的位置(每次的位置从上一次位置后开始查找)
  //从查找到的位置-1开始替换
  //p.s.初始状态下S1为非空串
  int pos = 0;
  if (StrEmpty(S1))
    return ERROR;
  //当pos存在时循环,当全部索引完毕后pos为0
  //将索引到的该位置对应的子串删除后再插入新的子串
  do
  {
    pos = Index(*T, S1, pos);
    if (pos)
    {
      StrDelete(T, pos, StrLength(S1));
      StrInsert(T, pos, S2);
    }
  }
  while(pos);
  return OK;
}
Status SubString(HString *Sub, HString S, int pos, int len)
{
  int i;
  if (pos < 1 || len > S.length || len < 0 || len > S.length - pos + 1)
    exit(OVERFLOW);
  if (Sub->ch)
    free(Sub->ch);
  //如果查询的长度为0,则子串置空
  if (len == 0)
  {
    Sub->ch = NULL;
    Sub->length = 0;
  }
  else
  {
    Sub->ch = (char *)malloc(len * sizeof(char));
    for (i = 0; i < len; ++i)
      Sub->ch[i] = S.ch[pos + i - 1];
    Sub->length = len;
  }
  return OK;
}
int main()
{
  int pos;
  HString t, s, r;
  char *p = "Hello,String!", *q = "Bye,Bye!";
  printf("String *p: %s\n", p);
  InitString(&t);
  StrAssign(&t, p);
  printf("StrAssign... OK.\nString t : ");
  StrPrint(t);
  printf("------------------------------\n");
  printf("StrLength... OK.\nString Length : %d\n", StrLength(t));
  printf("StrEmpty... OK.\n");
  if (StrEmpty(t))
    printf("String is Empty.\n");
  else
    printf("String is not Empty.\n");
  printf("------------------------------\n");
  InitString(&s);
  StrAssign(&s, q);
  printf("String s : ");
  StrPrint(s);
  printf("------------------------------\n");
  InitString(&r);
  Concat(&r, t, s);
  printf("Concat... OK.\n");
  printf("String r : ");
  StrPrint(r);
  printf("------------------------------\n");
  printf("StrDelete... OK.\n");
  StrDelete(&r, 14, 4);
  printf("String r : ");
  StrPrint(r);
  printf("------------------------------\n");
  printf("StrInsert... OK.\n");
  StrAssign(&t, "Bye,Bye,Bye!");
  StrInsert(&r, 14, t);
  printf("String r : ");
  StrPrint(r);
  printf("------------------------------\n");
  StrAssign(&t, "ye");
  printf("Index... ");
  StrPrint(t);
  pos = 1;
  while(pos)
  {
    pos = Index(r, t, pos + 1);
    if (!pos)
      break;
    printf("Position : %d\n", pos);
  }
  printf("------------------------------\n");
  StrAssign(&t, "ye");
  StrAssign(&s, "oo");
  Replace(&r, t, s);
  printf("Replace ye -> ooo ... OK.\n");
  printf("String r : ");
  StrPrint(r);
  printf("------------------------------\n");
  SubString(&t, r, 7, 4);
  printf("SubString... OK.\n");
  printf("String SubString : ");
  StrPrint(t);
  printf("------------------------------\n");
  return OK;
}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

[!--infotagslink--]

相关文章

  • C语言实现放烟花的程序

    这篇文章主要为大家详细介绍了C语言实现放烟花的程序,有音乐播放,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-23
  • C语言中的字符(char)详细讲解

    本篇文章主要介绍C语言中char的知识,并附有代码实例,以便大家在学习的时候更好的理解,有需要的可以看一下...2020-04-25
  • C#中截取字符串的的基本方法详解

    这篇文章主要介绍了C#中截取字符串的的基本方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-11-03
  • c#中判断字符串是不是数字或字母的方法

    这篇文章介绍了C#判断字符串是否数字或字母的实例,有需要的朋友可以参考一下...2020-06-25
  • PostgreSQL判断字符串是否包含目标字符串的多种方法

    这篇文章主要介绍了PostgreSQL判断字符串是否包含目标字符串的多种方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-02-23
  • 详解C++ string常用截取字符串方法

    这篇文章主要介绍了C++ string常用截取字符串方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-25
  • 详解如何将c语言文件打包成exe可执行程序

    这篇文章主要介绍了详解如何将c语言文件打包成exe可执行程序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-25
  • php字符串按照单词逐个进行反转的方法

    本文实例讲述了php字符串按照单词进行反转的方法。分享给大家供大家参考。具体分析如下:下面的php代码可以将字符串按照单词进行反转输出,实际上是现将字符串按照空格分隔到数组,然后对数组进行反转输出。...2015-03-15
  • MySQL 字符串拆分操作(含分隔符的字符串截取)

    这篇文章主要介绍了MySQL 字符串拆分操作(含分隔符的字符串截取),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-22
  • C#实现字符串转换成字节数组的简单实现方法

    这篇文章主要介绍了C#实现字符串转换成字节数组的简单实现方法,仅一行代码即可搞定,非常简单实用,需要的朋友可以参考下...2020-06-25
  • 使用list stream: 任意对象List拼接字符串

    这篇文章主要介绍了使用list stream:任意对象List拼接字符串操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-09
  • C# 16 进制字符串转 int的方法

    这篇文章主要介绍了C# 16 进制字符串转 int的方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下...2020-06-25
  • C#数据结构之队列(Quene)实例详解

    这篇文章主要介绍了C#数据结构之队列(Quene),结合实例形式较为详细的讲述了队列的功能、原理与C#实现队列的相关技巧,需要的朋友可以参考下...2020-06-25
  • 获取中文字符串的实际长度代码

    JS中默认中文字符长度和其它字符长度计算方法是一样的,但某些情况下我们需要获取中文字符串的实际长度,代码如下: 复制代码 代码如下: function strLength(str) { var realLength = 0, len = str.length, charCode = -1;...2014-06-07
  • PostgreSQL 字符串处理与日期处理操作

    这篇文章主要介绍了PostgreSQL 字符串处理与日期处理操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-01
  • C语言中free函数的使用详解

    free函数是释放之前某一次malloc函数申请的空间,而且只是释放空间,并不改变指针的值。下面我们就来详细探讨下...2020-04-25
  • C语言中计算正弦的相关函数总结

    这篇文章主要介绍了C语言中计算正弦的相关函数总结,包括正弦和双曲线正弦以及反正弦的函数,需要的朋友可以参考下...2020-04-25
  • 详解C语言中的rename()函数和remove()函数的使用方法

    这篇文章主要介绍了详解C语言中的rename()函数和remove()函数的使用方法,是C语言入门学习中的基础知识,需要的朋友可以参考下...2020-04-25
  • php 中英文混合字符串截取

    文章介绍一个实用的函数,我们如果用php substr来截取字符在中文上处理的很有问题,今天自己写了一个比较好的中文与英文字符截取的函数,有需要的朋友可以参考下。 ...2016-11-25
  • C语言中求和、计算平均值、方差和标准差的实例

    这篇文章主要介绍了C语言中求和、计算平均值、方差和标准差的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-12-10