本文记录了关于广义表的存储,以及比较两个广义表是否相等的一个题目。
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函数的意思是,把元素按照约定的方式存储,然后把第一个节点返回来。