数据结构-符号表

server/2024/11/14 20:09:42/

1.概述

符号表最主要的目的就是将一个键和一个值联系起来,符号表能够将存储的数据元素是一个键和一个值共同组成的键值对数据,我们可以根据键来查找对应的值。

符号表中,键具有唯一性,符号表在实际生活中的使用场景是非常广泛的,见下表:

 2.符号表的特性

  • 键值对存储符号表通常以键值对的方式存储符号名和相关信息(如类型、值、作用域等)

  • 快速查找符号表需要支持快速查找操作,以便在编译或执行期间快速获取符号的信息

  • 作用域管理:在某些情况下,符号表需要支持多层作用域,以便处理局部变量和全局变量

  • 动态更新符号表需要能够动态添加、修改和删除符号

3.代码说明

package mainimport ("errors""fmt"
)// Symbol 结构体表示符号的信息
type Symbol struct {Name  string      // 符号名称Value interface{} // 符号的值Type  string      // 符号的类型
}// SymbolTable 结构体表示符号表
type SymbolTable struct {table map[string]*Symbol // 符号名到符号的映射
}// NewSymbolTable 创建一个新的符号表
func NewSymbolTable() *SymbolTable {return &SymbolTable{table: make(map[string]*Symbol),}
}// Set 添加或更新符号
func (st *SymbolTable) Set(name string, value interface{}, typeInfo string) {st.table[name] = &Symbol{Name: name, Value: value, Type: typeInfo}
}// Get 查找符号
func (st *SymbolTable) Get(name string) (*Symbol, error) {symbol, exists := st.table[name]if !exists {return nil, errors.New("symbol not found")}return symbol, nil
}// Remove 删除符号
func (st *SymbolTable) Remove(name string) {delete(st.table, name)
}// Print 打印符号表的内容
func (st *SymbolTable) Print() {for _, symbol := range st.table {fmt.Printf("Name: %s, Value: %v, Type: %s\n", symbol.Name, symbol.Value, symbol.Type)}
}func main() {// 创建一个新的符号表symbolTable := NewSymbolTable()// 添加一些符号symbolTable.Set("x", 10, "int")symbolTable.Set("y", 20.5, "float")symbolTable.Set("z", "Hello, World!", "string")// 获取并打印符号的值if symbol, err := symbolTable.Get("x"); err == nil {fmt.Printf("Retrieved: Name: %s, Value: %v, Type: %s\n", symbol.Name, symbol.Value, symbol.Type)}// 打印整个符号表symbolTable.Print()// 删除一个符号symbolTable.Remove("y")// 打印整个符号表fmt.Println("After removing y:")symbolTable.Print()
}

 代码说明

  1. Symbol 结构体:表示符号的基本信息,包括符号名称、值和类型

  2. SymbolTable 结构体:使用一个 map 来存储符号,键是符号名,值是 Symbol 结构体的指针

  3. NewSymbolTable:创建并返回一个新的符号表实例

  4. Set:添加或更新符号的值和类型

  5. Get:根据符号名查找符号的信息,如果未找到则返回错误

  6. Remove:从符号表中删除指定的符号

  7. Print:打印符号表中所有符号的详细信息

使用示例

        在 main 函数中,创建了一个符号表,添加了几种类型的符号(整型、浮点型和字符串),并打印了它们的信息。然后,我们删除了符号 y 并再次打印符号表的内容。

扩展功能

在实际应用中,符号表的实现可以更加复杂,例如:

  • 支持嵌套作用域(如函数内的局部变量)。
  • 支持类型检查和符号的生命周期管理。
  • 提供更复杂的查询功能,如根据类型好的,我们可以进一步扩展符号表的功能,以支持更复杂的需求。

4. 有序符号表

有序符号表(Ordered Symbol Table)是一种数据结构,通常用于存储键值对,以便能够快速查找、插入和删除操作,同时保持键的有序性。它常用于实现字典、索引等功能。

主要特性

  1. 有序性符号表中的元素是按照键的顺序存储的,支持范围查询。
  2. 高效的操作:支持高效的查找、插入和删除操作,通常时间复杂度为 O(logn)。

常见实现

有序符号表可以通过以下数据结构实现:

  1. 红黑树:一种自平衡的二叉搜索树,能够保持树的高度为 O(logn),使得查找、插入和删除操作都能在对数时间内完成。

  2. AVL树:另一种自平衡的二叉搜索树,保持严格的平衡条件,确保操作的时间复杂度为 O(logn)。

  3. B树:一种自平衡的树数据结构,适用于大规模数据的存储,常用于数据库和文件系统。

  4. 跳表:一种基于链表的概率性数据结构,支持高效的查找、插入和删除操作。

主要操作

  • 插入(Insert):将一个新的键值对添加到符号表中。
  • 查找(Search):根据键查找对应的值。
  • 删除(Delete):根据键删除对应的键值对。
  • 最小值/最大值(Min/Max):返回符号表中最小或最大的键。
  • 范围查询(Range Query):返回某一范围内的所有键值对。

应用场景

  • 数据库索引
  • 语言的符号解析
  • 实现有序集合等数据类型

示例

以下是一个简单的红黑树实现的有序符号表的伪代码示例:

class OrderedSymbolTable:def __init__(self):self.root = None  # 红黑树的根节点def insert(self, key, value):# 实现红黑树的插入操作passdef search(self, key):# 实现红黑树的查找操作passdef delete(self, key):# 实现红黑树的删除操作passdef min(self):# 返回最小键passdef max(self):# 返回最大键passdef range_query(self, low, high):# 返回范围内的所有键值对pass


http://www.ppmy.cn/server/108361.html

相关文章

数据结构——树

文章目录 二叉树和**BST**树与二叉树基本概念常见例子相关术语二叉树 二叉搜索树(**BST**)二叉树(**BST**)的算法二叉树(**BST**)完整实现 二叉树和BST 树与二叉树 基本概念 树是一种非线性结构&#xf…

MONAILabel in 3D Slicer 案例1: 在腹部CT中自动分割脾脏

MONAILabel in 3D Slicer 案例1: 在腹部CT中自动分割脾脏 导读 本系列涵盖从 3D Slicer 医学图像查看器的基础使用到高级自动分割扩展程序的内容(从入门到高阶!),具体包括软件安装、基础使用教程,自动分割扩展&#x…

网络安全的历史

如今,网络安全几乎成为各大公司和利益相关者关注的焦点。但在早期,网络安全的概念非常模糊。 直到多年以后,由于网络攻击和危险实体威胁的频繁发生,网络安全的发展才受到重视。这些措施的发展成为了网络安全的演变。 网络安全起…

Go语言Time包的使用

原文链接,关注可获取更新 time包 Go语言中有关于时间和日期的方法都在time包里面,Go语言的time包为开发者提供了一套全面而简洁的工具来处理时间相关的操作。包括解析和格式化时间字符串,计算时间差和时区转换等,time包时Go语言…

【数据结构篇】~链式二叉树(附源码)

链式二叉树 前言(含头文件)头文件 1.链式二叉树的组成2.前、中、后、层序遍历1.前序遍历2.中序遍历3.后序遍历 3.结点个数以及高度等​4.判断二叉树是否为完全二叉树 前言(含头文件) 之前的堆是特殊的二叉树是顺序结构的二叉树&a…

MySQL中的事务

一、事务是什么??? 事务(Transaction),就是将一组SQL语句放在同一批次内去执行,如果一个SQL语句出错,则该批次内 的所有SQL都将被取消执行。 二、事务的特性 原子性:意味着数据库中的事务执行是作为原…

34. 打字机效果 水平滚动贴合

打字机效果 创建打字机效果动画。 定义两个动画,typing 用于字符动画,blink 用于光标动画。使用 ::after 伪元素在容器元素中添加光标。使用 JavaScript 为内部元素设置文本,并设置包含字符数的 --characters 变量。这个变量用于文本动画。使用 white-space: nowrap 和 overfl…

LuaJit分析(五)LuaJit filename分析

LuaJit执行文件过程分析 通过之前对luajit -b命令的分析可知,在luajit.c文件的runargs函数中,用于手机参数,对相应的参数调用对应的函数,若返回LUA_OK则执行handle_script函数,该函数用于执行一个lua脚本文件&#xf…