文章中用纯文本制作的图不可使用等宽字体显示。请进入论坛查看本文,文中错误参考回帖,谢谢。
引用
在
函数式编程语言曲高和寡? 一文中,我们看到 Haskell 能用两行代码
sort [] = []
sort (x:xs) = sort [y | y <- xs, y < x] ++ [x] ++ sort [y | y <- xs, y >= x]
搞定快速排序算法。这是偶然,还是必然?在这篇文章中,lichray 用我们所熟悉的 Python 语言,几行代码搞定很多学编程几年的人都只是一知半解的算法——八皇后问题,展示和上篇文章中的快速排序一样清晰的、令人耳目一新的
函数式算法思想。
预备知识:
这一部分对于那些 Python 老手和已经知道八皇后问题定义的程序员来说是多余的。
1. 八皇后问题(摘自 SICP ed2 中文版 P84 练习2.42)
“八皇后谜题”问的是怎样将八个皇后摆在国际象棋棋盘上,使得任意一个皇后都不能攻击另一个皇后(也就是说,任意两个皇后都不在同一行、同一列或者同一对角线上)。一个可能的解如图所示。
┌──┬──┬──┬──┬──┬──┬──┬──┐
│ │ │ │ │ │ Q │ │ │
├──┼──┼──┼──┼──┼──┼──┼──┤
│ │ │ Q │ │ │ │ │ │
├──┼──┼──┼──┼──┼──┼──┼──┤
│ Q │ │ │ │ │ │ │ │
├──┼──┼──┼──┼──┼──┼──┼──┤
│ │ │ │ │ │ │ Q │ │
├──┼──┼──┼──┼──┼──┼──┼──┤
│ │ │ │ │ Q │ │ │ │
├──┼──┼──┼──┼──┼──┼──┼──┤
│ │ │ │ │ │ │ │ Q │
├──┼──┼──┼──┼──┼──┼──┼──┤
│ │ Q │ │ │ │ │ │ │
├──┼──┼──┼──┼──┼──┼──┼──┤
│ │ │ │ Q │ │ │ │ │
└──┴──┴──┴──┴──┴──┴──┴──┘
在这篇文章中,我们要解决的问题比这个范围还要更广一点,即:允许棋盘是 n × m 大小的。也就是说,所谓的 n 皇后问题只是我们给出的程序的 n = m 时的版本。不过别担心,
函数式编程的力量就在于抽象等级的空前提高,问题越抽象,解决起来越顺手。
2. 列表领悟特性
现在应该绝大多数动态语言的程序员都对这个特性很了解了,因为常见的 Python, Ruby, ErLang, Haskell 甚至是 JavaScript 都加上了这个特性。这是一种通过给出列表中
每一项的形式和组成形式的元素要满足的条件自动生成列表的语法糖。下面是 Python 中的两个例子:
# 得到一个 2 到 20 中的偶数组成的列表,只要写
>>> [x for x in range(2, 21) if x % 2 == 0]
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
# 记住,只需给出一个形式,比方说想求两个列表的“笛卡尔乘积”
>>> [(x , y) for x in range(4) for y in [3,1,7,8]]
很明显,仅仅使用列表领悟特性就可以表示一些算法了,比如提到过的快速排序:
def sort (ls):
return [] if ls == [] \
else sort([y for y in ls[1:] if y < ls[0]]) + \
[ls[0]] + \
sort([y for y in ls[1:] if y >= ls[0]])
# 别忘了 python-2.5 的新特性条件分支表达式哦!可惜太长,不得不强制换行。
但要注意一点:
实现拙劣的多未知数列表领悟(比如 Python)可能会崩了你的程序,文中会谈到这一点。
算法描述:
首先我们要认识到一点,算法所对应的函数的输入和输出分别是什么。我们需要的是一个函数 queens(),它接受两个参数,
自然数 row 和 col,分别表示行数和列数;坐标是 (col, row) 形式的序对,下标 从 0 开始计数。例如,对于一个 3 × 4 的棋盘,
┌──┬──┬──┬──┐
│0, 0│1, 0 │ │ │
├──┼──┼──┼──┤
│ │ Q │2, 1│ │ row = 3
├──┼──┼──┼──┤
│ │ │2, 2│ │
└──┴──┴──┴──┘
col = 4
我们把输出的结果表示为棋盘格局描述组成的列表。那棋盘格局呢?难道表示为所有棋子的坐标,像 [(5,0), (2,1), (0,2),(6,3), (4,4), (7,5), (1,6), (3,7)] ?不需要吧,看也能看出来,完全可以使得下标 col、row 中有一个是有序排列的。在这里,我们
认为 row 是有序的,对于上面的例子,只须表示为 [5, 2, 0, 6, 4, 7, 1, 3] 即可,row 是一个解的下标。
那么,整个函数的输出就应该类似这样:[[1, 3, 0, 2], [2, 0, 3, 1]];这是 queens(4,4) 的输出结果。
归纳法定义:
什么是归纳法定义?回忆一下经典的求级数例程是怎么写出来的。我们根据数学归纳法得到:
f (0) = 1
f (n) = 1 +
f (n - 1)
然后把这些抄成编程语言的形式。对于函数 queens 也是这样,我们要确定这个函数的递归下界和递推表示。
递归下界很好办,就是 queens(n,0) (此处 n 忽略,因为不影响结果)的输出结果。对于一个没有列数的棋盘,只有一个解,空解 [];同时,输出的
解集也只有这一个元素,为 [[]](下面的数学定义使用了集合表示代替列表)。
f (*,0) = {{}}
递推表示是什么呢?我们可以在纸上画画图,不难发现,对于一个解,你画出的最后一个位置就是在前面已画出的
少一个棋子的格局的基础上再
加一个位置
安全的棋子。设这个“加”函数为
g (x,y),“安全”函数为
s (x,y)。那么
f (n,m) = {
g (x,y) | x ∈ [0, n], y ∈
f (n,m-1)
s (x,y) =
true}
形式化的思考:
有了上面的数学定义,抄成 Python 代码,那就是用脚趾都能搞定呀。
def queens (row, col):
return [[]] if col == 0 \
else [[ran] + rst \ # 在 Python 中,g(x,y)=[x]+y
for ran in range(row) \
for rst in queens(row, col - 1) \
if safe(ran, rst)]
不难看出,有了列表领悟这个强大的武器,我们就可以放心大胆地利用描述一个元素形式的思路来解决这类列表输出的问题。这就是列表领悟最根本的思想:“形式化的思维方式”。
现在只剩一个问题了:safe() 函数。先应用一次我们的“图形化的思考”。对一个格局(解,rst)来说,新加入的棋子的 col 值 ran 必须对这个格局中所有已存在的
位置满足一个测试 check(),这个测试对于一个位置 (x,y),要求(col 值不等已自动满足) ran ≠ x and |ran - x| ≠ y + 1。
ran ≠ x 很好理解,就是不为同一列;|ran - x| ≠ y + 1 则意味着左右不在同一斜线上。
┌──┬──┬──┬──┐
│ │ran │ │ │ 0
├──┼──┼──┼──┤
│x1y │ │ │ Q │ 1
├──┼──┼──┼──┤
│ Q │ │ │x2y │ 2
├──┼──┼──┼──┤
│ │ │ Q │ │ 3
└──┴──┴──┴──┘
0 1 2 3
如图,算一算图中的两个点 (x1,y) 和 (x2,y),是不是满足了上面的式子?
由于这里要同时用到 rst 中点的 col 值和 row 值,这样解决:在前文的
算法描述中已经指出,因为 row 值被认为是有序的,事实上是一个解的下标,我们 check 一下这个下标,在 check() 的过程中去获取 col 值不就行了?
def check (pos):
# 表达式变个形式,少打点字
return not (ran == rst[pos] or abs(ran - rst[pos]) == pos + 1)
值得注意的是,由于这里 check() 用到了逃逸变量 ran 和 rst,check 函数体就必须写在 safe() 函数体内部以使这它们在其
闭包环境中出现。
safe() 函数也就很明了了:先生成一个由全部 check(pos), pos ∈ [0, #rst] 结果组成的列表,然后判断一下这个列表中每一项是否都为真。假设我们已得到这样的一种测试一个列表中元素是否全为 True 的函数叫 ands()。
def safe (ran, rst):
def check (pos):
return not (ran == rst[pos] or abs(ran - rst[pos]) == pos + 1)
return ands([check(pos) for pos in range(len(rst))])
前文已经说明,ands() 函数接受一个列表为参数,如果列表中每一项都为 True 则返回 True,否则返回 False。还是直接把数学定义抄一遍:
def ands (ls):
return True if ls == [] \
else (False if not ls[0] \
else ands(ls[1:]))
于是,我们的程序就写完啦!试着跑一下 queens(4,4),
>>> queens(4,4)
[[1, 3, 0, 2], [2, 0, 3, 1]]
没问题!再跑一下 queens(8,8)!奇怪,为什么跑了 10 分钟还没出结果?
问题在哪儿:
拙劣的列表领悟实现。Python 在处理列表领悟时,一方面把“形式”部分封装为一个函数,然后找出所有未知数的列表,组装成一个大的矩阵,然后对矩阵中的每一项应用该函数。问题出在哪儿?先生成了所有项,占用了过多的空间。如果在 Haskell 里面,这样做是无所谓的,因为惰性的列表会生成一点,计算一点,抛弃一点,输出一点;
但这对于严格(采用应用序求值)的命令式语言 Python 来说,这种实现仅仅是玩具级的。
其实,列表领悟不仅仅是一个语法糖,在严格的语言实现它需要一定技巧:首先分析未知数对于的列表的计算所消耗时间(数据流分析 call 的次数),把计算耗时最多的列表应用群体操作,对结果的每一项应用产生下一个列表的群体操作,依此类推,
只要产生一个包含所有未知数的序对就应用包装好的函数。空泛的讲这些用处不大,下面我们手工把这个该死的程序救活。
通用列表操作:
关键在于处理掉这一句:
[[ran] + rst \
for ran in range(row) \
for rst in queens(row, col - 1) \
if safe(ran, rst)]
首先对最耗时的列表 queens(row, col - 1) 应用群体操作 flatmap(newcol, queens(row, col - 1))。这里需要注意的是,光用 map() 是不够的,因为下面会根据另一个列表 rang(row) 中的每一项产生一个新列表,导致
多出一个列表层。所以我们需要用 flatmap() 函数,它在普通的 map() 操作之后会用 append() 把产生的列表联结起来(所以叫“展平”的 map),把多出的一层列表消去:
def flatmap (opt, ls):
# 小技巧:累积器在连接列表时可以不用 lambda x,y: x+y,直接用 list.__add__,
# 重点是类型出错时有报警
return reduce(list.__add__, map(opt, ls))
接下来,根据列表和列表生成列表(在通用列表操作的世界中,就是 list, list, and list),注意原来的形式 [ran] + rst 是怎么被函数封装掉的:
def newcol (rst):
# 顺手解决 filter 只能传递一个参数的限制,用 lambda 代掉
return filter(lambda ls: safe(ls[0], rst), map(lambda x: [x] + rst, range(row)))
其它什么内容都不用改了(当然了,如果你有心情,还可以把另一个列表领悟替换掉,
def safe (ran, rst):
return every(check, range(len(rst)))
# every() 函数相当于打过兴奋剂的 ands
def every (test, ls):
return True if ls == [] \
else (False if not test(ls[0]) \
else every(test, ls[1:]))
不过单层的列表领悟没有性能问题)。现在可以完美地输出八皇后问题的 92 个解了(这里就不列了,太长了)。
反思:
- 函数式编程的思想描述算法绝对强,无论是列表领悟还是通用列表操作都十分清晰,仿佛能感受到数据在表达式间游动;
- 和平起见,就不把我那个传说中的只有一行代码的版本拿来和几十行的命令式风格的代码比较了,但大家应该心领神会;
- 有时候,把问题想的简单一些,思维更“形而上学”一些,反而能更快的得到解决问题的思路,顺着思路再改进也不迟;
- Python 的表达式版的分支语句很漂亮,但被该死的换行限制给玷污了;另外列表领悟实现得够烂,眼下只能是玩玩儿。
最后留个小问题:我们在
算法描述一节中提到了一种解的表示方法,把一个格局中所有棋子的坐标表示为序对,然后返回解的列表。请给出一个小函数,把我们现在的实现版本输出的解转换为这种形式。数据的本质是信息。信息的完全是首要的,数据的表示只是个次要问题。
- queen8.zip (478 Bytes)
- 描述: 这是我写的完整代码,和文中略有出入。PS: 文中的“图”不可用等宽字体查看。
- 下载次数: 340
分享到:
相关推荐
《八数码问题与IDA*算法实现详解》 八数码问题,又称滑动拼图或九宫格游戏,是计算机科学中一个经典的搜索问题。玩家需要通过最少的移动次数,将初始状态的九宫格恢复到目标状态。在这个过程中,IDA*(Iterative ...
# 压缩文件中包含: 中文文档 jar包下载地址 Maven依赖 Gradle依赖 源代码下载地址 # 本文件关键字: jar中文文档.zip,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压最外层zip,再解压其中的zip包,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作,请放心使用。 ·只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; ·不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 # 温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件;
scratch少儿编程逻辑思维游戏源码-光线投射引擎 v0.9.zip
内容概要:本文详细介绍了基于S7-1200 PLC的一拖三恒压供水系统,涵盖PLC程序、PID控制、触摸屏界面及项目图纸等方面。PLC程序方面,重点讲解了PID控制功能块的应用及其参数配置,确保系统能够根据设定值和实际测量值调整输出,保持供水压力恒定。触摸屏程序提供了直观的操作界面,允许操作人员实时监控和调整系统参数。项目图纸展示了详细的硬件连接和布线方式,有助于理解和实施系统安装与调试。此外,文中还分享了许多调试经验和注意事项,如PID参数整定、泵组切换逻辑、报警处理机制等。 适合人群:从事自动化控制系统设计、调试的技术人员,尤其是对PLC编程和PID控制感兴趣的工程师。 使用场景及目标:适用于工业现场的恒压供水系统设计与实现,旨在提高系统的稳定性和效率,减少维护成本。通过学习本文,读者可以掌握S7-1200 PLC编程技巧、PID控制原理及触摸屏应用方法。 其他说明:本文不仅提供了理论知识,还包括大量的实战经验和调试技巧,帮助读者更好地理解和应用相关技术。
# 压缩文件中包含: 中文文档 jar包下载地址 Maven依赖 Gradle依赖 源代码下载地址 # 本文件关键字: jar中文文档.zip,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压最外层zip,再解压其中的zip包,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作,请放心使用。 ·只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; ·不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 # 温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件;
网络仿真与自动化_华为ENSP模拟器_MobaXterm会话管理_Python脚本自动化生成Telnet会话文件_用于批量创建连接ENSP设备的MobaXterm会话_自动解析拓扑
内容概要:本文详细介绍了使用KGDB(Kernel GNU Debugger)调试Linux内核的方法及其重要性。文章首先强调了Linux内核作为系统核心的重要性及其调试的必要性,随后介绍了KGDB的基本原理和优势,包括其基于调试stub和GDB串行协议的工作机制。接着,文章详细描述了使用KGDB调试内核的具体步骤,包括准备工作、内核配置、设置启动参数、建立调试连接和进行调试操作。文中还通过一个实战案例展示了KGDB在解决实际问题中的应用,并总结了使用KGDB时的注意事项和常见问题的解决方法。最后,文章展望了KGDB未来的发展方向和应用场景,如优化调试性能、支持新型硬件架构以及在嵌入式系统、云计算和大数据领域的应用。 适合人群:具备一定Linux系统开发经验的研发人员,尤其是那些需要调试和优化Linux内核的工程师。 使用场景及目标:①帮助开发者深入了解Linux内核的运行状态,精准定位并修复内核问题;②优化内核性能,提高系统的稳定性和可靠性;③适用于嵌入式系统开发、远程服务器维护等场景,特别是在硬件资源有限或无法直接接触设备的情况下。 其他说明:在使用KGDB进行调试时,需特别注意串口设置的一致性、内核版本的兼容性以及调试信息的完整性。同时,要解决常见的连接失败、断点无效等问题,确保调试过程顺利进行。未来,KGDB有望在技术上不断优化,并拓展到更多应用场景中,为Linux系统的持续发展提供支持。
内容概要:本文深入剖析了一款基于STM32F407的CNC雕刻机控制系统,涵盖硬件原理图和源码实现。首先介绍了步进电机驱动部分,详细解释了XYZ三轴的方向引脚配置及时序控制,确保电机平稳运行。接着讨论了PWM脉冲生成的核心配置,通过定时器精确控制雕刻精度,并解决了高速雕刻时的脉冲丢失问题。串口通信部分采用DMA+空闲中断,显著提升了数据处理效率。运动插补算法利用定时器触发DMA传输脉冲,实现高效的三轴联动。此外,文中还涉及了G代码解析、运动前瞻算法以及硬件设计中的防呆措施,如IO口的TVS二极管和RC滤波。最后,分享了一些调试经验和隐藏的开发彩蛋,如通过LED灯效显示工作状态和电流检测实现堵转保护。 适合人群:具备嵌入式开发基础,尤其是对STM32和CNC雕刻机感兴趣的开发者和技术爱好者。 使用场景及目标:①帮助开发者理解和实现CNC雕刻机的控制系统;②提供详细的硬件和软件设计方案,便于动手制作;③分享调试技巧和实战经验,提高系统的稳定性和可靠性。 阅读建议:本文不仅提供了详细的代码实现和硬件设计,还包括了许多实战经验和调试技巧,因此在阅读过程中应重点关注这些细节,并尝试复现相关功能。
# 压缩文件中包含: 中文文档 jar包下载地址 Maven依赖 Gradle依赖 源代码下载地址 # 本文件关键字: jar中文文档.zip,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压最外层zip,再解压其中的zip包,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作,请放心使用。 ·只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; ·不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 # 温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件;
内容概要:本文详细介绍了如何使用MATLAB实现ELMAN神经网络进行时间序列预测。首先讲解了如何读取本地Excel数据,并进行了必要的数据预处理,如转置和归一化。接着,构建了ELMAN网络,设置了训练参数,并进行了模型训练。随后,展示了如何进行预测并将结果反归一化,以及如何通过可视化手段评估预测效果。文中还提供了多个调试技巧,帮助解决常见的新手问题。 适合人群:具备基本MATLAB编程能力,希望学习时间序列预测的新手。 使用场景及目标:适用于需要进行时间序列数据分析和预测的研究人员或工程师,目标是掌握ELMAN神经网络的基本原理及其在MATLAB中的具体实现方法。 其他说明:本文不仅提供完整的代码示例,还包括了许多实用的小贴士,如数据读取、归一化、网络结构调整等,帮助读者更快地上手并解决问题。
winmm简谱播放器3音轨程序代码ZXQZQ-2025-5-4
scratch少儿编程逻辑思维游戏源码-鼓手猴子.zip
# 压缩文件中包含: 中文-英文对照文档 jar包下载地址 Maven依赖 Gradle依赖 源代码下载地址 # 本文件关键字: jar中文-英文对照文档.zip,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压最外层zip,再解压其中的zip包,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作,请放心使用。 ·只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; ·不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 # 温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件;
内容概要:本文详细介绍了如何使用MATLAB实现改进二进制粒子群算法来解决含需求响应的机组组合问题。文章首先构建了机组组合问题的基本模型,定义了机组的数量及其最小和最大发电功率等参数。接着,在此基础上加入了需求响应机制,通过设置需求响应的最大可削减负荷量和补偿系数,实现了对负荷侧的管理。为了提高求解效率,采用了一种改进的二进制粒子群算法,该算法通过独特的更新策略使粒子更快更准地找到最优解。此外,还讨论了微电网调度中如何降低发电成本并确保供电稳定性,强调了需求响应在优化调度中的重要性。 适合人群:对电力系统优化、机组组合问题、需求响应机制以及改进粒子群算法感兴趣的科研人员和技术开发者。 使用场景及目标:适用于需要优化电力系统调度的研究项目或实际工程应用,旨在通过引入需求响应机制和改进的粒子群算法,降低发电成本,提高系统的灵活性和经济效益。 其他说明:文中提供的MATLAB代码示例有助于理解和复现算法的具体实现,同时提醒了一些常见的陷阱和注意事项,如负荷预测误差的影响和合理的参数选择。
内容概要:本文详细介绍了威纶触摸屏与台达变频器通过RS485通讯实现控制与监视的方法。首先,文章解释了MODBUS RTU协议的基础,包括读写指令的数据帧格式。接着,描述了威纶触摸屏和台达变频器的通讯参数设置步骤,确保双方参数一致。随后,提供了具体的Lua脚本代码示例,展示了如何通过写入特定寄存器来控制变频器的启动、正反转、点动、停止等功能,以及如何读取变频器的频率、电流、电压等运行参数。此外,还提到了一些常见的调试技巧和注意事项,如数据类型的正确转换、线序连接、通讯超时处理等。 适合人群:从事自动化控制系统开发的技术人员,尤其是熟悉威纶触摸屏和台达变频器的工程师。 使用场景及目标:适用于需要通过RS485通讯接口实现威纶触摸屏对台达变频器进行远程控制和实时监测的应用场景。主要目标是提高系统的自动化程度和可靠性,减少人工干预。 其他说明:文中提供的代码和配置方法可以直接应用于实际项目中,但在具体应用时需要注意不同型号设备的具体参数差异。调试过程中可以借助串口助手等工具进行辅助验证。
内容概要:本文详细介绍了基于UWB(超宽带)技术的多设备测距系统的设计与实现。主要内容涵盖设备ID管理、双向测距(TWR)算法、温度补偿、功耗优化、串口通信协议设计等方面。文中提供了具体的C语言代码片段,展示了如何通过宏定义控制设备类型,利用位操作高效管理设备ID,采用双向测距算法提高测距精度,通过加速度计动态调整测距频率以优化功耗,以及设计轻量级串口通信协议确保数据传输可靠性。此外,还讨论了一些常见的烧录和调试问题及其解决方案。 适合人群:具有一定嵌入式开发经验的研发人员,特别是从事无线通信、室内定位系统开发的技术人员。 使用场景及目标:适用于需要实现高精度室内定位系统的开发者,帮助他们理解和掌握UWB模块的工作原理及其实现细节,从而能够构建稳定的多设备测距系统。 其他说明:文中提到的具体实现方法和技术细节对于理解和优化UWB模块的应用非常有价值,尤其是关于设备管理和测距算法的部分。同时,文中提供的代码片段可以直接用于实际项目中,加快开发进度并提高系统的稳定性。
即时通讯_分布式系统_WebSocket_Golang_Redis_MySQL_RabbitMQ_Gin_Logrus_Docker_微服务架构_高并发_消息队列_实时聊天_多节点
# 压缩文件中包含: 中文-英文对照文档 jar包下载地址 Maven依赖 Gradle依赖 源代码下载地址 # 本文件关键字: jar中文-英文对照文档.zip,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压最外层zip,再解压其中的zip包,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作,请放心使用。 ·只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; ·不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 # 温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件;
# 压缩文件中包含: 中文文档 jar包下载地址 Maven依赖 Gradle依赖 源代码下载地址 # 本文件关键字: jar中文文档.zip,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压最外层zip,再解压其中的zip包,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作,请放心使用。 ·只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; ·不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 # 温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件;