串String(1):串的实现(定长顺序存储结构)
前言
PS:本文相关头文件、预编译以及typedef如下,阅读一遍以便于下面的理解:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSTRLEN 40
#define OK 1
#define ERROR 0
#define TURE 1
#define FALSE 0
#define OVERFLOW -2 typedef int Status;
typedef char SString[MAXSTRLEN+1];
ADT
串是一个重要的数据结构,我在这里实现串的ADT如下:


串的结构概念图

我定义了一个数组,0位存储字符长度,1到MAX位存储字符。这和传统的gets();函数或者 scanf(%s,);函数实现的串是有区别的,所以我封装了一个串赋值函数去实现两种串结构之间的转化,代码如下:
/* 字符串赋值,当赋值字符串长度超过被赋值字符串时候截断,未超过时先将长度存入T[0],再逐位赋值 */
Status StrAssign(SString T,char *chars)
{
int i;
if(strlen(chars)>MAXSTRLEN)
{
for(i = 1;i <= MAXSTRLEN;i++)
{
T[i] = *(chars + i - 1);
}
T[0] = MAXSTRLEN; //T[0]存入int 型数据,%s无法打印
}
else
{
T[0] = strlen(chars); //T[0]存入的是chars的字符长度
for(i = 1;i <= strlen(chars);i++)
{
T[i] = *(chars + i - 1);
}
}
return OK;
}
功能函数算法难点
我认为其中的StrIndex();索引子串函数是相对难理解一些的。其函数功能是:索引子串,返回串T中第一个索引到与串S相同的子串的位置。算法思路图如下:

尤其要注意,当T[i] != S[j]时,需要将i指针置于上次相同时的下一个位置,代码实现为 i = i - j + 2,而不是i++
该模块函数封装代码如下:
/* 索引子串,返回串T中第一个索引到与串S相同的子串的位置 */
Status StrIndex(SString T,SString S,int *pos)
{
int i=1,j=1;
while((i <= T[0]) && (j <= S[0]))
{
if(T[i] == S[j])
{
i++;
j++;
}
else
{
i = i - j + 2;
j = 1;
}
}
if(j > S[0])
{
*pos = i - j + 1;
printf("Found,position is %d\n",*pos);
return OK;
}
else
{
printf("NOT find child string yet.\n");
return ERROR;
}
}
其次,StrInsert();插入函数中也比较难想,因为其需要讨论插入位置以及插入后长度是否越界问题,设计算法时易漏了其中某一个情况。
该模块函数封装代码如下:
/* 在串T的第pos个位置后插入子串S */
Status StrInsert(SString T,SString S,int pos)
{
int i;
if(pos > T[0])
{
pos = T[0] +1;
}
if(T[0] + S[0] <= MAXSTRLEN)
{
for(i = 1; i <= pos;i++)
T[T[0] + S[0] - i +1] = T[T[0] + S[0] - i -pos];
for(i = 1;i <= S[0];i++)
T[pos + i] = S[i];
T[0] = T[0] + S[0];
return OK;
}
if(T[0] + S[0] > MAXSTRLEN)
{
for(i = 1;i <= (MAXSTRLEN - pos);i++)
T[i + pos] = S[i]; //超出部分被删除
T[0] = MAXSTRLEN;
return ERROR;
}
}
代码
/*************************************************************************
> File Name: String fuctions
> Author: Bw98
> Mail: 786016746@qq.com
> Blog: www.cnblogs.com/Bw98blogs/
> Created Time: SUN 23th Jul. 2017
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSTRLEN 40
#define OK 1
#define ERROR 0
#define TURE 1
#define FALSE 0
#define OVERFLOW -2 typedef int Status;
typedef char SString[MAXSTRLEN+1]; Status StrEmpty(SString S);
Status StrAssign(SString T,char *chars);
Status StrCopy(SString T,SString S);
Status StrLength(SString T);
Status StrPrint(SString T);
Status StrClear(SString S);
Status StrConcat(SString T,SString S1,SString S2);
Status StrIndex(SString T,SString S,int *pos);
Status StrInsert(SString T,SString S,int pos);
Status StrDelete(SString T,int pos,int len); int main()
{
/* 根据功能自行调用 */
return 0;
} /* 字符串赋值,当赋值字符串长度超过被赋值字符串时候截断,未超过时先将长度存入T[0],再逐位赋值 */
Status StrAssign(SString T,char *chars)
{
int i;
if(strlen(chars)>MAXSTRLEN)
{
for(i = 1;i <= MAXSTRLEN;i++)
{
T[i] = *(chars + i - 1);
}
T[0] = MAXSTRLEN; //T[0]存入int 型数据,%s无法打印
}
else
{
T[0] = strlen(chars); //T[0]存入的是chars的字符长度
for(i = 1;i <= strlen(chars);i++)
{
T[i] = *(chars + i - 1);
}
}
return OK;
} /* 字符串拷贝,逐个字符拷贝(仅拷贝长度范围内的) */
Status StrCopy(SString T,SString S)
{
int i;
for(i = 1;i <= S[0];i++)
{
T[i] = S[i];
}
T[0] = S[0];
return OK;
} /* 字符串判空,S[0] == 0时为空 */
Status StrEmpty(SString T)
{
if(T[0] == 0)
{
printf("The string is empty!\n");
return TURE;
}
else
{
printf("The string is NOT empty!\n");
return FALSE;
}
} /* 返回该字符串的长度 */
Status StrLength(SString T)
{
return T[0];
} /* 打印字符串 */
Status StrPrint(SString T)
{
int i;
for(i = 1;i <= T[0];i++)
printf("%c",T[i]);
printf("\n");
return OK;
}
/* 清除字符串,即长度清空 */
Status StrClear(SString S)
{
S[0] = 0;
return OK;
} /* 字符串联接,通过T来存储结果,S2连接而成的新串,若未截断则返回TRUE,截断返回FAlSE,注意字符串数组越界问题 */
Status StrConcat(SString T,SString S1,SString S2)
{
int i;
if(S1[0]+S2[0] <= MAXSTRLEN)
{
for(i = 1;i <= S1[0];i++)
{
T[i] = S1[i];
}
for(i = 1;i <= S2[0];i++)
{
T[S1[0]+i] = S2[i];
}
T[0] = S1[0] + S2[0];
return TURE;
}
else
{
for(i = 1;i <= S1[0];i++)
{
T[i] = S1[i];
}
for(i = 1;i <= (MAXSTRLEN-S1[0]);i++)
{
T[S1[0]+i] = S2[i];
}
T[0] = MAXSTRLEN;
return FALSE;
}
} /* 索引子串,返回串T中第一个索引到与串S相同的子串的位置 */
Status StrIndex(SString T,SString S,int *pos)
{
int i=1,j=1;
while((i <= T[0]) && (j <= S[0]))
{
if(T[i] == S[j])
{
i++;
j++;
}
else
{
i = i - j + 2;
j = 1;
}
}
if(j > S[0])
{
*pos = i - j + 1;
printf("Found,position is %d\n",*pos);
return OK;
}
else
{
printf("NOT find child string yet.\n");
return ERROR;
}
} /* 在串T的第pos个位置后插入子串S */
Status StrInsert(SString T,SString S,int pos)
{
int i;
if(pos > T[0])
{
pos = T[0] +1;
}
if(T[0] + S[0] <= MAXSTRLEN)
{
for(i = 1; i <= pos;i++)
T[T[0] + S[0] - i +1] = T[T[0] + S[0] - i -pos];
for(i = 1;i <= S[0];i++)
T[pos + i] = S[i];
T[0] = T[0] + S[0];
return OK;
}
if(T[0] + S[0] > MAXSTRLEN)
{
for(i = 1;i <= (MAXSTRLEN - pos);i++)
T[i + pos] = S[i]; //超出部分被删除
T[0] = MAXSTRLEN;
return ERROR;
}
} /* 删除串T的第pos个位置起,长为len的子串 */
Status StrDelete(SString T,int pos,int len)
{
int i;
if(pos > T[0])
return ERROR;
if(len > T[0])
len = T[0] - pos + 1;
for(i = len + pos;i <= T[0];i++)
T[i - len] =T[i];
T[0] = T[0] - len;
return OK;
}
串String(1):串的实现(定长顺序存储结构)的更多相关文章
- javascript实现数据结构:串--定长顺序存储表示以及kmp算法实现
串(string)(或字符串)是由零个或多个字符组成的有限序列.串中字符的数目称为串的长度.零个字符的串称为空串(null string),它的长度为零. 串中任意个连续的字符组成的子序列称为该串的子 ...
- 生成定长随机数-可做3des密钥
3DES加解密需要密钥支持,要求为8的倍数,一般会使用32位的字母数字随机字符串作为密钥. 下面这个工具类,可用做key值的生成,详见下方代码: package test; import java.u ...
- Delphi String 常用字串符处理函数
Delphi 在面对跨平台开发,程序语言也改进不少,不过有些改进,让原本 Delphi 开发者有些不适应,最显注的就是字串处理函数了,原本 Pascal 语言字串起始由 1 开始,几乎是它的经典了,新 ...
- 串string (KMP)
1.Definition 串string,是零个或多个字符组成的有限序列.一般记作S="a1a2a3...an",其中S是串名,双引号括起来的字符序列是串值:ai(1<= i ...
- Day07 - Ruby比一比:Symbol符号与String字串
前情提要: 第六天我们透过Ruby代码练习public,protected和privatemethod时,发现冒号在前面的参数,:mydraft,:myspace,这些就是符号Symbol.在今天,我 ...
- LeetCode Reverse Words in a String 将串中的字翻转
class Solution { public: void reverseWords(string &s) { string end="",tem="" ...
- hdu5384 AC自己主动机模板题,统计模式串在给定串中出现的个数
http://acm.hdu.edu.cn/showproblem.php?pid=5384 Problem Description Danganronpa is a video game franc ...
- HDU - 2222,HDU - 2896,HDU - 3065,ZOJ - 3430 AC自动机求文本串和模式串信息(模板题)
最近正在学AC自动机,按照惯例需要刷一套kuangbin的AC自动机专题巩固 在网上看过很多模板,感觉kuangbin大神的模板最为简洁,于是就选择了用kuangbin大神的模板. AC自动机其实就是 ...
- Java随机生成定长纯数字或数字字母混合数
(转)Java随机生成定长纯数字或数字字母混合数 运行效果图: 具体实现代码
随机推荐
- TIJ学习总结(1)- Java基础语法
TIJ(Thinking in Java)作为Java学习书籍里的"圣经",之前花两个月系统的捋了一遍,很多东西有种豁然开朗的感觉,入门之后读一遍TIJ,相信会有很多意外收获哦- ...
- 获取request header的值
1Sring mvc 中可以通过注解 : @RequestHeader ("host") String hostName 2httpservletrequest request ...
- C#设计模式之十七观察者模式(Observer Pattern)【行为型】
一.引言 今天是2017年11月份的最后一天,也就是2017年11月30日,利用今天再写一个模式,争取下个月(也就是12月份)把所有的模式写完,2018年,新的一年写一些新的东西.今天我们开始讲& ...
- 基于 HTML5 Canvas 的简易 2D 3D 编辑器
不管在任何领域,只要能让非程序员能通过拖拽来实现 2D 和 3D 的设计图就是很牛的,今天我们不需要 3dMaxs 等设计软件,直接用 HT 就能自己写出一个 2D 3D 编辑器,实现这个功能我觉得成 ...
- DNS单机部署以及智能dns部署
dns理论 dns的出现 网络出现的早期是使用IP地址通讯的,那时就几台主机通讯.但是随着接入网络主机的增多,这种数字标识的地址非常不便于记忆,UNIX上就出现了建立一个叫做hosts的文件(Linu ...
- NodeJS网络爬虫
原文地址:NodeJS网络爬虫 网上有很多其他语言平台版本的网络爬虫,比如Python,Java.那怎么能少得了我们无所不能的javascript呢
- Cannot load browser "PhantomJS": it is not registered! Perhaps you are missing some plugin? 测试安装遇到的BUG
安装了半天phantomjs就是安装不好,后面想了个死办法,http://phantomjs.org/download.html这个网址下先去下载好 phantomjs-2.1.1-windows.z ...
- 用python 抓取B站视频评论,制作词云
python 作为爬虫利器,与其有很多强大的第三方库是分不开的,今天说的爬取B站的视频评论,其实重点在分析得到的评论化作嵌套的字典,在其中取出想要的内容.层层嵌套,眼花缭乱,分析时应细致!步骤分为以下 ...
- 如何在仅主机模式下ping通网路上网
1 主机的控制面板,找到电脑的实际网卡,勾选,并选择VMware Network Adapter VMnet1 找到虚拟网卡VMware Virtual Ethernet Adapter for VM ...
- 获取或设置当前窗口contextmenu事件的事件处理函数
在浏览器中 鼠标右键点击会显示默认的 自带的菜单,那么如何禁止 和更改呢? 1) 禁止右键 window.oncontextmenu = funcRef; //funcRef是个函数引用 列子: w ...