基于 double array 实现汉字的trie树索引 与 查询功能 python实现

PYNLPL:轻量确定性NLP工具在资源受限与合规场景中的实践 在自然语言处理领域,'确定性NLP'正成为嵌入式系统、金融审计、政务OCR等强监管与资源受限场景的关键需求。区别于依赖深度学习模型的主流框架,确定性NLP强调结果可复现、零外部依赖、低内存占用与跨平台一致性。其技术原理根植于有限状态自动机(FSM)、双数组Trie(DAT)词典、Unicode位图分类及纯规则驱动的分词与标注机制。这类方案不追求统计意义上的最高准确率,而保障100%可验证的行为边界与硬实时响应能力,天然适配离线部署、信创环境、C++/Rust混合工程及WebAssembly扩展。本文以PYN 阅读详情

一、 基本原理。

基本原理:利用字符串集合中字符串的公共前缀来降低时间开销以达到提高效率的目的。

性质:1,根结点不包含任何字符信息;2,如果字符的种数为n(如英文的26个字母),则每个结点的出度为n(这样必然会导致浪费很多空间,这也是trie的缺点,我还没有想到好点的办法避免);3,查找,插入复杂度为O(n),n为字符串长度。

具体请百度之。



二、基于 trie字典的汉字串检索代码(python):

# coding=gbk
dicts = ['啊','阿根廷','阿胶','阿拉伯','阿拉伯人','埃及']
# 字后缀数组
sufarr = {'啊':[],'阿':['根','胶','拉'],'埃':['及'],
          '根':['廷'],'胶':[],'拉':['伯'],'及':[],
          '廷':[],'伯':['人'],'人':[]}
# 按ID编码
codes = [ '啊','阿','埃','根','胶','拉','及','廷','伯','人' ]
# 字的层次标示
level = [1, 1, 1, 2, 2, 2, 2, 3, 3, 4]

# 构建双数组
base = [0]*21           # len:21 ; 21=2*10+1 的素数
check = [0]*21
# 记录已确定的字的base索引
bid_mark = {'啊':0,'阿':1,'埃':2, '根':0,'胶':0,'拉':0,'及':0,'廷':0,'伯':0,'人':0}
base[:3]=[1]*3          # 首字部分,简单置为1
def pre_mark(pre_word,wi,word):
    ''' 判断base中wi下标的前缀都在pre_words词表直到首字 且word为wi下标对应的字 '''
    bkeys = bid_mark.keys()    
    if word not in bkeys or bid_mark[word]!=wi:             # 当前字的base值不匹配
        return False
    pre_wi = check[wi]                     # 逆序遍历base的前缀
    pid = -1                               # 逆序遍历字的前缀 
    while pre_wi!=0 and (-1)*pid<=len(pre_word):
        if pre_word[pid] not in bkeys or bid_mark[pre_word[pid]]!=pre_wi:
            return False
        pre_wi = check[pre_wi]
        pid -= 1
    if (-1)*pid>len(pre_word): return True # 完成前缀的遍历
    else: return False

for w in dicts:         
    cw = [ w[i:i+2] for i in range(0,len(w),2) ]            # 分割出字
    for iid in range(1,len(cw)):
        par_w = cw[iid-1]                   # 字的前缀
        iid_w = cw[iid]                     # 当前的字
        par_id = codes.index(par_w)         # 字的前缀的编码
        wid = codes.index(iid_w)
        bval = bid_mark[par_w]
        #if iid_w=='及': print "ID: %d, word: %s, pre-wrod: %s, code: %d, pre-code: %d, pre-base:%d"%(
        #    iid,iid_w,par_w,wid,par_id,bval)
        for wi in range(base[bval]+wid,21):   # 遍历所有可能的base位置
            # 找到其base-id,置位
            p_mk = pre_mark(cw[:iid],wi,iid_w)  
            print "TEST::pre_mark() base-id: %d, word: %s, result: %s"%(wi,iid_w,str(p_mk))
            if p_mk:                              # 该词及其前缀部分已经设置值
                break
            if (not base[wi] and not check[wi]):  # 该位置未使用或吻合前缀
                check[wi] = bval 
                # 设置字的 base[] 值
                for tval in range(1,21-wi):    # 遍历所有可能的取值
                    flag = True
                    for suf_w in sufarr[iid_w]:
                        chi_id = codes.index(suf_w)     # 字的后缀的编码
                        if  base[tval+chi_id]!=0 or check[tval+chi_id]!=0:
                            flag = False
                            break              # tval不满足child的base check 为0,再尝试其他值
                    if flag:
                        base[wi] = tval        # 成功,保存该base[]
                        if wi==6 or wi==-1 or wi==9:
                            print "ID: %d, word: %s, pre-word: %s, base: %d, base-val: %d, check: %d"%(
                                iid,iid_w,par_w,wi,tval,check[wi])
                        break
                if not base[wi]:               # 无合适的 base 
                    print "ERROR:: set %s's base[]" % iid_w
                    exit(1)
                bid_mark[iid_w] = wi #; print "finnished one! %s=%d" % (iid_w,wi)
                break                          # base check均成功
        if not base[wi]: 
            print "ERROR:: get %s's position in base[]" % iid_w
            exit(2)

# 修改词尾标志
for w in bid_mark.keys():
    if len(sufarr[w])==0:
        eid = bid_mark[w]
        base[eid] *= -1

# 查询给定词    
def next_check(wid, code):
    ''' 验证两个base[]索引id间是否有连接 '''
    if code<0 or code>=len(codes):          # 字编码无效
        return False
    chiid = abs(base[wid])+code
    if check[chiid]!=wid:
        return False
    return True
qw = dicts[1] ;     # 查询词
res = ''            # 返回结果
words=[ qw[w:w+2] for w in range(0,len(qw),2) ]
head_bid = bid_mark[words[0]] ; res = ''.join(words[0])
for w in words[1:]:
    cod = codes.index(w)
    if not next_check(head_bid,cod):
        print "word: %s no find!" % qw
        break
    head_bid = abs(base[head_bid])+cod      # 更新id
    res = ''.join([res,w])
    if base[head_bid]<0:
        print "find a word: %s in Search word: %s"%(res,qw)    

           
参考: http://blog.youkuaiyun.com/joylnwang/article/details/6825991





嵌入式显示开发实战:从图像取模到DMA驱动的全流程优化 在嵌入式系统开发中,图形显示是连接硬件与用户界面的关键技术。其核心原理在于将图像数据转换为屏幕控制器可识别的格式,并通过总线协议高效传输。这项技术的价值在于以有限的硬件资源实现流畅、稳定的视觉输出,是提升产品交互体验的关键。在物联网设备、工业HMI和消费电子等应用场景中,优化显示流程能显著降低CPU负载并提高刷新效率。本文聚焦于嵌入式显示开发的完整流水线,针对单色OLED和彩色LCD,深入探讨了使用Img2Lcd等工具进行图像取模的参数配置、常量数据在Flash中的存储优化,以及如何利用STM32的DMA( 阅读详情

相关推荐

【16】linux命令/工具,systemd,文件操作,动静态库,信号,socket

apt install python3-pip --fix-missing(断开vpn,cp /etc/apt/sources.list /etc/apt/sources.list.bak,python3 -m pip install --upgrade pip,apt-get update,pip install 包名 -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com)设置时间,联网,apt-get install vim。

持续更新ing... 6788

python版本的双数组trie树使用学习笔记 (double array trie ;DATrie)

#pip install datrie import string import datrie trie = datrie.Trie(string.ascii_lowercase) trie[u'foo'] = 5 trie[u'foobar'] = 10 trie[u'bar'] = 'bar value' trie.setdefault(u'foobar', 15) print(u'foo' in trie) #查找单词的所有前缀: print(trie.prefixes(u'foobarb...

samoyan的博客,记录技术成长~ 1268

基于双数组Trie_树中文分词研究

对双数纽Trie 树(Double-Array Trie)分词算法进行了优化:在采用Trie 树构造 双数纽Trie 树的过程中,优先处理分支节点多的结点,以减少冲突;构造一个空状态序列; 将冲突的结点放入Hash表中,不需要重新分配结点.然后,利用这些方法构造了一个中文 分词系统,并与其他几种分词方法进行对比,结果表明,优化后的双数纽Trie 树插入速度和 空间利用率得到了很大提高,且分词查询效率也得到了提高.

python实现Trie 树+朴素匹配字符串+RK算法匹配字符串+kmp算法匹配字符串

一.trie树应用: 常用于搜索提示,如当输入一个网址,可以自动搜索出可能的选择。当没有完全匹配的搜索结果,可以返回前缀最相似的可能。 例如三个单词app, apple, add,我们按照以下规则创建了一颗Trie树.对于从树的根结点走到黑色结点的路径上的字母依次组合起来就是一个完整的单词. class Trie: # word_end = -1 def __init__...

智障变智能 1762

DoubleArrayTrie:双端trie树的python实现

DoubleArrayTrie 双端trie树的python实现 版本翻译于 将其改写成python3.5版本 最主要的贡献是 —— 1:实现了其模糊查询的功能;2:自定义编码值,解决双端trie树需要预定义字母表的问题 另外,有实现了字典Trie树,字典Trie树构建简单、模糊查找功能实现容易,无需状态记录;其与双数组Tire可以说在功能上互补; 在存储值很多且多有冲突、字符编码范围较大的情况下,双数组Trie树很可能在序列化到硬盘以及加载到内存的占用空间都远大于字典Trie树

Algorithm-AhoCorasickDoubleArrayTrie.zip

Algorithm-AhoCorasickDoubleArrayTrie.zip,基于双数组trie的aho-corasick算法的快速实现。,算法是为计算机程序高效、彻底地完成任务而创建的一组详细的准则。

trie(字典树)的双数组实现

trie的双数组实现是为了减少空间复杂度。 http://www.cnblogs.com/cuberub/archive/2012/03/24/2416195.html http://hi.baidu.com/%CF%B5%B4%C7%CF%C2%B4%CE/blog/item/3ae945d5368db9c5572c84e8.html http://linux.thai.net/~

train的专栏 3835

double-array-trie原理与算法

double-array-trie原理与算法实现探索,dat算法分析

Trie树在多语言文本处理中的优化与应用

Trie树(前缀树)是一种高效处理字符串匹配的数据结构,通过共享公共前缀来组织数据,显著提升文本处理效率。其核心原理是将每个字符作为节点,路径构成字符串前缀,特别适合实现自动补全、敏感词过滤等功能。在工程实践中,Trie树面临多语言字符编码(如UTF-8/UTF-32)、内存优化等挑战,常用双数组Trie、后缀压缩等技术降低内存消耗。典型应用场景包括智能输入法词频预测、多语言敏感词过滤系统等,其中Unicode编码处理和内存优化策略尤为关键。随着全球化应用增多,支持中文、阿拉伯语等复杂语言特性的Trie树优

weixin_30596023的博客 345

DoubleArrayTrie(双数组Trie树)

关于本源码更详细的解释说明,请参见:http://blog.youkuaiyun.com/lemon_tree12138/article/details/49281865

LangChain Agent Skills 实战指南:12个案例玩转智能体技能封装与编排

大语言模型应用开发中,智能体(Agent)的能力扩展正从零散的函数调用走向标准化封装。Agent Skills 将某项具体能力组织为带说明、代码与依赖的技能目录,让模型能自动发现和调度,其核心价值在于解决工具数量膨胀后的维护混乱与调用失控问题。与 Tool 的单一执行、MCP 的协议连接不同,Skill 更强调能力的语义描述与组合复用,配合 LangGraph 的状态编排和 LangSmith 的可观测性,可构建生产级智能体系统。在实际场景中,Agent Skills 可覆盖 RAG 知识库问答、多轮记忆保

weixin_34335458的博客 407

C++实现中文分词器:从Trie树、动态规划到HMM的完整工程实践

自然语言处理(NLP)是人工智能领域的关键技术,而中文分词是几乎所有中文NLP任务的基础前置步骤,其核心目标是将连续的汉字序列切分为有意义的词语序列。其基本原理结合了词典匹配与统计模型,通过构建高效的数据结构(如Trie树)存储词典,并利用动态规划算法在有向无环图(DAG)中寻找最优切分路径,以解决组合爆炸问题。对于未登录词,则依赖隐马尔可夫模型(HMM)等统计方法进行序列标注和识别。在工程实践中,采用C++实现能深入掌控内存管理、算法效率与多线程优化,例如通过**Trie树**加速词典查询,并运用**动态

weixin_34384681的博客 384

PSO算法介绍

结合网上的文章对PSO进行一些介绍,并附上自己复现的算法。

Witty_Hou的博客 1万+

Modern C++高性能NLP词表设计与实现

词表(Vocabulary)是NLP流水线的前置核心组件,其构建与查询效率直接影响端到端推理性能。传统方案依赖Python绑定或通用容器,存在内存不可控、零拷贝缺失、运行时解析开销大等瓶颈;而Modern C++凭借std::string_view、constexpr、concepts、memory_resource等特性,可实现编译期词表预加载、无锁DAT查询、线程局部内存池及二进制镜像mmap加载,显著提升Tokenization的吞吐与确定性。本文围绕Vocabulary和Tokenization两大

weixin_30608503的博客 488

UM2 3D 打印机 DIY 实践 (2) 电路篇

涉及到的东西非常多,实际上后面还会讲到。主要部件清单: 主板 mega2560 + Ramps1.4 + LCD12864 各一张 42 x38mm x3,xyz 轴各一台 42 x23mm x1,用在挤出机 泰坦远程挤出机 x1 TMC2225 驱动板 x4, 替代a4988、TMC2208,静音效果好,性价比高 s-250-12v 20A开关电源 x1。功率必须足够大,宁可选大一点的 大功率 MOS 管,25A x1 NTC .

afeiqiang的专栏 3601

信号完整性分析学习--16--传输线效应

传输线效应 说到传输线效应,大多数人都会想到一个经验法则,那就是: “当互连线的长度大于1/6倍的信号上升时间的空间延伸时,互连线就体现出传输线效应。” 上升时间越小越容易体现传输线效应。 由此可见,同一根互连线,它是否体现传输线效应,要看它要传输什么样的信号。下图所示,一根延时为15ps的互连线,当它传输上升时间为60ps的信号时就会体现传输线效应;当它传输上升时间为180ps的信号时就不体现传输线效应。

qq_29476769的博客 7274

python笔记

my_name='陈志隆'print('luck_number的数据类型是',type(luck_number))# python 可以动态修改变量的数据类型 通过赋不同类型的值,就可以修改luck_number='北京欢迎你'# python中允许多个变量指向同一个值运行后输出如下:D:\Anaconda\envs\run\python.exe D:\Pycharm\Project\Basic\示例3-3变量的定义和使用.pyluck_number的数据类型是 <class 'int'>

weixin_55944609的博客 137

Altium Designer(AD)PCB拼版——两种方法教程

本文详细介绍了PCB拼版的设计要点与操作方法。主要内容包括:拼版目的(解决小尺寸夹持问题、提高利用率、降低成本)和三大连接方式(V-CUT、邮票孔、空心连接条)的特点与参数设置;工艺边设计规范(宽度、定位孔、Mark点等要求);拼版尺寸限制与常见错误检查;以及两种具体拼版操作方法(特殊粘贴和拼版阵列),并附有工艺边、定位孔、Mark点的绘制步骤示意图。同时提供了硬件工程师笔试面试相关资源链接。全文系统阐述了PCB拼版的核心技术和操作流程,为电子设计人员提供了实用指导。

XU157303764的博客 7599

MOE词向量:专治拼写错误的轻量级鲁棒嵌入方案

词向量是自然语言处理的基础表征技术,其核心目标是将词汇映射为稠密、语义可计算的向量。传统方法如Word2Vec和GloVe依赖固定词表,面对用户生成内容(UGC)中高频出现的拼写错误(如recieve/receive)、OCR识别噪声或网络缩写(thx/b4),极易产生未知词(OOV)问题,导致下游任务性能断崖式下降。MOE(Misspelling Oblivious Embeddings)通过子词分解与可控字符扰动建模,在保持fastText轻量架构的同时,显式学习拼写变异下的语义不变性,显著提升向量空间

weixin_30614109的博客 446

dy创作者平台上传并发布视频

整体上来说不是很难,就是过程有点复杂。因为这个是别人给的单子,所以这里不放源码了。细致一点就可以搞定。如果要Signature算法,可私信,不免费。

记录一些web逆向的过程 1515

SAP_MM模块采购价格确定控制简介

SAP MM模块采购价格确定控制是采购管理中的关键功能,系统通过"价格确定日期"判断条件记录有效性并带出正确价格。文章分析了四种常见业务场景及其对应的价格确定方案:普通采购订单(创建日期)、长期合同(交货日期)、特殊业务(手动输入)和接口下单(系统传入)。详细介绍了配置方法和前台操作步骤,并提供了不同业务类型对应的推荐控制方式汇总表。通过合理设置价格确定日期控制,企业可以确保采购价格准确性,满足各种复杂业务场景下价格管理的需求,从而提高采购管理效率和成本控制能力。

我小时候很黑的博客 737

JavaSE『学习笔记』

本教程以 JDK8 为主,新版本与新特性以介绍与使用为辅。

小哞^同^学的技术博客 1236

自私兽群优化器(SHO)详解:从生物本能到智能优化

自私兽群优化器(SHO)是一种受动物群体自私行为启发的智能优化算法。该算法模拟动物在捕食威胁下的两种行为:聚集行为(全局搜索)和自私行为(局部搜索),将优化问题的解空间映射为生存环境,候选解视为猎物个体。SHO通过安全性评估将猎物分为安全、危险和高危三类,分别采用不同的位置更新策略,并引入捕食者角色增加选择压力。相比传统优化算法,SHO具有无需梯度信息、自适应平衡探索与开发、参数简单等优势,特别适合高维复杂和多模态优化问题。算法通过马尔可夫链理论保证收敛性,已在工程设计和数据挖掘等领域展现出良好性能。

qq_42212808的博客 196

MuleSoft+LLM企业级AI编排实战:可审计、可治理的智能工作流

AI编排(AI Orchestration)是将大语言模型深度融入企业核心业务系统的关键范式,其本质并非简单调用API,而是通过确定性中间件实现意图识别、上下文组装、安全路由与合规审计的全链路协同。在金融、制造、零售等强监管场景中,MuleSoft凭借DataWeave规则引擎、私有化部署能力与原生追踪机制,有效弥合数据主权、业务语义与审计合规三重断层。它使LLM从不可控的‘概率输出’转变为受约束的‘结构化协作者’,支撑端到端37秒自动化工单闭环、ISO 27001合规建议生成等真实生产需求。本文聚焦AI

weixin_30251829的博客 817

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

大模型技术之-LangChain框架

摘要: LangChain是由哈佛大学Harrison Chase开发的开源框架(2022年10月发布),用于构建基于大语言模型(LLMs)的应用程序,支持Agent、问答系统、文档搜索等场景。其核心模块包括Model I/O(标准化模型输入/输出)、Chains(流程组合)、RAG(检索增强生成)和Agents(任务自动化)。相比直接调用GPT等API,LangChain简化开发流程、降低学习成本,并提供统一接口。 环境配置: 需Python 3.12环境,通过requirements.txt安装依赖,建

专业的计算机毕业设计指南 769

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

程序员写作者的提示词三层结构实战指南

提示词工程不是编写AI指令,而是将人类专业思维结构化为可执行、可验证、可版本化的技术接口。在大模型应用落地中,'领域层—任务层—约束层'三层结构替代了模糊的角色设定与笼统任务描述,使提示词具备类似Git提交、SQL查询和单元测试的工程属性。该方法特别适用于技术文档生成、PR描述润色、API文档自动化等程序员写作者高频场景,依托Kimi K2.5长文本理解与代码推理能力,实现输出稳定性从62%提升至94%以上,并支撑术语一致性、架构图对齐、OpenAPI Schema校验等关键质量要求。

weixin_30500473的博客 314

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

上一篇: 大数据集处理策略 Bloom-Filter trie树
下一篇: 逆转链方法遍历二叉树 不使用栈与递归 Robson方法 与 Morris方法
stund
博客等级 码龄18年 28粉丝 15原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值