串的定义:串是由零个或多个字符组成的有限序列,是数据元素为单个字符的特殊线性表。
串长:串中所包含的字符个数。
空串:长度为零的串,它不包含任何字符。记作“∅”
空格串:由一个或多个空格组成的串,其长度为串中空格字符的个数。它与空串∅是不同的概念。
子串个数:2n+1
串与线性表的区别:
1.串的数据对象约束为字符集。
2.线性表的基本操作中,大多以“单个元素”作为操作对象;而串的基本操作中,通常以“串的整体”作为操作对象。
串与字符的区别:
"a"串,长度为1的串。(除了要存储字符‘a',还要存储串长1)
'a'字符a。(只存储字符‘a')
串的计算:
#include<string.h>
strcmp(char s1,char s2) //比较
strcpy(char to,char from) //复制
strcat(char to,char from) //连接
strlen(char s) //串长
Status Concat(SString &T,SString S1,SString S2)
{
if(S1.length+S2.length<=MAXLEN)//不截断
{
for(i=1;i<=S1.length;i++) T.ch[i]=S1.ch[i];
for(i=1;i<=S2.length;i++) T.ch[i+S1.length]=S2.ch[i];
T.length=S1.length+S2.length;
uncut = TRUE;
}
else //截断
{
for(i=1;i<=S1.length;it+) T.ch[i]=S1.ch[i];
for(i=1;i<=MAXLEN-S1.length;i++) T.ch[i+S1.length]=S2.ch[i];
T.length = MAXLEN;
uncut = FALSE;
}
return uncut;
}
数组:
数组的定义:数组是由一组类型相同的数据元素构成的有序集合,每个数据元素称为一个数组元素(简称为元素),每个元素受n(n≥1)个线性关系的约束,每个元素在n个线性关系中的序号i1、i2、...、in称为该元素的下标,并称该数组为n维数组。
数组的特点:
1.元素本身可以具有某种结构,属于同一数据类型。
2.数组是一个具有固定格式和数量的数据集合。
二维数组是数据元素为线性表的线性表。
数组基本操作:
1.存取:给定一组下标,存储或读出对应的数组元素。
2.修改:给定一组下标,修改与其相对应的数组元素。
广义表:
广义表是线性表的推广,也被称为列表(lists)。
广义表一般记作:
LS=(a1,a2,a3,…,a n)
LS是表的名称,n是表的长度。在线性表的定义中,a i (1<=i<=n)只能限于单个元素,但是在广义表中a i 可以是 单个元素,也可以是广义表,分别称为广义表LS的原子和子表。 当广义表非空时,第一个元素(a1)被称为表头,其余元素(a2,a3,…,a n)被称为子表。
二,广义表的存储结构
由于广义表的数据元素可以是原子和子表,因此很难用顺序存储结构来表示,通常采用链式存储结构,每个数据元素可以用一个结点来表示。
由此我们需要2种数据结构来表示结点:一个是表结点,用来表示列表,另一个是原子结点,用来表示原子。
广义表的操作:
//返回一个空的广义表
Mul_Lists GetMulLists(void);
//构造广义表
void InitMulLists(Mul_Lists *LS, char *Num, LS_Data Data[], int Len);
//广义表是否为空
bool Empty(Mul_Lists *LS);
//销毁广义表
void Destroy(Mul_Lists *LS);
//获取广义表的长度
unsigned int Length(Mul_Lists *LS);
//获取广义表的深度
unsigned int Depth(Mul_Lists *LS);
//获取表头数据
LS_Data *GetHead(Mul_Lists *LS);
//获取表尾数据
LS_Data *GetTail(Mul_Lists *LS);
//插入元素(第一个元素)
void InsertFirst(Mul_Lists *LS, const LS_Data Data);
//删除元素(第一个元素)
LS_Data DeleteFirst(Mul_Lists *LS);
//遍历广义表
void Traverse(Mul_Lists* LS);
//构造广义表
void InitMulLists(Mul_Lists *LS, char *Num, LS_Data Data[], int Len)
{
int len = 0;//记录表长度
LS_Node *curPtr = NULL;
//如果表的编号为空就直接返回
if (!STRING_LEN(Num))
return;
//给头结点赋值,只做一次(即进入递归之后不能修改头结点)
if (!LS->len)
{
LS->lastNode = LS->headPtr = GetListsNode(LIST);
curPtr = LS->lastNode;
}
//进入递归后会执行else中的代码
else
{
curPtr = GetListsNode(LIST);
LS->lastNode->ptr.hp = curPtr;
LS->lastNode = curPtr;
}
LS->len++;
//表长加一
++len;
//删除首字符
DeleteString(Num);
while (STRING_LEN(Num))
{
//修改LS中的表长
LS->len = len;
if (Num[0] == '(')
{
//记录尾结点
LS->lastNode = curPtr;
//进入递归
InitMulLists(LS, Num, Data, Len);
}
else if (Num[0] == ',')
{
curPtr = LS->lastNode;
curPtr->ptr.tp = GetListsNode(LIST);
curPtr = curPtr->ptr.tp;
LS->lastNode = curPtr;
//表长加一
++len;
}
else if (Num[0] == ')')
{
break;
}
else
{
//链接新节点
curPtr->ptr.hp = GetListsNode(ATOM);
//给节点数据赋值
curPtr->ptr.hp->value = Data[0];
//移除第一个数据
DeleteArray(Data, &Len);
}
//删除首字符
DeleteString(Num);
}
}
//销毁结点
static void FreeMulListsNode(LS_Node *Node)
{
LS_Node *temp = NULL;
while (Node)
{
if (Node->ptr.hp->Tag == ATOM)
{
//释放原子结点
free(Node->ptr.hp);
}
else if (Node->ptr.hp->Tag == LIST)
{
//递归删除列表结点
FreeMulListsNode(Node->ptr.hp);
}
//保存下一个结点的位置
temp = Node->ptr.tp;
//释放列表结点
free(Node);
Node = temp;
}
}
//计算广义表深度
static int ListsDepth(LS_Node *Node)
{
//如果表为空表时,直接返回长度1;
if (PTR_IS_NULL(Node))
{
return 1;
}
//如果表为原子时,直接返回0;
if (Node->Tag == ATOM)
{
return 0;
}
int max = 0; //设置表的初始长度为0;
LS_Node *temp = Node;
while (temp)
{
int dep = ListsDepth(temp->ptr.hp);
if (dep > max)
{
max = dep; //每次找到表中遍历到深度最大的表,并用max记录
}
temp = temp->ptr.tp;
}
//程序运行至此处,表明广义表不是空表,由于原子返回的是0,而实际长度是1,所以,此处要+1;
return max + 1;
}