广义表的存储及比较

本文记录了关于广义表的存储,以及比较两个广义表是否相等的一个题目。

1 题目描述

【问题描述】

请写出判断两个广义表是否相等的递归算法,如果两个广义表相等,则输出1,否则输出0。如A=((a)),B=((a)),则A=B,输出1。要求输入的广义表采用链式存储结构存储,并基于链式存储结构编写递归函数。

【输入形式】

输入为由原子元素(数字,字符)、逗号、圆括号组成的广义表。先输入一个广义表,回车后再输入一个广义表。

【输出形式】

数字1,或者0。

【样例输入】

((a),b)

((a),b)

【样例输出】

1

【样例说明】
【评分标准】如果广义表未采用链式存储结构存储,或未基于链式存储结构编写递归函数,都不得分

2 基本思路

思路很简单。用链式结构存储,然后递归比较是否相等。但是由于自己的指 针知识学的很不扎实。做这道简单的题目做了好久。下面介绍一下我做的时候遇到的难点。

难点一:链式结构的设计。因为可能括号层数很多。所以我就设计成这样的结构。

typedef struct GLNode {
   
    int tag;
    char atom;
    struct GLNode *hp;
    struct GLNode *tp;
}glNode,*Glist;

tag代表标签,如果标签为0,就表示是一个普通元素。这时把hp赋值空(tp代表同层中的另一个元素,hp表示下一层。)。如果标签为1,则表示是(m,n)这种类型的元素。所以要创建子层,然后hp指向它。
这里你可能会问,为啥不把hp和atom设计成一个union类型,这,,,只能说自己太菜了,玩不六union.
在这里插入图片描述
数据结构的设计其实并不难。大概是脑子短路了,才觉得这很难😥.

难点二:如果将输入的字符串存入结构。
如果是单个元素,貌似很容易,但是如果是有括号,那怎么办呢。到右括号时看成一个元素。额,貌似不对,如果多个括号怎么办。于是这里我用一个变量记录括号层数。左括号+1,右括号-1,变量为0时也就是成功的剥离出了一个带括号的元素。

难点三:如何比较是否相等,这个其实是比较简单的递归。每一层的比较方式都相同,如果遇到子层,则递归调用,就好了,同一层的就在比较方法里进行比较。

3 具体实现

1.数据的剥离:

Glist storage2(string s) {
   
    Glist head = new glNode;
    Glist temp;
    Glist w = head;
    int flag = 0;
    int point = 1;
    for (int i = 1; i < s.length(); ++i) {
   
        if(s[i] == '(') {
   
            flag++;
           }
        if(s[i] == ')') {
   
            flag--;
        }
        if ((s[i] == ',' && flag == 0) || i == s.length() - 1 ) {
   
            storage(temp, s.substr(point, i - point));
            w->tp = temp;
            w = w->tp;
            flag = 0;
            point = i + 1;
        }
    }
    return head->tp;
}

看着是不是有点懵,有一种想小声嘀咕(这是什么垃圾代码)的冲动。好吧,我也有这种冲动。不过尽管如此,我还是想解释一下我的代码😂。首先申请一个头节点。然后定义一个结构体的指针变量temp。然后再定义一个结构体的指针变量w。w指向头节点。前两个判断语句就不说了,用来判断层数的。然后第三个if,一旦执行,就表示找到了一个元素,一开始point指向1(去除了最外围的‘(’),然后找到了一个元素,此时i应该指向的是逗号,然后就应该明白元素的截取了。flag=0表示重新计算层次。

接下来是硬核。w->tp = temp,这是什么意思,这里storage函数的意思是,把元素按照约定的方式存储,然后把第一个节点返回来。

  • 11
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值