Program in Lua中图算法的改进(打印所有图路径)

Android集成Lua脚本引擎实战:从环境搭建到双向交互完整指南 脚本引擎技术作为实现应用动态化与热更新的核心方案,在移动开发领域备受关注。其原理在于将脚本语言运行时嵌入宿主应用,通过解释执行或即时编译实现逻辑的动态加载与更新,从而赋予应用在无需重新发布安装包的情况下修改业务逻辑的能力。这一技术为应用带来了显著的价值:提升迭代效率、优化用户体验、降低发版成本,尤其适用于业务规则频繁变动、活动运营需求多的场景,如电商促销、游戏数值调整等。在Android生态中,Java/Kotlin与Lua的混合开发模式是实现该能力的主流路径之一。本文聚焦于**Android-Lua混合开 阅读详情

    在Program in Lua第二版,第11.7节中介绍了用lua写“图”数据结构的方法,

但书中提供的图的算法只能打印出第一条找到的正确路径,于是我就自己琢磨

着怎么用lua写出一个图算法打印出所有可能的路径,自己独自一个人思考了

很久,期间没有参考任何资料,完全靠“头脑暴力”把它解决了,最后思考了看看,

也不知道这到底是什么算法,完全凭借着自己认为的所谓的"退化"的概念,奇妙

的解决了这个问题,所以我把这个算法拿出来分享一下。

(总觉得在哪本书上看到过“退化”这个字眼,但我其实不知道什么是真正的“退化”,

但在我脑海里,“退化”就是一个概念而已,在这里,觉得似乎用这个概念有那么

一点合适的味道,那我就把它称之为“退化”了。另外,也许这个算法也有人实现

过,但我其实并不知道这是什么算法,我只知道这个算法的思想---用我所谓的

“退化”(因为我学的很少,至少还没去专门学过图论,所以勿喷),如果我这个

”设计“的算法你见过,或知道是什么算法可以告诉我(至少我不认为我能想出来

的东西别人会没想到,我应该还没到那种境界吧=_=))


正文:

首先是一个保存了图中数据的.lua文件,其名为graph.lua,

相对路径为./lua/graph.lua

内容如下所示:

a b 
b c
b f 
c d
c f
d e
f g
g h
f i
i j
j c
j k
i l
c k 
k l

示意图如下:

(该算法只适用于单向的图)



然后是“图”数据结构及我“设计”的这个算法:

相对路径为./lua/11.7.lua

(注释写的很详细,都写在代码里面了,不懂的可以问我)

Graph = {}
--生成图节点
function Graph.newNode(graph, name)
	if not graph[name] then
		graph[name] = {name = name, adj={}} --创建一个新的图结点
	end
	return graph[name]
end

--生成图
function Graph.gen(s)
	local graph = {}
	for line in io.lines(s) do
		--匹配起始,通往结点
		local namefrom, nameto = string.match(line, "(%S+)%s(%S+)")
		local from = Graph.newNode(graph, namefrom) --生成起始结点
		local to = Graph.newNode(graph, nameto)   --生成通往结点
		local path = from.adj       --得到路径表
		path[#path + 1] = to 		--连接图结点路径
	end
	return graph
end

function Graph.findpath(curr, to, path, visited)
--参数:当前结点, 目的结点, 保存路径的集合, 已访问结点集合(可退化)
--关于退化:这里的退化概念是自己提出的,意思是对得到一条通路上的结点
--往前回溯取消记录,以致于另一个递归搜素分支可以找到这条路径,同时,
--对于已压栈函数记录的结点和无通路径上的结点保存记录以至于递归函数
--直接返回

	path = path or {}         --path作为table来记录所有保存的路径
	visited = visited or {}   --visited为保存记录结点的表
	if visited[curr] then     --对记录结点直接返回
		return nil 
	end 
	visited[curr] = true      --记录访问节点
	path["name"] = curr["name"]  --记录路径
	if curr == to then        --找到终点,构成一条路径,返回
		visited[curr] = nil   --退化(取消该终点的记录)
		return path          
	end 
	
	local p
	for i,from in ipairs(curr.adj) do 
		path[i] = {father = path}    --保存一个能找到父结点的字段
		--递归搜索路径
		local rightPath = Graph.findpath(from, to, path[i], visited)
		if not rightPath then path[i] = nil end --找不到,取消一个子table
		p = rightPath or p   --有路径时记录最后一条通路返回,否则返回nil
	end
	
	if p then 
		visited[curr] = nil       --退化该路径节点
		return p["father"] 		  --返回该路径的father,即本结点
	end    							

	path = nil                	  --没找到,删除该节点
end

--打印所有图路径
function Graph.printPath(path, visited)
--路径结点集合, 已访问结点集合(可退化)
	path = path or {}           
	visited = visited or {}
		
	if path then 
		visited[#visited + 1] = path  --以数组形式保存访问过的路径
		io.write(path.name, " ")      --打印本结点名字和空格符
	end
	
	local maxn = table.maxn(path)     --取可行支路中的最大编号
	if maxn == 0 then 				  --不存在支路(即终点)时
		visited[#visited] = nil       --退化,取消记录该结点
		io.write("\n")                --该条路径已完全输出,换行
		return 
	end 							  --终点,返回
	
	local count = 0                   --统计支路的数目
	for i = 1, maxn do 
		if path[i] then				  --该条编号的支路存在
			count = count + 1		  --递增支路数
			if count > 1 then         		  --除第一条支路之外,
				for i,v in ipairs(visited) do --对已记录的根路结点进行打印
					io.write(v.name, " ")
				end
			end
			Graph.printPath(path[i], visited) --然后再次递归搜索下一条支路
		end
	end
	visited[#visited] = nil           --支路已搜索完毕,此分支不再搜索,退化
end

local graph = Graph.gen("./lua/graph.lua")         --生成图
local path = Graph.findpath(graph["a"], graph["l"]) --寻找图路径
Graph.printPath(path)								--输出图路径


下面是运行后的输出结果:




CTF逆向工程实战:从二进制分析到算法破解的完整指南 逆向工程是计算机安全领域的核心技术之一,它涉及对软件二进制代码的分析与理解,以揭示其内部逻辑与算法实现。其基本原理是通过静态分析与动态调试相结合的方法,解析程序的执行流程与数据结构。这项技术的核心价值在于漏洞挖掘、恶意软件分析、软件保护评估以及知识产权研究等多个领域。在网络安全竞赛(CTF)中,逆向工程挑战尤为常见,参赛者需要运用IDA Pro、Ghidra等工具进行反汇编与反编译,识别加密算法、绕过反调试机制,并最终提取关键信息。本文聚焦于CTF逆向挑战的实战流程,详细拆解了从信息收集、静态分析到动态调试 阅读详情

相关推荐

从Unity/UE4到Love2D:轻量级2D游戏开发环境搭建与高效工作流指南

在游戏开发领域,选择合适的工具链是项目成功的关键。对于2D游戏开发,尤其是快速原型、独立游戏和学习场景,重型游戏引擎的复杂性和资源消耗有时会成为创作阻力。轻量级游戏框架应运而生,它们通过提供核心的图形渲染、音频处理和输入管理功能,让开发者能够更直接地控制游戏逻辑,实现更快的迭代速度。Love2D正是这样一个基于Lua脚本语言的轻量级2D游戏框架,其核心库仅数兆大小,解压即用,并与现代代码编辑器VSCode深度协同,形成了一套高效的开发工作流。这套组合不仅解决了传统引擎的臃肿感,还通过模块化设计、清晰的游戏循

weixin_34006468的博客 611

【Lua】Lua基础语法

Lua 是一个小巧的脚本语言,用标准C语言编写而成,由巴西里约热内卢天主教大学的 Roberto Ierusalimschy、Waldemar Celes 和 Luiz Henrique de Figueiredo 三人于1993年开发,设计目的是为了灵活嵌入应用程序,实现灵活的扩展和定制功能。 Lua 具有以下特性: 脚本语言、解释型语言 嵌入程序开发 容易与其他语言相互调用 轻量级 面向过程编程 函数式编程 热更新

little_fat_sheep 4749

Roblox沙盒与6502仿真:构建继电器连锁调度系统实践

如果你正在寻找一个既能学习计算机底层原理,又能动手搭建物理控制系统的有趣项目,那么将 Roblox 的 Ro-scale sandbox 与经典的 6502 处理器仿真结合,构建一个继电器连锁调度系统,绝对值得你深入了解。这个项目听起来复杂,但核心思想很清晰: 在一个高度可视化的沙盒环境中,用虚拟继电器模拟真实硬件逻辑,通过仿 6502 汇编指令控制它们,最终实现一个如车辆调度、灯光控制或产线协调这样的连锁反应系统 。 它巧妙地将几个关键点串联起来:Roblox 的 Ro-scale sandbox 提供了

cuililai5127的博客 423

构造树

/** * 构建树结构 * * @return {Array} 树结构[{id:树id,children:[]}] */ buildTree() { const CHINA_ID = 998; const FOREIGN_ID = 999;

shanqianmin_new的博客 1109

【漏洞修复】 CVE Linux 系统应用漏洞修复笔记

根据SSL/TLS协议信息泄露漏洞(CVE-2016-2183)原理,通过发送精心构造的数据包到目标服务,根据目标的响应情况,验证漏洞是否存在。启动完成后查看nginx的版本信息,验证nginx的openssl版本号是否已经升级成功。原本我的nginx中使用的openssl 版本号为:1.0.2s。结束后在此查询openssl的版本号,验证是否升级成功。目录,使用以下命令下载最新版的安装包到此目录下。将以下的内容替换 nginx 的443配置中的。进入nginx的安装目录下的。目录下启动nginx。

张小三的博客 8841

Unreal Engine 5.1.1 集成 Angelscript 实战指南

Angelscript 是一种轻量、零GC停顿、与C++内存布局完全兼容的嵌入式脚本语言,其核心原理在于直接映射C++原生类型与虚表调用,避免序列化开销,实现游戏线程内低延迟逻辑执行。相比Python或Lua,它在UE中具备行级调试、无缝VS2022断点切入、无跨进程通信瓶颈等技术优势,特别适用于需高频热重载行为逻辑的中小团队。典型应用场景包括NPC对话树动态更新、任务触发条件实时调整、UI交互响应脚本化等——即把编译耗时长、修改频次高的纯行为层代码下沉至脚本层。本实践严格基于UE 5.1.1 LTS版本,

weixin_30399155的博客 377

7-4 树的遍历 (20 分)

7-4树的遍历(20分) 给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列。这里假设键值都是互不相等的正整数。 输入格式: 输入第一行给出一个正整数N(≤30),是二叉树中结点的个数。第二行给出其后序遍历序列。第三行给出其中序遍历序列。数字间以空格分隔。 输出格式: 在一行中输出该树的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。 输入样例: 7 2...

韩旭051的博客 6006

lua写的寻路算法

一个lua写的寻路算法,一条路径下去,寻过的节点做标记不要再寻,一个临时的航线列表做维护,选出一条路径后,以后大于这条路径长度就不要再去做递归了

通过递归构造树

使用 Stream 流的 filter() 方法来筛选根节点和子节点,并使用 peek() 方法将节点添加到相应的列表中。在 addChildren() 方法中,我们使用 Stream 流的 filter() 方法筛选出每个父节点的子节点,并将它们添加到父节点的 children 列表中。然后,再递归地调用 addChildren() 方法,以添加每个子节点的子节点,直到所有节点被处理完毕。递归出口:可以想到,当子节点下再找不到下一级的子节点了,那么这个root节点下的递归构造就完成了,便可回溯。

qq_1763467007的博客 1667

lua算法:Lua算法库,涵盖了常用的数据结构和算法

lua算法:Lua算法库,涵盖了常用的数据结构和算法

VASPKIT绘制平面平均电荷差分密度

平面平均密度差(planar-averaged electron density difference)是密度差的衍生。密度差是个三维空间函数,经常通过绘制平面图、等值面图方式图形化考察。虽然这两种图很直观,但平面图会受到截面选取的影响,而等值面图会受到等值面数值(isovalue)选取的影响,因此都有一定任意性,也不容易定量讨论。对于电子转移有比较明确方向的情况,可以绘制平面平均密度差曲线,由此可以清楚地考察垂直于选取的方向上每个截面上的密度差积分值,在定量讨论、对比上比较便利。

weixin_43948934的博客 1万+

java构造树结构

构造工具类: @UtilityClass public class TreeUtil { /** * 两层循环实现建树 * @param treeNodes 传入的树节点列表 * @return <T extends TreeNode> */ public <T extends TreeNode> List<T> build(List<T> treeNodes, Object root) { List<T> trees =

panpeichang的博客 622

三极管NPN与PNP的工作原理及快速识别技巧

本文深入浅出地解析了三极管NPN与PNP的核心工作原理。通过“水龙头”比喻,阐明其以小电流控制大电流的放大与开关本质。文章重点对比了NPN与PNP在电流方向、电位关系和控制逻辑上的根本区别,并提供了快速识别技巧与实用的选型、应用指南,帮助电子爱好者与工程师快速掌握这两种基础元件的关键知识。

neovim7hacker的博客 454

游戏资源逆向:从LUC二进制文件到可读Lua源码的完整解析

在游戏开发与资源管理领域,虚拟文件系统(VFS)是一种常见的资源打包技术,用于将大量散落的游戏资源(如脚本、纹理、音频)整合到少数几个容器文件中,以提升加载效率并增加资源提取难度。其核心原理是通过索引区记录文件元数据,数据区存储实际内容,有时还会进行压缩或加密处理。这项技术的工程价值在于优化资源分发与管理,广泛应用于客户端游戏、移动应用等场景。其中,Lua脚本常被编译为字节码(如LUC文件)以保护知识产权并提升执行速度,但这也给调试、分析与本地化带来了挑战。本文聚焦于如何逆向解析这类非标准格式,通过专用解包

weixin_30621711的博客 484

PyQt(Python+Qt)学习随笔:PyQt界面派生类构造方法中super方法的使用

老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 在《第15.7节 PyQt入门学习:PyQt5应用构建详细过程介绍》和订阅专栏《第二章、PyQt5应用构建详细过程介绍》中,老猿介绍界面派生类的构造方法如下: class MediaPlayerWin(QtWidgets.QWidget,Ui_UI_PlayerWin): def __i...

老猿Python 2711

让 ABAP Screen Variant 安稳上车:SHD0 与 SHD0_MANDT 的 Transport 全攻略

摘要: SAP项目常需优化交易码界面,通过SHD0的Transaction Variant和Screen Variant可实现字段精简、默认值预设及权限控制,避免修改标准代码。但跨系统迁移时易出现变式丢失或版本兼容问题。核心概念包括: Screen Variant:针对单个屏幕的字段属性配置(跨Client); Transaction Variant:串联多屏幕变式(分跨Client和Client-specific); 版本差异:4.70/6.x后需区分SHD0(跨Client)与SHD0_MANDT(Cl

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 230

如何利用Embedded-Product-Collect快速学习嵌入式开发:10个精选项目实战指南 [特殊字符]

嵌入式开发是当今科技领域的热门技能,但很多初学者常常面临"从何学起"的困惑。Embedded-Product-Collect嵌入式产品级项目收集库为你提供了完美的解决方案!这个开源项目汇集了25个真实的产品级嵌入式项目,覆盖了从入门到进阶的各个阶段,让你能够通过实际项目快速掌握嵌入式开发的核心技能。 ## 📊 为什么要通过实战项目学习嵌入式开发? 传统的嵌入式学习往往从理论开始,但真正的技能

gitblog_00777的博客 504

AD(十四)调用已有的PCB元件封装库

软件:Altium Designer 16 需要资料:已有的PCB原理图文件(.PCBDOC)或者PCB库文件(.PCBLIB)(来源文中细说) 调用已有的PCB元件封装库(一)从已有的PCB原理图文件(*.PCBDOC)中调用1、PCB原理图文件来源2、打开已有的PCB原理图文件(*.PCBDOC)3、生成PCB封装库4、复制封装到工程文件下的PCB库文件(*.PCBLIB)5、重名问题(二)从已有的PCB库文件(*.PCBLIB)中调用1、PCB库文件(*.PCBLIB)的来源2、打开已有的PCB库 (

Curnane0_0的博客 5083

Java零基础到就业实战路线:6阶段拆解学习路径与避坑指南

在软件开发领域,编程语言的学习路径规划是初学者面临的核心挑战。Java作为企业级应用开发的主流语言,其知识体系庞大,从基础语法到框架应用涉及多个技术层级。理解Java的核心原理,如面向对象编程、JVM内存管理等,是构建扎实技术根基的关键。掌握这些原理不仅能提升代码质量,还能为解决复杂业务场景提供理论支撑。在工程实践中,Spring Boot框架的自动配置与约定大于配置理念,极大地简化了企业级应用的开发流程,结合MyBatis或JPA等数据访问技术,可以高效实现数据持久化。对于希望快速入行的学习者,明确每个阶

weixin_34166472的博客 493

本地Pycharm连接远程服务器详细配置过程(直接在本地使用服务器显卡,很棒)

相信很多人都遇见过这种情况:实验室成员使用同一台服务器,每个人拥有自己的独立账号,我们可以使用服务器更好的配置完成实验,毕竟自己哪有money拥有自己的3090呢。

NorthSmile的博客 4万+

【大语言模型 21】语言模型训练目标:MLM vs CLM vs GLM对比分析

本文深入对比分析三种主流语言模型训练目标:掩码语言模型(MLM)、因果语言模型(CLM)和双空白填充(GLM)。通过数学推导、代码实现和实验对比,揭示不同训练目标的工作机制、适用场景和性能差异,为选择合适的预训练策略提供科学指导。

熵数实验室 1177

996引擎开发环境配置与高效工作流构建实战指南

在游戏开发工程实践中,项目配置与环境依赖管理是保障开发效率与稳定性的基础。其核心原理在于通过规范化的工具链和路径规划,解决因系统权限、资源管理和构建流程不一致引发的各类兼容性与效率问题。从技术价值看,一套健壮的开发环境能显著降低团队协作成本,加速迭代速度,并提升问题排查能力。尤其在Windows环境下,规避管理员权限陷阱和规范项目路径是保障工具链顺畅运行的关键。应用场景广泛覆盖从个人项目到团队协作的游戏开发全流程。本文聚焦于国产996引擎,系统阐述如何通过版本控制、IDE增强、资源管理优化及性能分析工具的组

weixin_30471561的博客 387

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Cocos2d-x老兵实战:从引擎原理到商业级项目优化

在游戏开发领域,引擎原理与性能优化是构建高质量应用的核心基础。理解渲染管线、内存管理机制和跨平台架构,能够帮助开发者从底层掌握技术主动权,避免成为单纯的功能调用者。Cocos2d-x作为一款经典的2D游戏引擎,其价值在于提供了对底层图形API和C++运行时的深度控制能力,尤其适合追求极致性能、包体控制和代码透明度的项目。通过系统学习其渲染优化(如Draw Call合并、纹理管理)和内存管理艺术(如引用计数、循环引用处理),开发者可以将这些通用方法论应用于实际的游戏开发中,有效解决卡顿、闪退等常见性能问题,并

weixin_30326741的博客 550

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

GDB 调试实战:5 步定位嵌入式程序数组越界与头文件缺失问题

本文详细介绍了使用GDB调试工具定位嵌入式程序中数组越界和头文件缺失问题的5步实战方法。通过冒泡排序案例,演示了从环境配置、基础调试到高级技巧的全流程,帮助开发者高效解决嵌入式系统开发中的常见问题。

weixin_33690367的博客 441

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Unity热更新安全实战:基于xLua的签名验证机制设计与实现

在移动应用开发中,热更新技术是实现快速迭代和问题修复的关键能力,它允许开发者在无需重新发布应用的情况下更新代码逻辑和资源。其核心原理是通过网络动态下载并执行新的脚本或资源包,从而绕过应用商店的审核流程。这项技术的核心价值在于极大地提升了开发效率和产品灵活性,使其成为游戏和大型应用的标准配置。然而,热更新也引入了显著的安全风险,尤其是资源在传输过程中可能被中间人攻击篡改,导致恶意代码执行或数据泄露。为了应对这一挑战,数字签名验证机制成为保障热更新安全性的基石技术。它基于非对称加密原理,通过私钥签名、公钥验签的

weixin_34284188的博客 380
上一篇: CreateRemoteThread函数多参数传入使用方法
下一篇: 一些基本排序算法的实现
Beyond我爱杨
博客等级 码龄13年 36粉丝 39原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值