//【数据结构】NOJ014 求广义表深度
//表头-表尾表示法
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
//广义表定义
typedef char Atomtype;
typedef enum{ATOM,LIST}NodeTag; //枚举类型
typedef struct GLNode //一个表结点
{
NodeTag tag;
union
{
Atomtype atom; //元素值
struct
{
struct GLNode *hp,*tp; //表头结点、表尾结点
}ptr;
};
}GLNode,*GList;
bool Create(GList *L,char *s); //根据输入字符串s,创建广义表
int GetDepthByhp(GList L); //按表头-表尾分析方法求表深
void server(char *s1,char *s); //分离s为s1头字符串与s尾字符串
void substr(char *s,char *s1,int start,int len); //复制字符串
bool Create(GList *L,char *s)
{//将字符串s插入L
char s1[100]; //存储待插入的表头结点
GList p,q; //p始终存储第一级广义表表尾结点,q存储p的前一个结点
if(s==NULL) //s为空则当前表空
(*L)=NULL;
else
{
(*L)=(GList)malloc(sizeof(GLNode)); //新建一个表结点
if(strlen(s)==1) //原子结点
{
(*L)->tag=ATOM;
(*L)->atom=*s;
}
else //表结点
{
substr(s,s,2,strlen(s)-2); //脱去最外层括号
p=(*L);
p->tag=LIST;
do{ //不断分离头尾结点,插入头结点,直到尾结点为空
server(s1,s); //分离后s1为头字符串,s为尾字符串
Create(&(p->ptr.hp),s1); //插入头结点
if((*s)!='\0') //若表尾非空,新建表尾结点
{
q=p;
p=(GList)malloc(sizeof(GLNode)); //新建表尾结点
p->tag=LIST;
q->ptr.tp=p; //将表尾结点插入表尾
}
else //表尾空
{
p->ptr.tp=NULL;
}
}while((*s)!='\0');
}
}
return true;
}
int GetDepthByhp(GList L)
{
int max=0,depth;
GList p;
if(!L)return 1; //空表深度1
else if(L->tag==ATOM)return 0; //原子深度0
for(p=L;p;p=p->ptr.tp) //遍历表头深度,至表尾为空
{
depth=GetDepthByhp(p->ptr.hp); //获取表头深度
if(max<depth)max=depth; //记录最深的表头深度
}
return (max+1); //加上最外层表深
}
void server(char *s1,char *s)
{//将头字符串分离到s1中,尾字符串脱去括号放到s中,其中s已脱去外括号
int i,k; //k记录左括号数
for(i=0,k=0;i<strlen(s);i++)
{
if(s[i]=='(')k++;
else if(s[i]==')')k--;
else if(s[i]==','&&k==0)break; //此时i为头尾分隔逗号处
}
if(i<strlen(s)) //表尾非空
{
substr(s,s1,1,i); //复制头字符串
substr(s,s,i+2,strlen(s)-i-1); //复制尾字符串
}
else //表尾为空
{
substr(s,s1,1,strlen(s)); //复制头字符串
s[0]='\0'; //表尾为空
}
}
void substr(char *s,char *s1,int start,int len)
{
int i;
for(i=0;i<len;i++)
s1[i]=s[i+start-1];
s1[i]='\0';
}
int main()
{
char s[100];
scanf("%s",s);
GList L;
Create(&L,s);
printf("%d\n%d",GetDepthByhp(L),GetDepthByhp(L));
return 0;
}
【后记】
1.表头-表尾表示法反复看了很久才搞明白,这道题也完全没思路,于是去抄网上代码,改了改别人的代码就能过,自己抄别人代码就过不了,挫败感十分强烈。下午重新自己写了一遍,发现bug在于手残把所有L->tag写成了L->atom。。。emmm可以说是非常愚蠢了。脱括号那里也想了许久才想明白。
2.题目要求“分别用表头、表尾分析法输出深度”,然而上网找了许久都只有一种深度求法。