广义表广泛应用于人工智能中,不可不谓很重要!
在学习的过程中,书里没有给出确切的实现方法。而在网上大多数是用c++面向对象来写的。程序冗长。而用C语音写出来的大多有点复杂。所以我结合了一下,写了一个比较容易实现的广义表。
广义表的节点分为两类:一类是原子(atom),另一类是子表(list)。在写节点时候我们需要给节点做标记,以便对节点类型做出判断,然后执行相应的操作。
下面是广义表的一个简单示意图,希望可以帮助大家理解。
#include<iostream>
#include<cassert>
using namespace std;
typedef enum {ATOM,LIST}AtomType;
typedef struct Node {
AtomType type;
union {
char atom;
struct Node *hp;
};
struct Node *tp;
}*GLNode;
GLNode Create_List(char* &str) {
assert(*str);
Node *head = new Node;
GLNode prev = head;
++str;
while (*str) {
if (*str >= 'a'&&*str <= 'z') {
prev->type = ATOM;
prev->atom = *str;
prev->tp = new Node;
prev = prev->tp;
++str;
}
else if (*str == '(') {
prev->type = LIST;
prev->hp = new Node;
prev->hp = Create_List(str); //递归
prev->tp = new Node;
prev = prev->tp;
++str;
}
else if (*str == ')') {
prev = NULL;
return head;
}
else ++str;
}
return head;
}
void output(GLNode head) {
cout << "(";
GLNode prev = head;
while (prev) {
if (prev->type == ATOM) {
cout << prev->atom;
prev = prev->tp;
}
else if (prev->type == LIST) {
output(prev->hp);
prev = prev->tp;
}
if (prev->type == ATOM || prev->type == LIST)cout << ",";
else break;
}
cout << ")";
}
int Depth(GLNode head) {
int depth=0;
GLNode p = head;
while (p) {
if (p->type == ATOM) p = p->tp;
else if (p->type == LIST) {
if(depth < Depth(p->hp)) depth = Depth(p->hp);
p = p->tp;
}
else break;
}
return depth+=1;
}
int Length(GLNode head) {
int length = 0;
GLNode p = head;
while (p) {
if (p->type == ATOM) {
++length;
p = p->tp;
}
else if (p->type == LIST) {
length += Length(p->hp);
p = p->tp;
}
else break;
}
return length;
}
GLNode Copy(GLNode head) {
GLNode p = head;
GLNode new_head = new Node;
GLNode n_p = new_head;
while (p) {
if (p->type == ATOM) {
n_p->type = ATOM;
n_p->atom = p->atom;
p = p->tp;
n_p->tp = new Node;
n_p = n_p->tp;
}
else if (p->type == LIST) {
n_p->type = LIST;
n_p->hp = new Node;
n_p->hp = Copy(p->hp);
p = p->tp;
n_p->tp = new Node;
n_p = n_p->tp;
}
else if (p == NULL)n_p == NULL;
else break;
}
return head;
}
void main() {
GLNode head = new Node;
char *str = "(a,(b,(g,h,(f,k)),d),c)";
head = Create_List(str);
output(head);
cout << endl;
cout << Depth(head) << endl;
cout << Length(head) << endl;
GLNode n_head = new Node;
n_head = Copy(head);
output(n_head);
cout << endl;
system("pause");
}