c/c++ 广义表
广义表
列表里面有列表,比如(1,(2,(3,4)),5)
用链表可以实现
结果如图

guangyibiao.h
#ifndef __GUANGYIBIAO__
#define __GUANGYIBIAO__
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <malloc.h>
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
#define AtomType int
typedef enum{ATOM, LIST}ElemTag;
typedef struct GLNode{
ElemTag tag;
union{
AtomType atom;
struct GLNode* head;
};
struct GLNode* tail;
}GLNode;
typedef GLNode* GenList;
void init(GenList* gl);
void createGenList(GenList* gl, char* s);
void show(GenList gl);
#endif
guangyibiao.c
#include "guangyibiao.h"
void init(GenList* gl){
*gl = NULL;
}
//挑出逗号前的一个元素,元素可以是原子也可以是列表
bool server1(char* sub, char* hsub){
int n = strlen(sub);
int i = 0;
char ch = sub[0];
int k = 0;
//k的作用是,识别逗号是括号里的,还是括号外的,如果是括号外的逗号就跳出while了,括号内的逗号不跳出循环,继续往下找。
while(i < n && (ch != ',' || k != 0)){
if(ch == '('){
k++;
}
else if(ch == ')'){
k--;
}
i++;
ch = sub[i];
}
//逗号在sub的范围内
if(i < n){
sub[i] = '\0';
strcpy(hsub, sub);
strcpy(sub, sub+i+1);
}
//括号不匹配
else if(k != 0) return false;
//sub本身就是表,比如为(1,2)时,i会等于n,所以把sub给hsub,sub就没有以后部分了
else{
strcpy(hsub, sub);
sub[0] = '\0';
}
return true;
}
//思路:递归创建节点,如果sub是列表,就递归调用自己
void createGenList(GenList* gl, char* s){
int n = strlen(s);
//去掉s的外括号,比如s为(1,(2, 3)),处理后sub为1,(2, 3),并在sub的最后加上'\0'
char* sub = (char*)malloc(sizeof(char) * (n - 2));
char* hsub = (char*)malloc(sizeof(char) * (n - 2));
assert(NULL != sub && NULL != hsub);
strncpy(sub, s+1, n-2);
sub[n-2] = '\0';
GLNode* p = *gl;
while(strlen(sub) != 0){
if(NULL == p){
*gl = p = (GLNode*)malloc(sizeof(GLNode));
p->head = p->tail = NULL;
}else{
p = p->tail = (GLNode*)malloc(sizeof(GLNode));
p->head = p->tail = NULL;
}
assert(NULL != p);
if(server1(sub, hsub)){
if(hsub[0] == '('){
p->tag = LIST;
createGenList(&(p->head), hsub);
}
else{
p->tag = ATOM;
p->atom = atoi(hsub);
}
}
}
}
//思路:递归
void show(GenList gl){
if(gl == NULL) return;
if(gl->tag == ATOM){
printf("%d", gl->atom);
if(gl->tail != NULL){
printf(",");
}
//如果gl为ATOM的话,gl就不会有head,所以只需调用show(gl->tail)
show(gl->tail);
}
//如果gl为LIST的话,gl就会有head,也会有tail,所以调用show(gl->head),show(gl->tail)
else if(gl->tag == LIST){
printf("(");
show(gl->head);
printf(")");
if(gl->tail != NULL){
printf(",");
}
show(gl->tail);
}
}
guangyibiaomai.c
#include "guangyibiao.h"
int main(){
GenList gl;
init(&gl);
char* a = "(1,2,3)";
char* b = "(1,(2,3))";
char* c = "(1,(2),3)";
char* d = "((1,2),3)";
char* e = "((1,2,3))";
char* f = "((),1)";
char* g = "(1,(2,(3,4)),5)";
char* h = "((),1,(2,(3,(),4)),5)";
char* i = "(())";
createGenList(&gl, i);
if(gl != NULL){
printf("(");
show(gl);
printf(")\n");
}
return 0;
}
c/c++ 广义表的更多相关文章
- 数据结构(C语言第2版)-----数组,广义表,树,图
任何一个算法的设计取决于选定的数据结构,而算法的实现依赖于采用的存储结构. 之前线性表的数据元素都是非结构的原子类型,元素的值是不可再分的.下面学习的这两个线性表是很特殊的,其中数据元素本身也可能是一 ...
- 广义表 Head Tail
head:取非空广义表的第一个元素 tail:取非空广义表除第一个元素外剩余元素构成的广义表 L=((x,y,z),a,(u,t,w)) head(L)为(x,y,z) head(head(L))为x ...
- 数据结构算法C语言实现(十九)--- 5.5&5.6&5.7广义表
一.简述 传说Lisp的基本数据结构就是广义表,广义表也是具有典型递归属性的数据结构,此外,由于建表要处理字符串,用C语言处理起来也是一脸懵逼.....最后自己还想写一个将广义表还原成字符串的函数,一 ...
- javascript实现数据结构:广义表
原文:javascript实现数据结构:广义表 广义表是线性表的推广.广泛用于人工智能的表处理语言Lisp,把广义表作为基本的数据结构. 广义表一般记作: LS = (a1, a2, ..., an ...
- 【C/C++】实现数据结构广义表
1. 广义表的定义 每个元素可以为Atom,原子,也可以为线性表. 线性表的推广.线性表元素有唯一的前驱和后继,为线性表,而广义表是多层次的线性表 表头:第一个元素,可能是 ...
- 数据结构(C语言版)-第4章 串、数组和广义表
补充:C语言中常用的串运算 调用标准库函数 #include<string.h> 串比较,strcmp(char s1,char s2) 串复制,strcpy(char to,char f ...
- 广义表操作 (ava实现)——广义表深度、广义表长度、打印广义表信息
广义表是对线性表的扩展——线性表存储的所有的数据都是原子的(一个数或者不可分割的结构),且所有的数据类型相同.而广义表是允许线性表容纳自身结构的数据结构. 广义表定义: 广义表是由n个元素组成的序列: ...
- 数据结构:广义表的实现(Java)
广义表的简单理解在这篇博文中:https://blog.csdn.net/lishanleilixin/article/details/87364496,在此不做赘述. Java实现广义表: pack ...
- 数据结构28:广义表及M元多项式
广义表,又称为列表.记作: LS = (a1,a2,…,an) ;( LS 为广义表的名称, an 表示广义表中的数据). 广义表可以看作是线性表的推广.两者区别是:线性表中的数据元素只能表示单个数据 ...
随机推荐
- 项目详解4—haproxy 反向代理负载均衡
一.企业服务架构图及负载均衡的要求 1.场景说明 在企业生产环境中,每天会有很多的需求变更,比如增加服务器.新业务上线.url路由修改.域名配置等等,对于前端负载均衡设备来说,容易维护,复杂度低,是首 ...
- Perl的IO操作(2):更多文件句柄模式
open函数除了> >> <这三种最基本的文件句柄模式,还支持更丰富的操作模式,例如管道.其实bash shell支持的重定向模式,perl都支持,即使是2>&1 ...
- python装饰器1:函数装饰器详解
装饰器1:函数装饰器 装饰器2:类装饰器 装饰器3:进阶 先混个眼熟 谁可以作为装饰器(可以将谁编写成装饰器): 函数 方法 实现了__call__的可调用类 装饰器可以去装饰谁(谁可以被装饰): 函 ...
- JQuery官方学习资料(译):$( document ).ready()
一个页面直到document是”ready“才能被安全的操作,Jquery为你检查这种状态.代码包含在$( document ).ready()的内部将会仅仅运行一次在页面Document ...
- 4.4 explain 之 possible_keys 、key、key_len
一.possible_keys 显示可能应用在这张表中的索引,一个或多个. 查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询实际使用. 二.key 实际使用的索引.如果为null,则没有 ...
- Mac下写博客工具MarsEdit相关资料
参考资料: https://www.maoshu.cc/967.html 下载地址: https://www.red-sweater.com/marsedit/ 博客园的配置: http://www. ...
- Hibernate(十四)抓取策略
抓取策略: 抓取策略是当应用程序需要在(Hibernate实体对象图的)关联关系间进行导航的时候,Hibernate如何获取关联对象的策略.Hibernate的抓取策略是Hibernate提升性能的一 ...
- JavaAndroid项目结构
使用Java的Android项目的结构 src: 源码文件夹 gen: 自动生成的源码文件夹 assets: 资产目录 bin: 编译生成的文件目录(apk等) libs: jar包 res: 资源文 ...
- 清除float影响
条件: 父元素中有子元素float的话,可能就会影响父元素的高度,从而影响布局: 解决方案: 1.直接给父元素定高: 弊端:必须知道父元素的高: 2. 父元素使用overflow属性值为hidden解 ...
- 剑指offer:2.二维数组的查找(Java版)
备注:本文参照<剑指offer第二版> 题目: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数, 输入这样的一个二维数组和一个整数 ...