_DataStructure_C_Impl:链串
//_DataStructure_C_Impl:链串
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define ChunkSize 4
#define stuff '#'
//串的结点类型定义
typedef struct Chunk{
char ch[ChunkSize];
struct Chunk *next;
}Chunk;
//链串的类型定义
typedef struct{
Chunk *head;
Chunk *tail;
int length;
}LinkString;
//初始化字符串S
void InitString(LinkString *S){
S->length=0; //将串的长度置为0
S->head=S->tail=NULL; //将串的头指针和尾指针置为空
}
//生成一个其值等于cstr的串S。 成功返回1,否则返回0
int StrAssign(LinkString *S,char *cstr){
int i,j,k,len;
Chunk *p,*q;
len=strlen(cstr); //len为链串的长度
if(!len)
return 0;
S->length=len;
j=len/ChunkSize; //j为链串的结点数
if(len%ChunkSize)
j++;
for(i=0;i<j;i++){
p=(Chunk *)malloc(sizeof(Chunk)); //动态生成一个结点
if(!p)
return 0;
for(k=0;k<ChunkSize&&*cstr;k++)
*(p->ch+k)=*cstr++; //将字符串ctrs中的字符赋值给链串的数据域
if(i==0) //假设是第一个结点
S->head=q=p; //头指针指向第一个结点
else{
q->next=p;
q=p;
}
if(!*cstr){ //假设是最后一个链结点
S->tail=q; //将尾指针指向最后一个结点
q->next=NULL; //将尾指针的指针域置为空
for(;k<ChunkSize;k++)
*(q->ch+k)=stuff; //将最后一个结点用'#'填充
}
}
return 1;
}
//推断串是否为空。假设S为空串,则返回1,否则返回0
int StrEmpty(LinkString S){
if(S.length==0)
return 1;
else
return 0;
}
//求串的长度
int StrLength(LinkString S){
return S.length;
}
//串的转换操作。将串S的内容转换为字符串,将串S中的字符复制到cstr。成功返回1,否则返回0
int ToChars(LinkString S,char **cstr){
Chunk *p=S.head; //将p指向串S中的第1个结点
int i;
char *q;
*cstr=(char *)malloc((S.length+1)*sizeof(char));
if(!cstr||!S.length)
return 0;
q=*cstr; //将q指向cstr
while(p){ //块链没结束
for(i=0;i<ChunkSize;i++)
if(p->ch[i]!=stuff) //假设当前字符不是填充的特殊字符'#'。则将S中字符赋值给q
*q++=(p->ch[i]);
p=p->next;
}
(*cstr)[S.length]='\0'; //在字符串的末尾加入结束标志
return 1;
}
//串的复制操作
int StrCopy(LinkString *T,LinkString S){
char *str;
int flag;
if(!ToChars(S,&str)) //将串S中的字符复制到字符串str中
return 0;
flag=StrAssign(T,str); //将字符串str的字符赋值到串T中
free(str); //释放str的空间
return flag;
}
//串的比較操作。若S的值大于T。则返回正值。若S的值等于T,则返回0。若S的值小于T,则返回负值
int StrCompare(LinkString S,LinkString T){
char *p,*q;
int flag;
if(!ToChars(S,&p)) //将串S转换为字符串p
return 0;
if(!ToChars(T,&q)) //将串T转换为字符串q
return 0;
for(;*p!='\0'&&*q!='\0';)
if(*p==*q){
p++;
q++;
}else{
flag=*p-*q;
free(p); //释放p的空间
free(q); //释放q的空间
return flag;
}
if(*p=='\0'||*q=='\0'){
free(p);
free(q);
return S.length-T.length;
}
}
//串的链接操作。将串S连接在串T的尾部
int StrConcat(LinkString *T,LinkString S){
int flag1,flag2;
LinkString S1,S2;
InitString(&S1);
InitString(&S2);
flag1=StrCopy(&S1,*T); //将串T的内容复制到S1中
flag2=StrCopy(&S2,S); //将串S的内容复制到S2中
if(flag1==0||flag2==0) //假设有一个串拷贝不成功,则返回0
return 0;
T->head=S1.head; //改动串T的头指针
S1.tail->next=S2.head; //将串S1和S2首尾相连
T->tail=S2.tail; //改动串T的尾指针
T->length=S.length+T->length; //改动串T的长度
return 1;
}
//串的插入操作。 在串S的第pos个位置插入串T
int StrInsert(LinkString *S,int pos,LinkString T){
char *t1,*s1;
int i,j;
int flag;
if(pos<1||pos>S->length+1)
return 0;
if(!ToChars(*S,&s1)) //将串S转换为字符串s1
return 0;
if(!ToChars(T,&t1)) //将串T转换为字符串t1
return 0;
j=strlen(s1); //j为字符串s1的长度
s1=(char *)realloc(s1,(j+strlen(t1)+1)*sizeof(char)); //为s1又一次分配空间
for(i=j;i>=pos-1;i--) //将字符串s1中的第pos以后的字符向后移动strlen(t1)个位置
s1[i+strlen(t1)]=s1[i];
for(i=0;i<(int)strlen(t1);i++) //在字符串s1中插入t1
s1[pos+i-1]=t1[i];
InitString(S);
flag=StrAssign(S,s1); //由s1生成串S
free(t1);
free(s1);
return flag;
}
//串的删除操作。 将串S中的第pos个字符起长度为len的子串删除
int StrDelete(LinkString *S,int pos,int len){
char *str;
int i;
int flag;
if(pos<1||pos>S->length-len+1||len<0)
return 0;
if(!ToChars(*S,&str)) //将串S转换为字符串str
return 0;
for(i=pos+len-1;i<=(int)strlen(str);i++) //将字符串中第pos个字符起的长度为len的子串删除
str[i-len]=str[i];
InitString(S); //释放S的原有存储空间
flag=StrAssign(S,str); //将字符串str转换为串S
free(str);
return flag;
}
//取子串操作。 用Sub返回串S的第pos个字符起长度为len的子串
int SubString(LinkString *Sub,LinkString S,int pos,int len){
char *t,*str;
int flag;
if(pos<1||pos>S.length||len<0||len>S.length-pos+1)
return 0;
if(!ToChars(S,&str)) //将串S转换为字符串str
return 0;
t=str+pos-1; //t指向字符串str中的pos个字符
t[len]='\0'; //将Sub结束处置为'\0'
flag=StrAssign(Sub,t); //将字符串t转换为Sub
free(str);
return flag;
}
//清空串操作。将串的空间释放
void ClearString(LinkString *S){
Chunk *p,*q;
p=S->head;
while(p){
q=p->next;
free(p);
p=q;
}
S->head=S->tail=NULL;
S->length=0;
}
//链串的输出
void StrPrint(LinkString S){
int i=0,j;
Chunk *h;
h=S.head;
while(i<S.length){
for(j=0;j<ChunkSize;j++)
if(*(h->ch+j)!=stuff){
printf("%c",*(h->ch+j));
i++;
}
h=h->next;
}
printf("\n");
}
void main(){
int i,j;
int flag;
LinkString S1,S2,S3,Sub;
char *str1="Welcome to";
char *str2=" Data Structure";
char *str3="Computer Architecture";
printf("串的初始化和赋值操作:\n");
InitString(&S1); /*串S1,S2。S3的初始化*/
InitString(&S2);
InitString(&S3);
InitString(&Sub);
StrAssign(&S1,str1); /*串S1。S2,S3的赋值操作*/
StrAssign(&S2,str2);
StrAssign(&S3,str3);
printf("串S1的值是:");
StrPrint(S1);
printf("串S2的值是:");
StrPrint(S2);
printf("串S3的值是:");
StrPrint(S3);
printf("%d\n",StrCompare(S1,S2));
printf("将串S2连接在串S1的末尾:\n");
StrConcat(&S1,S2); /*将串S2连接在串S1的末尾*/
printf("S1是:");
StrPrint(S1);
printf("将串S1的第12个位置后的14个字符删除:\n");
StrDelete(&S1,12,14); /*将串S1中的第12个位置后的14个字符删除*/
printf("S1是:");
StrPrint(S1);
printf("将串S3插入到串S1中的第12个字符后:\n");
StrInsert(&S1,12,S3); /*将串S3插入到串S1的第12个字符后*/
printf("S1是:");
StrPrint(S1);
printf("将串S1中的第12个字符后的8个字符取出并赋值给串Sub:\n");
SubString(&Sub,S1,12,8); /*将串S1中的第12个位置后的8个字符取出赋值给Sub*/
printf("Sub是:");
StrPrint(Sub);
system("pause");
}
_DataStructure_C_Impl:链串的更多相关文章
- YTU 3008: 链串的基本运算
3008: 链串的基本运算 时间限制: 1 Sec 内存限制: 128 MB 提交: 1 解决: 1 题目描述 编写一个程序,实现链串的各种基本运算,主函数已给出,请补充每一种方法. 1.建立串s ...
- 数据结构(c语言第2版)-----了解链表,栈,队列,串
关于链表我觉得这都是最基本的东西,但是不常见,在实际的应用中很少的使用,了解它会用就OK,不需要研究的那么深,除非做那种内存压缩,存储方面工作. C语言中动态申请空间 malloc() q=(dlin ...
- JavaScript责任链模式
介绍 责任链模式(Chain of responsibility)是使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理 ...
- 【数据结构(C语言版)系列四】 串
串类型的定义 串(或字符串)是由零个或多个字符组成的有限序列,一般记为 s = 'a1a2...an',s为串名.子串在主串中的位置以子串的第一个字符在主串中的位置来表示. 串和表示和实现——定长顺序 ...
- RxJava如何结合观察者与链式处理
RxJava如何结合观察者与链式处理 Author: Dorae Date: 2018年12月3日17:10:31 转载请注明出处 一.概述 首先问自己几个问题,如果非常清楚这几个问题的目的与答案,那 ...
- nginx应用总结(1)--基础认识和应用配置
在linux系统下使用nginx作为web应用服务,用来提升网站访问速度的经验已五年多了,今天在此对nginx的使用做一简单总结. 一.nginx服务简介Nginx是一个高性能的HTTP和反向代理服务 ...
- nginx常用命令
ps -ef | grep nginx在进程列表里面找master进程,它的编号就是主进程号了. 步骤2:发送信号 从容停止Nginx: kill -QUIT 主进程号 快速停止Nginx: kill ...
- HDU 2609 最小表示法
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2609 题意:给定n个循环链[串],问有多少个本质不同的链[串](如果一个循环链可以通过找一个起点使得和 ...
- nginx全局变量实例对照 rewrite参考手册
http://dwz.stamhe.com/index.php?_a=index&_m=show&count=10 remote_addr 客户端ip,如:192.168.4.2 bi ...
随机推荐
- [Luogu 1850] noip16 换教室
[Luogu 1850] noip16 换教室 好久没有更博客了,先唠嗑一会,花了两天的空闲时间大致做完了昨年的noip真题 虽然在经过思考大部分题目都可出解(天天爱跑步除外),但是并不知道考试时候造 ...
- fontSpider字蛛,好用的字体压缩工具教程
一直觉得很多字体特别好看,但是那些好看的字体只能做在图片上不能用CSS样式去实现,作为一个会设计的前端,真心觉得很烦恼,有时候那些文字需要更换,修改起来非常麻烦,要到处去找源文件,找不到源文件还要尽力 ...
- Spring Boot (16) logback和access日志
Spring Boot 内部采用的是Commons Logging进行日志记录,但是在底层为Java Util Logging.Log4J2.Logback等日志框架提供了默认配置. logback ...
- 使用OpenCV画折线图
使用OpenCV画直方图是一件轻松的事情,画折线图就没有那么Easy了,还是使用一个库吧: GraphUtils 源代码添加入工程 原文链接:http://www.360doc.com/content ...
- 微信小程序,时间戳和日期格式互相转化
微信小程序,时间戳转为日期格式 通常后台传递过来的都是时间戳,但是前台展示不能展示时间戳.就需要转化了. 功能说明: 微信小程序里,时间戳转化为日期格式,支持自定义. 拷贝至项目utils/utils ...
- PAT_A1141#PAT Ranking of Institutions
Source: PAT A1141 PAT Ranking of Institutions (25 分) Description: After each PAT, the PAT Center wil ...
- 三种办法来安装Python3.x
Centos7默认自带了Python2.7版本,但是因为项目需要使用Python3.x你可以按照此文的三个方法进行安装. 注:本文示例安装版本为Python3.5, 一.Python源代码编译安装 安 ...
- python 疑难杂症
1.getpass模块 :Pycharm不支持getpass模块,使用terminal可运行,但是getpass中文提示显示乱码?
- /proc/sys/vm man手册
Manual page proc(5) line 1967 (press h for help or q to quit) /proc/sys/vm This directory contains f ...
- Vue学习之路第二十篇:Vue生命周期函数-组件创建期间的4个钩子函数
1.每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听.编译模板.将实例挂载到 DOM 并在数据变化时更新 DOM 等.同时在这个过程中也会运行一些叫做生命周期钩子的函数 ...