定长顺序结构的实现

一、定长顺序结构的概述

定长顺序结构 是类似于线性表的顺序存储结构,使用一组连续的存储单元存储串值的字符序列。

二、串的定长顺序存储表示

# define MAXSTRLEN 40//用户可以在255以内定义最大串长
typedef unsigned char SString[MAXSTRLEN + 1];//0号单元存放串的长度

串的实际长度可在这个预定义长度范围内随意,超出预定义长度的串则会被舍去,这称之为“截断”。

三、串的两种表示方法

1、0号单元存放串的长度

如上述定义的那样,一下标为0的数组分量存放串的实际长度。

2、串值后加"\0"

即在串值后加入一个不计入串长的结束标记字符。此时串长是一个隐含值,不变域操作。

四、串的操作

//1、生成一个其值等于chars的字符串T
bool StrAssign(SString T, char *chars);
//2、由串T复制得串S
void StrCopy(SString S, SString T);
//3、若S为空串,则返回true,否则返回false
bool StrEmpty(SString S);
//4、字符串长短比较,返回S长度-T长度
int StrCompare(SString S, SString T);
//5、返回串S的元素个数
int StrLength(SString S);
//6、显示串的值
void Strshow(SString S);
//7、串的拼接 S1后接S2,结果在T中。
bool StrConcat1(SString T, SString S1, SString S2);
//8、串的拼接 S1后接S2,结果放在S1中
bool StrConcat2(SString S1, SString S2);
//9、用Sub返回串S的第pos个字符起(包括pos位置处的字符)长度为len的子串。
bool SubString(SString Sub, SString S, int pos, int len);
//10、清空串
void ClearString(SString S);
//11、 返回子串T在主串S中的位置。若不存在,则函数值为0,其中,T非空。
int Index1(SString S, SString T);
//12、 返回子串T在主串S中第pos个字符之后的位置。若不存在,则函数值为0,其中,T非空,1≤pos≤StrLength(S)。
int Index2(SString S, SString T, int pos);
//13、在串S的第pos个字符之前插入串T。完全插入返回true,部分插入返回false
bool StrInsert(SString S, int pos, SString T);
//14、从串S中删除第pos个字符起长度为len的子串
bool StrDelete(SString S, int pos, int len);

五、串操作的实现

1、生成一个其值等于chars的字符串T

bool StrAssign(SString T, char *chars)
{int i;if (strlen(chars) > MAX_STR_LEN)//chars 的长度大于最大长度,返回falsereturn false;else{T[0] = strlen(chars); // 0号单元存放串的长度for (i = 1; i <= T[0]; i++)//从1号单元开始复制串的内容{T[i] = *(chars + i - 1);//等价于T[i] = chars[i-1];    }return true;}
}

2、由串S复制得串T

void StrCopy(SString T, SString S)
{ int i;for (i = 0; i <= S[0]; i++)T[i] = S[i];
}

3、若S为空串,则返回true,否则返回false

//3、若S为空串,则返回true,否则返回false
bool StrEmpty(SString S)
{if (S[0] == 0)return true;elsereturn false;
}

4、字符串长短比较,返回S长度-T长度

int StrCompare(SString S, SString T)
{// 初始条件:串S和T存在。//操作结果:若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0int i;for (i = 1; i <= S[0] && i <= T[0]; ++i)if (S[i] != T[i])return S[i] - T[i];return S[0] - T[0];
}

5、返回串S的元素个数

int StrLength(SString S)
{ return S[0];
}

6、显示串的值

void Strshow(SString S)
{int i;for (i = 1; i <= S[0]; i++)//从1号单元开始逐单元输出串中的字符{printf("  %c", S[i]);}printf("\n");
}

7、串的拼接 S1后接S2,结果放在T中

当S1和S2的长度加在一起超出MAX_STR_LEN时,S2会被截断

bool StrConcat1(SString T, SString S1, SString S2)
{ // 用T返回S1和S2联接而成的新串。若未截断,则返回true,否则falseint i;if (S1[0] + S2[0] <= MAX_STR_LEN){ // 未截断for (i = 1; i <= S1[0]; i++)//先放S[1]到T中T[i] = S1[i];for (i = 1; i <= S2[0]; i++)//接着放S[2]到T中T[S1[0] + i] = S2[i];T[0] = S1[0] + S2[0];return true;}else{ // 截断S2for (i = 1; i <= S1[0]; i++)//先放S[1]到T中T[i] = S1[i];for (i = 1; i <= MAX_STR_LEN - S1[0]; i++)//关键,若第一个串长度超过MAX_STR_LEN 则条件不成立,这里循环的次数为,S1剩余空间单位数T[S1[0] + i] = S2[i];T[0] = MAX_STR_LEN;return false;}
}

8、串的拼接 S1后接S2,结果放在S1中

bool StrConcat2(SString S1, SString S2)
{ // 用T返回S1和S2联接而成的新串。若未截断,则返回true,否则falseint i = 1;int lens1 = S1[0];//保存S1的长度while (i <= (MAX_STR_LEN - S1[0]) && i<= S2[0])//i小于等于除去S1长度剩余的长度&&i小于S2的长度{S1[S1[0] + i] = S2[i];//逐字符赋值i++;}S1[0] = S1[0] + i - 1;//更新S1长度if ((lens1 + S2[0]) <= MAX_STR_LEN)//判断有没有截断return true;elsereturn false;
}

9、用Sub返回串S的第pos个字符起(包括pos位置处的字符)长度为len的子串。

bool SubString(SString Sub, SString S, int pos, int len)
{ int i;if (pos<1 || pos>S[0] || len<0 || len>S[0] - pos + 1)//排除pos值不在S长度范围内的值和len值+pos值超出S长度return false;for (i = 1; i <= len; i++)Sub[i] = S[pos + i - 1];//包括pos位置处的字符Sub[0] = len;return true;
}

10、清空串

void ClearString(SString S)
{ // 初始条件:串S存在。//操作结果:将S清为空串S[0] = 0; // 令串长为零
}

11、 返回子串T在主串S中的位置。若不存在,则函数值为0,其中,T非空

int Index1(SString S, SString T)
{int i = 1, j = 1;for ( i = 1; i <=S[0]; i++)//循环主串{if (S[i]==T[1])//如果在主串中找到一个与子串的第一个字符相等的字符时{int cont = 1;//计数变量for ( j = 1; j <=T[0]; j++)//遍历子串{if (T[j + 1] != S[i + j])//在遍历T[0]时如果有不一致时退出遍历{ break;}else//否则计数{cont++;if (cont == T[0])//当有T[0]个字符相同时则找到子串位置return i;}                                 }           }continue;  }return 0;//不存在时
}

12、 返回子串T在主串S中第pos个字符之后的位置。若不存在,则函数值为0,其中,T非空,1≤pos≤StrLength(S)。

int Index2(SString S, SString T, int pos)
{ int i, j;if (1 <= pos && pos <= S[0]){i = pos;//从主串的第pos个字符开始和子串的第一个字符比较j = 1;while (i <= S[0] && j <= T[0]){ if (S[i] == T[j]) // 若第一个字符比较后相等则继续比较后继字符{++i;++j;}else //若第一个字符不叫后不相等则后移一个位置重新开始匹配{i = i - j + 2;j = 1;}}if (j > T[0])//条件成立表示子串中的所有字符都能匹配相等,即主串中包含子串return i - T[0];elsereturn 0;}elsereturn 0;
}

13、在串S的第pos个字符之前插入串T。完全插入返回true,部分插入返回false

bool StrInsert(SString S, int pos, SString T)
{ // 初始条件:串S和T存在,1≤pos≤StrLength(S)+1// 操作结果:在串S的第pos个字符之前插入串T,第pos个位置插入T[1]。完全插入返回true,部分插入返回falseint i;if (pos<1 || pos>S[0] + 1)//插入位置不在S长度范围之内return false;if (S[0] + T[0] <= MAX_STR_LEN){ // 完全插入for (i = S[0]; i >= pos; i--)//pos之后的元素后移T[0]个长度S[i + T[0]] = S[i];for (i = pos; i < pos + T[0]; i++)//插入S[i] = T[i - pos + 1];S[0] += T[0];//更新长度return true;}else{ // 部分插入for (i = MAX_STR_LEN; i >= pos + T[0]; i--)//移动串S中位于pos之后仍在串内的字符,因为(S[0] + T[0] > MAX_STR_LEN)所S串插入T后必满, pos + T[0]是插入元素和pos及pos之前元素所占位置S[i] = S[i - T[0]];for (i = pos; i < pos + T[0] && i <= MAX_STR_LEN; i++)S[i] = T[i - pos + 1];S[0] = MAX_STR_LEN;//S的长度为最大return false;//部分插入}
}

14、从串S中删除第pos个字符起长度为len的子串

bool StrDelete(SString S, int pos, int len)
{ // 初始条件:串S存在,1≤pos≤StrLength(S)-len+1// 操作结果:从串S中删除第pos个字符起长度为len的子串int i;if (pos<1 || pos>S[0] - len + 1 || len < 0)//pos和len的值超出范围return false;for (i = pos + len; i <= S[0]; i++)//循环删除子串后的所有字符S[i - len] = S[i];//向前移动len个位置S[0] -= len;//更新串S的长度return  true;
}

最后给出完整代码

// 串的定长顺序存储结构.cpp
#include<string.h>
#include<malloc.h> // malloc()等
#include<stdio.h> // EOF(=^Z或F6),NULL
#include<stdlib.h> // atoi()#define MAX_STR_LEN 40 // 用户可在255(1个字节)以内定义最大串长
typedef char SString[MAX_STR_LEN + 1]; // 0号单元存放串的长度// SString是数组,故不需引用类型//1、生成一个其值等于chars的字符串T
bool StrAssign(SString T, char *chars);
//2、由串T复制得串S
void StrCopy(SString S, SString T);
//3、若S为空串,则返回true,否则返回false
bool StrEmpty(SString S);
//4、字符串长短比较,返回S长度-T长度
int StrCompare(SString S, SString T);
//5、返回串S的元素个数
int StrLength(SString S);
//6、显示串的值
void Strshow(SString S);
//7、串的拼接 S1后接S2,结果在T中。
bool StrConcat1(SString T, SString S1, SString S2);
//8、串的拼接 S1后接S2,结果放在S1中
bool StrConcat2(SString S1, SString S2);
//9、用Sub返回串S的第pos个字符起(包括pos位置处的字符)长度为len的子串。
bool SubString(SString Sub, SString S, int pos, int len);
//10、清空串
void ClearString(SString S);
//11、 返回子串T在主串S中的位置。若不存在,则函数值为0,其中,T非空。
int Index1(SString S, SString T);
//12、 返回子串T在主串S中第pos个字符之后的位置。若不存在,则函数值为0,其中,T非空,1≤pos≤StrLength(S)。
int Index2(SString S, SString T, int pos);
//13、在串S的第pos个字符之前插入串T。完全插入返回true,部分插入返回false
bool StrInsert(SString S, int pos, SString T);
//14、从串S中删除第pos个字符起长度为len的子串
bool StrDelete(SString S, int pos, int len);int  main()
{char  c[MAX_STR_LEN + 1];SString T;printf("请输入串T: ");gets_s(c);//接收字符串printf("输入的字符串为 %s\n", c);printf("输入的字符串长度为 %d\n", strlen(c));if (!StrAssign(T, c)){printf("串长超过MAX_STR_LEN(=%d)\n", MAX_STR_LEN);exit(0);}Strshow(T);printf("T长度为 %d\n", StrLength(T));///SString S;StrCopy(S, T);Strshow(S);///if (StrEmpty(S)){printf("串S为空!\n");}else{printf("串S不为空!\n");}printf("比较S和T的长度结果 %d\n", StrCompare(S, T));SString S1, S2;printf("请输入串s1: ");gets_s(c);//接收字符串printf("输入的字符串S1为 %s\n", c);printf("输入的字符串S1长度为 %d\n", strlen(c));StrAssign(S1, c);printf("请输入串s2: ");gets_s(c);//接收字符串StrAssign(S2, c);printf("输入的字符串S2为 %s\n", c);printf("输入的字符串S2长度为 %d\n", strlen(c));StrConcat1(T, S1, S2);Strshow(T);StrConcat2(S1, S2);Strshow(S1);printf("字符串S1长度为 %d\n", S1[0]);printf("T在S1中的位置为 %d\n",Index1(S1, S2));int pos = 3, len = 2;printf("T在S1中的位置为 %d\n",Index2(S1, S2,pos));StrInsert(S1, pos, T);Strshow(S1);StrDelete(S1, pos,len);Strshow(S1);return 0;
}//1、生成一个其值等于chars的字符串T
bool StrAssign(SString T, char *chars)
{int i;if (strlen(chars) > MAX_STR_LEN)//chars 的长度大于最大长度,返回falsereturn false;else{T[0] = strlen(chars); // 0号单元存放串的长度for (i = 1; i <= T[0]; i++)//从1号单元开始复制串的内容{T[i] = *(chars + i - 1);//等价于T[i] = chars[i-1];    }return true;}
}
//2、由串T复制得串S
void StrCopy(SString S, SString T )
{ int i;for (i = 0; i <= T[0]; i++)S[i] = T[i];
}//3、若S为空串,则返回true,否则返回false
bool StrEmpty(SString S)
{if (S[0] == 0)return true;elsereturn false;
}
//4、字符串长短比较,返回S长度-T长度
int StrCompare(SString S, SString T)
{// 初始条件:串S和T存在。//操作结果:若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0int i;for (i = 1; i <= S[0] && i <= T[0]; ++i)if (S[i] != T[i])return S[i] - T[i];return S[0] - T[0];
}
//5、返回串S的元素个数
int StrLength(SString S)
{ return S[0];
}//6、显示串的值
void Strshow(SString S)
{int i;for (i = 1; i <= S[0]; i++)//从1号单元开始逐单元输出串中的字符{printf("  %c", S[i]);}printf("\n");
}//7、串的拼接 S1后接S2,结果放在T中
bool StrConcat1(SString T, SString S1, SString S2)
{ // 用T返回S1和S2联接而成的新串。若未截断,则返回true,否则falseint i;if (S1[0] + S2[0] <= MAX_STR_LEN){ // 未截断for (i = 1; i <= S1[0]; i++)//先放S[1]到T中T[i] = S1[i];for (i = 1; i <= S2[0]; i++)//接着放S[2]到T中T[S1[0] + i] = S2[i];T[0] = S1[0] + S2[0];return true;}else{ // 截断S2for (i = 1; i <= S1[0]; i++)//先放S[1]到T中T[i] = S1[i];for (i = 1; i <= MAX_STR_LEN - S1[0]; i++)//关键,若第一个串长度超过MAX_STR_LEN 则条件不成立T[S1[0] + i] = S2[i];T[0] = MAX_STR_LEN;return false;}
}//8、串的拼接 S1后接S2,结果放在S1中
bool StrConcat2(SString S1, SString S2)
{ // 用T返回S1和S2联接而成的新串。若未截断,则返回true,否则falseint i = 1;int lens1 = S1[0];//保存S1的长度while (i <= (MAX_STR_LEN - S1[0]) && i<= S2[0])//i小于等于除去S1长度剩余的长度&&i小于S2的长度{S1[S1[0] + i] = S2[i];//逐字符赋值i++;}S1[0] = S1[0] + i - 1;//更新S1长度if ((lens1 + S2[0]) <= MAX_STR_LEN)//判断有没有截断return true;elsereturn false;
}//9、用Sub返回串S的第pos个字符起(包括pos位置处的字符)长度为len的子串。
bool SubString(SString Sub, SString S, int pos, int len)
{ int i;if (pos<1 || pos>S[0] || len<0 || len>S[0] - pos + 1)//排除pos值不在S长度范围内的值和len值+pos值超出S长度return false;for (i = 1; i <= len; i++)Sub[i] = S[pos + i - 1];//包括pos位置处的字符Sub[0] = len;return true;
}
//10、清空串
void ClearString(SString S)
{ // 初始条件:串S存在。//操作结果:将S清为空串S[0] = 0; // 令串长为零
}//11、 返回子串T在主串S中的位置。若不存在,则函数值为0,其中,T非空。
int Index1(SString S, SString T)
{int i = 1, j = 1;for ( i = 1; i <=S[0]; i++)//循环主串{if (S[i]==T[1])//如果在主串中找到一个与子串的第一个字符相等的字符时{int cont = 1;//计数变量for ( j = 1; j <=T[0]; j++)//遍历子串{if (T[j + 1] != S[i + j])//在遍历T[0]时如果有不一致时退出遍历{ break;}else//否则计数{cont++;if (cont == T[0])//当有T[0]个字符相同时则找到子串位置return i;}                                 }           }continue;  }return 0;//不存在时
}//12、 返回子串T在主串S中第pos个字符之后的位置。若不存在,则函数值为0,其中,T非空,1≤pos≤StrLength(S)。
int Index2(SString S, SString T, int pos)
{ int i, j;if (1 <= pos && pos <= S[0]){i = pos;//从主串的第pos个字符开始和子串的第一个字符比较j = 1;while (i <= S[0] && j <= T[0]){ if (S[i] == T[j]) // 继续比较后继字符{++i;++j;}else // 指针后退重新开始匹配{i = i - j + 2;j = 1;}}if (j > T[0])return i - T[0];elsereturn 0;}elsereturn 0;
}
//13、在串S的第pos个字符之前插入串T。完全插入返回true,部分插入返回false
bool StrInsert(SString S, int pos, SString T)
{ // 初始条件:串S和T存在,1≤pos≤StrLength(S)+1// 操作结果:在串S的第pos个字符之前插入串T,第pos个位置插入T[1]。完全插入返回true,部分插入返回falseint i;if (pos<1 || pos>S[0] + 1)//插入位置不在S长度范围之内return false;if (S[0] + T[0] <= MAX_STR_LEN){ // 完全插入for (i = S[0]; i >= pos; i--)//pos之后的元素后移T[0]个长度S[i + T[0]] = S[i];for (i = pos; i < pos + T[0]; i++)//插入S[i] = T[i - pos + 1];S[0] += T[0];//更新长度return true;}else{ // 部分插入for (i = MAX_STR_LEN; i >= pos + T[0]; i--)//移动串S中位于pos之后仍在串内的字符,因为(S[0] + T[0] > MAX_STR_LEN)所S串插入T后必满, pos + T[0]是插入元素和pos及pos之前元素所占位置S[i] = S[i - T[0]];for (i = pos; i < pos + T[0] && i <= MAX_STR_LEN; i++)S[i] = T[i - pos + 1];S[0] = MAX_STR_LEN;//S的长度为最大return false;//部分插入}
}
//14、从串S中删除第pos个字符起长度为len的子串
bool StrDelete(SString S, int pos, int len)
{ // 初始条件:串S存在,1≤pos≤StrLength(S)-len+1// 操作结果:从串S中删除第pos个字符起长度为len的子串int i;if (pos<1 || pos>S[0] - len + 1 || len < 0)//pos和len的值超出范围return false;for (i = pos + len; i <= S[0]; i++)//循环删除子串后的所有字符S[i - len] = S[i];//向前移动len个位置S[0] -= len;//更新串S的长度return  true;
}

数据结构笔记(十二)-- 定长顺序结构的实现相关推荐

  1. 29、数据结构笔记之二十九数组之硬币抛掷模拟

    29.数据结构笔记之二十九数组之硬币抛掷模拟 "人生是各种不同的变故.循环不已的痛苦和欢乐组成的.那种永远不变的蓝天只存在于心灵中间,向现实的人生去要求未免是奢望.-- 巴尔扎克" ...

  2. Python语言入门这一篇就够了-学习笔记(十二万字)

    Python语言入门这一篇就够了-学习笔记(十二万字) 友情提示:先关注收藏,再查看,12万字保姆级 Python语言从入门到精通教程. 文章目录 Python语言入门这一篇就够了-学习笔记(十二万字 ...

  3. 【Visual C++】游戏开发笔记十二 游戏输入消息处理(一) 键盘消息处理

    相信大家都熟悉<仙剑奇侠传98柔情版>的人机交互方式,用的仅仅是键盘.在那个物质并不充裕的时代,一台配置并不高的电脑,一款名叫<仙剑奇侠传>的游戏,却能承载一代人对梦想的追逐. ...

  4. 【Visual C 】游戏开发笔记十二 游戏输入消息处理 一 键盘消息处理

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 本系列文 ...

  5. 读文章笔记(二):模型结构优化前沿动态综述

    读文章笔记(二):模型结构优化前沿动态综述 公众号东大自然语言处理实验室文章链接: link. NLP领域神经网络结构的发展历程: 相关模型总结分析,NLP领域模型结构的整体趋势 神经网络模型结构优化 ...

  6. 串的定长顺序存储结构|C++实现

    数据结构里的串,是一种简单的线性表 一系列相连的字符就形成了字符串 空串不含有任何字符 空格也是字符 对照ASCII码 子串必须是一个串中连续字符组成的,哪怕所有元素都是一个串中的,但是不连续也不是子 ...

  7. 设某机为定长指令字结构,指令长度12位,每个地址码占3位,试提出一种分配方案……

    2022年12月13日修改 原来的博客是 2018-09-21 17:34:47 发布 的啊,偶尔也有人让详细讲讲--行吧-- 题目: 设某机为定长指令字结构,指令长度12位,每个地址码占3位,试提出 ...

  8. 软考-软件设计师 笔记十二(数据流图)

    本栏博客目录 软考-软件设计师 笔记一(计算机组成与体系结构) 软考-软件设计师 笔记二(操作系统基本原理) 软考-软件设计师 笔记三(数据库系统) 软考-软件设计师 笔记四(计算机网络) 软考-软件 ...

  9. c语言实现定长顺序存储,c语言:定长顺序串的基本操作实实现

    // 串的定长顺序存储实现.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include #include #include #incl ...

最新文章

  1. [ Python ] PIL
  2. python 绝对路径
  3. 每日一题:leetcode456.132模式
  4. MouseOut与RollOut,MouseOver与RollOver
  5. 特殊时期,字节跳动高效有序的远程协作办公经验,值得各企业学习!
  6. [OpenJDK]native.java.lang.UNIXProcess_md.c
  7. 接下来会普及流行能实现《集中授权集中管理,分级授权逐级管理》的标准化权限系统...
  8. mysql 测试快生产慢_兴奋!阿里三位扫地憎专家总结的Mysql性能优化金字塔法则,操作细节满分...
  9. Impala 的特点
  10. flux mono 转_自语之Reactor中FluxMono的粗略使用
  11. 透析澳大利亚大学计算机硕士课程 .转
  12. 绝对干货-国内值得关注的官方API集合,很全很强大(必须收藏)
  13. [情侣空间] 基于spring boot的自制情侣空间
  14. table里的th和td加了边框后,他是两个边框重合的,1PX就变成了2PX
  15. PopupWindow
  16. 意想不到,这个神奇的bug让我加班到深夜
  17. 用100nf的电容滤除72MHz正弦波信号,合适么?
  18. 「分布式架构」最终一致性:反熵
  19. Java程序员必须掌握的线程知识-Callable和Future
  20. 【附源码】计算机毕业设计SSM宿舍人员签到管理系统

热门文章

  1. torch.ones,normal,max
  2. C - 二进制换十进制(简单)
  3. 安卓intent发起广播事件给系统或当前app,并从系统或当前app中接收广播
  4. js排序算法详解-基数排序
  5. matlab2c使用c++实现matlab函数系列教程-circshift函数
  6. CELL_TYPE_STRING cannot be resovled or is not a field
  7. 图像处理二:仿射变换和透视变换
  8. 阶段1 语言基础+高级_1-2 -面向对象和封装_1面向对象思想的概述
  9. WeixinJSBridge API使用实例
  10. document.ready 与 onload 的区别