数据结构复习之广义表的创建和遍历

#include<iostream>
#include<string>
#include<cstring>
#include<cstdlib>
#include<list>
#include<map>
using namespace std;

class GLNode{
    public:
        int tag;
        string node;
        class {
            public:
                GLNode *hp, *tp;
        } ptr;
};

typedef GLNode *GList;

class MyGList{
    public:
        static const int ERROR = -1;
        static const int OK = 1;
        static const int LIST = 2;
        static const int NODE = 3;
        list<string> sl;//广义表的描述字符串
        map<string, string>mp;
        GList L = NULL;
        MyGList(list<string> sl){
            this->sl = sl;
            initMap();
        }

        void buildGList(){
            string s = *sl.begin();
            int pos = s.find_first_of("=");
            if(pos!=s.npos)
                createGList(L, s.substr(pos+1, s.length()));
        }

        void outGList(){
            out(L);
        }

    private:
        void server(string &s, string &hs){
            int k = 0;//记录尚未匹配的左括弧的个数
            int i = 0;
            for(i; i<s.length(); ++i) {
                if(s[i]==‘(‘) ++k;
                if(s[i]==‘)‘) --k;
                if(k==0 && s[i]==‘,‘) break;
            }
            if(i < s.length()){
                hs = s.substr(0, i);
                s = s.substr(i+1, s.length()-(i+1));
            } else {
                hs = s;
                s = "";
            }
        }

        int initMap(){
            for(list<string>::iterator i = sl.begin(); i!=sl.end(); ++i){
                string s = *i, first, second;
                   int pos = s.find_first_of("=");
                   if(pos!=s.npos){
                       first = s.substr(0, pos);
                       second = s.substr(pos+1, s.length());
                   } else {
                       cout<<"广义表的描述字符串出错!"<<endl;
                       return ERROR;
                   }
                mp.insert(make_pair(first, second));
            }
        }

        void out(GList Lx){
            if(!Lx) return;
            if(Lx->tag==NODE){
                cout<<Lx->node<<endl;
                return;
            }
            for(GList p=Lx; p; p=p->ptr.tp)
                out(p->ptr.hp);
        }

        void createGList(GList &L, string s){
            if(s=="()"){
                //创建空表
                L = NULL;
            } else {
                L = new GLNode;//因为类中有string变量,不能用malloc, 否者赋值无效
                if(s.find(",")==s.npos && s.find("(")==s.npos && s.find(")")==s.npos){//原子结点
                    if(mp.find(s) == mp.end()){
                        L->tag = NODE;
                        L->node = s;
                    } else {//当s是只有一个大写字母组成的时候,说明它是一个子表,继续扩展
                        createGList(L, mp[s]);//这块出了开始bug, 调了好长时间
                    }
                } else {//非原子结点
                    L->tag = LIST;
                    GList p = L, q;
                    s = s.substr(1, s.length()-2);
                    do{
                        string hs;
                        server(s, hs);//分离表头
                        createGList(p->ptr.hp, hs);
                        q = p;
                        if(s!=""){//表尾不空
                            p = new GLNode;
                            p->tag = LIST;
                            q->ptr.tp = p;
                        }
                    }while(s!="");
                    q->ptr.tp = NULL;
                }
            }
        }
};

int main(){
    freopen("in.txt", "r", stdin);
    list<string> sl;
    string s;
    while(cin>>s){
        sl.push_back(s);
    }
    MyGList myGList(sl);
    myGList.buildGList();
    myGList.outGList();
    return 0;
}

测试数据:

D=(A,B,C)
A=()
B=(e)
C=(a,(b,c,d))

 
时间: 2024-10-19 01:53:52

数据结构复习之广义表的创建和遍历的相关文章

广义表的创建与打印

广义表的创建与打印            本文取自<数据结构与算法>(C语言版)(第三版),出版社是清华大学出版社. 本博文作为学习资料整理. 源码是VC++ 6.0上可运行程序,我挪到了VS2010中运行. 在VS2010中新建C++ Win32 控制台应用程序项目,创建结果截图:            1.广义表的创建: 广义表的存储结构示意图:演示样例:C(x, y, (a, b)) 广义表能够通过以下的递归方式进行定义. 基本项:(1)广义表为空表,当s为空时:(2)广义表为原子结点.

数据结构29:广义表的长度和深度

广义表的长度 通过前一节对广义表的介绍,例子中给出了几个广义表的长度.例如:空表的长度为 0,只含有一个原子的广义表长度为 1,等等. 广义表的长度指的是广义表中数据元素的数量.这里需要指明的是,一个广义表中,一个原子算做是一个元素,一个子表也只算做一个元素. 在 LS = (a1,a2,…,an) 中,ai表示原子或者子表, LS 的长度为 n. 广义表的深度 广义表的深度,指的是广义表中括号的重数.例如:C=(a,(b,c,d)): 图1 广义表C的深度 图1中,从前往后数左括号的数量就是广

数据结构28:广义表及M元多项式

广义表,又称为列表.记作: LS = (a1,a2,…,an) ;( LS 为广义表的名称, an 表示广义表中的数据). 广义表可以看作是线性表的推广.两者区别是:线性表中的数据元素只能表示单个数据元素:广义表中的单个数据元素 ai ,既可以是单个元素,也可以是广义表. 原子和子表 在广义表中,单个元素被称为 “原子”:包含的广义表被称为 “子表”. 例如: A = ()  :A 表示一个广义表,只不过表是空的,广义表 A 的长度为 0. B = (e)  :广义表 B 中只有一个原子 e ,

【数据结构复习】线性表的链式存储--单链表

链表的重点概念: 数据域和指针域 头指针和头结点 下面是单链表的实现源码: // // main.c // DataStructure // // Created by SuooL on 15/5/22. // Copyright (c) 2015年 SuooL. All rights reserved. // #include "stdio.h" #include "string.h" #include "ctype.h" #include &

数据结构之 线性表--顺序创建链表

数据结构实验之链表一:顺序建立链表 Time Limit: 1000MS Memory limit: 65536K 题目描述 输入N个整数,按照输入的顺序建立单链表存储,并遍历所建立的单链表,输出这些数据. 输入 第一行输入整数的个数N: 第二行依次输入每个整数. 输出 输出这组整数. 示例输入 8 12 56 4 6 55 15 33 62 示例输出 12 56 4 6 55 15 33 62 写的时候,定义一个结构体变量就要为它申请空间,不然程序会运行时出问题 ! #include <ios

数据结构复习之线性表

线性表的存储结构 1.顺序存储结构 存储方式:顺序储存结构用一段连续的存储单元一次存储线性表的的数据元素 适用情况:当线性表频繁查找,很少进行插入和删除操作的情况 优缺点: 优点:  无须为表示元素之间的逻辑关系而增加额外的存储空间 可以快速地存取表中任一位置的元素 缺点:  插入和删除元素操作需要移动大量元素 当线性表长度变化较大时,难以确定存储空间的容量 顺序存储结构需要预分配存储空间,分大了易造成浪费,分小了,易发生向上溢出 造成存储的碎片化 2.链式存储结构 存储方式:单链表采用链式存储

数据结构复习之顺序表3中删除元素的方式(你造吗)

#include<iostream> #include<cstring> #include<string> #include<queue> #include<map> #include<cstdio> using namespace std; template <typename T> class Sqlist{ public: T data[100]; int n; void initData(); void delet

【数据结构之二叉树】二叉树的创建、遍历等操作

二叉树的基本操作: 1.创建二叉树 2.销毁二叉树 3.遍历二叉树:1)前序遍历 2)中序遍历 3)后序遍历 4)层次遍历 4.搜索二叉树 5.删除子叶 6.插入子叶 7.获取左/右子叶的值 8.获取树深度 9.获取叶子结点数 1.创建二叉树 这里创建的是链式存储结构的二叉树,包含数据域,左右两结点的指针域:在读取创建树时,以#代替空格,输入格式的规范为:以前序遍历的顺序输入,如果该结点的左子叶为空,则输入#,以此类推: e.g: -  +         \ a    *    e    f 

javascript实现数据结构:广义表

原文:javascript实现数据结构:广义表  广义表是线性表的推广.广泛用于人工智能的表处理语言Lisp,把广义表作为基本的数据结构. 广义表一般记作: LS = (a1, a2, ..., an) LS是广义表的名称,n是它的长度,ai可以是单个元素,也可以是广义表,分别称为广义表LS的原子和子表.习惯上,用大写字母表示广义表的名称,小写字母表示原子.当广义表LS非空时,称第一个元素a1为LS的表头,称其余元素组成的表(a2, a3, ..., an)是LS的表尾. 下面列举一些广义表的例