【数据结构】NOJ014 求广义表深度

//【数据结构】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.题目要求“分别用表头、表尾分析法输出深度”,然而上网找了许久都只有一种深度求法。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值