hdu - 4323 - Magic Number - dp + 数据结构优化

编辑距离、拼写检查与度量空间:一个有趣的数据结构     除了字符串匹配、查找回文串、查找重复子串等经典问题以外,日常生活中我们还会遇到其它一些怪异的字符串问题。比如,有时我们需要知道给定的两个字符串“有多像”,换句话说两个字符串的相似度是多少。1965年,俄国科学家Vladimir Levenshtein给字符串相似度做出了一个明确的定义叫做Levenshtein距离,我们通常叫它“编辑距离”。字符串A到B的编辑距离是指,只用插入 阅读详情

题意:http://acm.hdu.edu.cn/showproblem.php?pid=4323

       对于每个询问,输出给定一列数里面与询问的数a编辑距离小于等于b的数。

解:

     dp,编辑距离。

转自Matrix67

 除了字符串匹配、查找回文串、查找重复子串等经典问题以外,日常生活中我们还会遇到其它一些怪异的字符串问题。比如,有时我们需要知道给定的两个字符串“有多像”,换句话说两个字符串的相似度是多少。1965年,俄国科学家Vladimir Levenshtein给字符串相似度做出了一个明确的定义叫做Levenshtein距离,我们通常叫它“编辑距离”。字符串A到B的编辑距离是指,只用插入、删除和替换三种操作,最少需要多少步可以把A变成B。例如,从FAME到GATE需要两步(两次替换),从GAME到ACM则需要三步(删除G和E再添加C)。Levenshtein给出了编辑距离的一般求法,就是大家都非常熟悉的经典动态规划问题。
    在自然语言处理中,这个概念非常重要,例如我们可以根据这个定义开发出一套半自动的校对系统:查找出一篇文章里所有不在字典里的单词,然后对于每个单词,列出字典里与它的Levenshtein距离小于某个数n的单词,让用户选择正确的那一个。n通常取到2或者3,或者更好地,取该单词长度的1/4等等。这个想法倒不错,但算法的效率成了新的难题:查字典好办,建一个Trie树即可;但怎样才能快速在字典里找出最相近的单词呢?这个问题难就难在,Levenshtein的定义可以是单词任意位置上的操作,似乎不遍历字典是不可能完成的。现在很多软件都有拼写检查的功能,提出更正建议的速度是很快的。它们到底是怎么做的呢?1973年,Burkhard和Keller提出的BK树有效地解决了这个问题。这个数据结构强就强在,它初步解决了一个看似不可能的问题,而其原理非常简单。

    首先,我们观察Levenshtein距离的性质。令d(x,y)表示字符串x到y的Levenshtein距离,那么显然:

1. d(x,y) = 0 当且仅当 x=y  (Levenshtein距离为0 <==> 字符串相等)
2. d(x,y) = d(y,x)     (从x变到y的最少步数就是从y变到x的最少步数)
3. d(x,y) + d(y,z) >= d(x,z)  (从x变到z所需的步数不会超过x先变成y再变成z的步数)

    最后这一个性质叫做三角形不等式。就好像一个三角形一样,两边之和必然大于第三边。给某个集合内的元素定义一个二元的“距离函数”,如果这个距离函数同时满足上面说的三个性质,我们就称它为“度量空间”。我们的三维空间就是一个典型的度量空间,它的距离函数就是点对的直线距离。度量空间还有很多,比如Manhattan距离,图论中的最短路,当然还有这里提到的Levenshtein距离。就好像并查集对所有等价关系都适用一样,BK树可以用于任何一个度量空间。

    建树的过程有些类似于Trie。首先我们随便找一个单词作为根(比如GAME)。以后插入一个单词时首先计算单词与根的Levenshtein距离:如果这个距离值是该节点处头一次出现,建立一个新的儿子节点;否则沿着对应的边递归下去。例如,我们插入单词FAME,它与GAME的距离为1,于是新建一个儿子,连一条标号为1的边;下一次插入GAIN,算得它与GAME的距离为2,于是放在编号为2的边下。再下次我们插入GATE,它与GAME距离为1,于是沿着那条编号为1的边下去,递归地插入到FAME所在子树;GATE与FAME的距离为2,于是把GATE放在FAME节点下,边的编号为2。
      
    查询操作异常方便。如果我们需要返回与错误单词距离不超过n的单词,这个错误单词与树根所对应的单词距离为d,那么接下来我们只需要递归地考虑编号在d-n到d+n范围内的边所连接的子树。由于n通常很小,因此每次与某个节点进行比较时都可以排除很多子树。
    举个例子,假如我们输入一个GAIE,程序发现它不在字典中。现在,我们想返回字典中所有与GAIE距离为1的单词。我们首先将GAIE与树根进行比较,得到的距离d=1。由于Levenshtein距离满足三角形不等式,因此现在所有离GAME距离超过2的单词全部可以排除了。比如,以AIM为根的子树到GAME的距离都是3,而GAME和GAIE之间的距离是1,那么AIM及其子树到GAIE的距离至少都是2。于是,现在程序只需要沿着标号范围在1-1到1+1里的边继续走下去。我们继续计算GAIE和FAME的距离,发现它为2,于是继续沿标号在1和3之间的边前进。遍历结束后回到GAME的第二个节点,发现GAIE和GAIN距离为1,输出GAIN并继续沿编号为0到2的边递归下去(那条编号为4的边连接的子树又被排除掉了,在这个图中没有编号为0的边)……
    实践表明,一次查询所遍历的节点不会超过所有节点的5%到8%,两次查询则一般不会17-25%,效率远远超过暴力枚举。适当进行缓存,减小Levenshtein距离常数n可以使算法效率更高。

#include <cstdio>
#include <cstring>
const int MAXN = 1505;

int dp[15][15];
char magic[MAXN][15];
int len[MAXN];
char temp[15];

inline int min(const int &x, const int &y)
{
    return x < y ? x : y;
}

inline int min(const int &x, const int &y, const int &z)
{
    return min(x, min(y, z));
}

int main()
{
    int t, n, m;
    scanf("%d", &t);
    for(int cas=1;cas<=t;++cas)
    {
        scanf("%d%d", &n, &m);
        for(int i=0;i<n;++i)
        {
            scanf("%s", magic[i]);
            len[i] = strlen(magic[i]);
        }
        printf("Case #%d:\n", cas);
        int threshold;
        for(int i=0;i<m;++i)
        {
            scanf("%s%d", temp, &threshold);
            int ans = 0;
            int l = strlen(temp);
            for(int j=0;j<n;++j)
            {
                for(int k=0;k<=l;++k)
                {
                    dp[0][k] = k;
                }
                for(int k=0;k<=len[j];++k)
                {
                    dp[k][0] = k;
                }
                for(int ii=0;ii<len[j];++ii)
                {
                    for(int jj=0;jj<l;++jj)
                    {
                        dp[ii+1][jj+1] = min(dp[ii][jj+1] + 1, dp[ii+1][jj] + 1, dp[ii][jj] + (magic[j][ii] == temp[jj] ? 0 : 1));
                    }
                }
                if(dp[len[j]][l] <= threshold)
                {
                    ++ ans;
                }
            }
            printf("%d\n", ans);
        }
    }
    return 0;
}

BK树模板:

 class BK {
    	int maxn = 12;// 最大距离
        class node {
            node ch[];
            String key;
            int count;
            node(String s) {
                key = s;
                count = 1;
                ch = new node[maxn];
            }
        }
        node root;
        int dp[][] = new int[maxn][maxn];
        int dis(String a, String b) {
            int n = a.length();
            int m = b.length();
            for (int i = 0; i < maxn; i++)
                dp[0][i] = dp[i][0] = i;
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= m; j++) {
                    int flag = 1;
                    if (a.charAt(i - 1) == b.charAt(j - 1))
                        flag = 0;
                    dp[i][j] = Math.min(
                            Math.min(dp[i - 1][j], dp[i][j - 1])+1,
                            dp[i - 1][j - 1] + flag);
                }
            }
            return  dp[n][m];
        }
        void init() {
            root = null;
        }
        void insert(String s, node r) {            
            int d = dis(r.key, s);
            if (d == 0){
                r.count++;
                }
            else if(r.ch[d]==null)
                r.ch[d]=new node(s);
            else
                insert(s, r.ch[d]);
        }

        void insert(String s) {
            if(root==null)
                root= new node(s);
            else
            insert(s, root);
        }

        int query(String s, int n) {
            return query(root, s, n);
        }
        int query(node r, String s, int n) {
            int ans = 0;
            if (r == null)
                return 0;
            int d = dis(r.key, s);
            if (d <= n)
                ans += r.count;

            int a = Math.max(d - n, 1), b = Math.min(maxn-1, d + n);
            for (int i = a; i <= b; i++)
                ans += query(r.ch[i], s, n);
            return ans;
        }
    }


python实现bk树(cython加速) 详细见blog:https://blog.youkuaiyun.com/koibiki/article/details/83052431 立即下载

相关推荐

树编辑距离的 Python APTED算法_python_代码_下载

这是 APTED 算法的 Python 实现,它是计算树编辑距离的最先进的解决方案 ,它取代了 RTED 算法 输入 目前,我们只支持输入树的所谓括号表示法,例如,编码{A{B{X}{Y}{F}}{C}}对应于以下树: A / \ B C /|\ X Y F 输出 我们的工具计算两个输出: 树编辑距离值 - 将源树转换为目标树的最小成本。 树编辑映射- 对应于树编辑距离值的节点之间的映射。未映射的节点将被删除(源树)或插入(目标树)。

编辑距离算法详解:Levenshtein Distance算法——动态规划问题

目录 背景: 求编辑距离算法: 图解过程: C++代码如下: 总结: 背景: 我们在使用词典app时,有没有发现即使输错几个字母,app依然能给我们推荐出想要的单词,非常智能。它是怎么找出我们想要的单词的呢?这里就需要BK树来解决这个问题了。在使用BK树之前我们要先明白一个概念,叫编辑距离,也叫Levenshtein距离。词典app是怎...

didiaola4003的博客 2029

10xGenomics官方可视化工具——Loupe Browser

Loupe Browser是⼀款10xGenomics开发的交互式桌⾯应⽤程序,⽤于探索10x单细胞数据,可以用来找出感兴趣的细胞、找出显著差异表达的基因、鉴定细胞类型、探索细胞亚类和数据共享。

weixin_47195452的博客 3344

BK树(Burkhard-Keller树)—离散度量空间的度量树

BK树构造就过程 BK树,是一种基于树的数据结构,被设计于快速查找近似字符串匹配,比方说拼写纠错,或模糊查找,当搜索”aeek”时能返回”seek”和”peek”。 在定义BK树之前,我们需要预先定义一些操作。为了索引和搜索字典,我们需要一种比较字符串的方法。编辑距离( Levenshtein Distance)是一种标准的方法,它用来表示经过插入、删除和...

红叶谷 wsp_1138886114的博客 3864

从零到一:i.MX8M Plus开发板全流程开发指南(源码编译、烧录、镜像运行)

本文详细介绍了i.MX8M Plus开发板的全流程开发指南,包括源码编译、烧录和镜像运行等关键步骤。通过实战案例和配置技巧,帮助开发者快速掌握工业级应用开发,提升在边缘计算和AI推理等领域的开发效率。

weixin_30687051的博客 566

Python爬虫实战:避开巨潮资讯网反爬,稳定获取上市公司年报PDF下载地址

本文详细介绍了如何使用Python和Selenium突破巨潮资讯网的动态加载限制,稳定获取上市公司年报PDF下载地址。通过模拟真实用户操作、智能等待策略和反反爬虫技巧,帮助开发者高效爬取财经数据,适用于股票代码查询和年报分析等场景。

weixin_29065659的博客 1664

hdu 4323 Magic Number(编辑距离)

http://acm.hdu.edu.cn/showproblem.php?pid=4323 题意:有n个数和m个询问。对于每个询问有一个数和临界值,问n个数中与这个数的编辑距离不大于临界值的数的个数。 对于编辑距离: 假设字符串的基本操作仅为:删除一个字符、插入一个字符和将一个字符修改成另一个字符这三种操作。  我们把进行了一次上述三种操作的任意一种操作称为进行了一步字符基本操作。 下

1073

Visual Tracker Benchamark傻瓜式教程(二)

问题  1 1  在调用main.m跑TRE和SRE时,因为会生成相应的.mat数据文件,如果跑完以后发现自己算法生成的.mat文件有问题,那么要把该文件删除,待找到错误原因后,重新生成相应的.mat文件。因为程序中写的是如果已经存在了.mat文件,例如已经存在car4_STC.mat文件,即使该文件中的数据有错误,但是重新跑时会默认该文件中的数据写完,不会重新写入数据 问题  2  b

mingbujingren的专栏 9928

hdu 4323 Magic Number

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4323 题目大意,求一个字典中,与询问串的最小编辑距离小于等于d的个数。 题目思路:dp很容易想,比赛的时候由于以为会超时,一直不敢写,结果直接暴力就可以过。。题解上说可用BK-tree优化,结果优化结果很不理想,和暴力差不多。。 #include&lt;iostream&gt; #include...

java开发指南博客 【转载】 182

什么是深度展开网络?如何将迭代算法的每一次迭代展开成深度网络对应的一层?深度展开网络进行端对端训练,其中端对端是什么意思?

在深度学习和机器学习的背景下,“端到端”(End-to-end)训练指的是将输入数据直接映射到最终输出的过程,而不需要任何中间的手动数据预处理或特征工程。- **自然语言处理**:端到端自然语言处理系统可以将自然语言输入直接转化为计算机可理解的语言输出,而不需要对语言进行分解和转化。- **推荐系统**:通过使用深度神经网络,端到端推荐系统可以直接根据用户历史行为预测其未来的兴趣爱好,并推荐相应的产品或服务。4. **直接映射**:从输入到输出的直接映射,中间没有任何拆分或分解的过程。

m0_67897882的博客 5423

【ARM Coresight | AMBA BUS | Cache 与 MMU/MPU | CoreLink | GCC | CSH 专栏导读】

1. ARM Coresight(SoC-400/SoC-600) 专栏 2. ARMv8/v9 CPU/Cache 专栏 3. Linux ARM AMBA 总线 专栏 4. Trace32/DS-5 专栏。。。

CodingCos的博客 8239

HDU 4323 Magic Number(编辑距离 DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4323 经典的编辑距离DP,进行一些必要的剪枝,也就是初始长度差大于small的话 直接continue; #include #include #include #include using namespace std; #define maxn 1500 #define MIN(a,

sunrain的专栏 707

[Godot][入门] 安装与版本选择:3.x 还是 4.x?(按项目类型一键决策)

摘要: Godot引擎版本选择需根据项目需求权衡3.x与4.x。Godot4.x(如4.2)适合3D开发和新项目,支持Vulkan和GDScript2.0,但生态尚不成熟;Godot3.x(如3.5.3)则更适合稳定2D开发、Web导出及依赖现有插件/教程的场景。安装方式极简,官网下载解压即可运行。新手建议:短期高效选3.x,长期探索选4.x,旧项目勿盲目迁移。附版本对比表及决策树,助开发者快速匹配需求。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 910

hdu4323Magic Number(dp)

http://acm.hdu.edu.cn/showproblem.php?pid=4323 去年的多校 编辑距离的变形 暴力居然过了 还想了好久别的方法,想得很头疼 1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm&...

weixin_30678821的博客 94

Avalonia+ReactiveUI跨平台路由:从零到舞者,你的UI也能跨界起舞?

至此,你已掌握了Avalonia+ReactiveUI的跨平台路由精髓!你的应用现在能够优雅地在各个界面间穿梭,就像是在不同星球间跳跃的宇宙飞船。无论是初探跨平台开发的新手,还是经验丰富的老船长,这段旅程都能让你的UI编排技能更上一层楼。现在,是时候让世界见证你的跨平台魔术了!💫记住,每一次实践都是向着完美编舞迈进的一步,勇敢地在你的项目中尝试吧!如果在航行中遇到风暴,别忘了回来看看这篇指南,或者在评论区抛出你的救生圈,我们一起解决!🌊。

java专栏 1534

温度PID控制PLC程序

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

hdu 4323 Magic Number 2012多校训练第三场1004题 BK树

今天下午进行了第三场的多校,表示被虐成了狗…… 1004题当时感觉想暴力,毛估复杂度是1000*1500*10*10……这还是单case的,所以一直没敢敲……直到最后发现全场几十支队伍都过了,开始敲……结果没想清楚最终WA到死 晚上的时候回基地写了个暴力解法,375ms过了,感觉时间卡的也不紧……需要稍作优化,两个字符串长度之差大于要求的编辑距离时就不用再去dp了,dp的状态转移和求最长公共子

renew 1094

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

编辑距离优化--二维数组转一维数组

之前的编辑距离小练习我一直是用二维数组去记录的,而经神学弟提醒改用了一维数组去优化,发现果然好了很多。

Bright-XL 1827

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

hdu 4323 Magic Number dp 多校联合赛(三)第四题

如果a[i],b[j]相等dp[i][j]=dp[i-1][j-1]; 如果不想等 dp[i][j]=min(dp[i-1][j],min(dp[i][j-1],dp[i-1][j-1]))+1; 注意最后dp[lena-1][lenb-1] #include #include #include using namespace std; int n,m,dp[15][15];int y; in

代码随想录 2191

hdu4323-Magic Number-2012 Multi-University Training Contest 3题解

Brief Description: 给定n个字符串,以及m个query,每个query包含1个字符串s和一个整数t,求n个字符串中与s距离小于等于t的个数,题目中给出了字符串的定义。 Analysis: 比赛时这题毛估的复杂度显然是TLE的级别的,所以一直没敢动,其实在有很多队伍过的情况下就应该大胆尝试。 这题的关键在于求2个字符串的距离,可以用dp做。若有2个字符串a,b,求它们的

linweiway67的专栏 830

Magic Number(Levenshtein distance算法)

Magic Number Time Limit:1000MSMemory Limit:65536KB64bit IO Format:%I64d & %I64u SubmitStatusPracticeHDU 4323 Description There are many magic numbers whose lengths a...

weixin_30822451的博客 162

目标检测指标之树编辑距离TEDS (Tree-Edit-Distance-based Similarity)

因为最近的项目需要用到TEDS这个指标,看原始论文没有看明白,整理了一下网上的资料汇总在这里做一个记录,如有侵权请联系我删除 首先是数据类型:表格的树结构图(HTML序列化结构 ) 对于树而言 ,同样定义了树编辑距离的增删改操作: 增:添加一个节点在父节点和其子节点之间 删:将树的某个节点删除,同时将其子节点移动到该节点的父节点上。 改:修改节点的label 计算树的编辑距离就是求从一棵树转换为另一棵树所需要树的编辑操作的最少次数。 具体的计算公式如下图所示: 树编辑距离的实现可以直接

m0_54167819的博客 3856

HDU 2476 字符串a转化为字符串b需要几次操作 结合编辑距离

与编辑距离思想类似,但是编辑距离每次只能增删改。还涉及到字符串的对齐问题。http://blog.youkuaiyun.com/vsooda/article/details/8313172 而本题每次修改就修改一个区间。自然地,使用dp[i][j]表示从i 到 j 所需要的修改次数的上界。 初始化dp[i][j]为dp[i+1][j] + 1 如果s2[i] == s2[k]   dp[i][j] =

vsooda的专栏 1895

BK-Tree

用于根据编辑距离(Levenshtein距离)概念执行拼写检查。 BK树也用于近似字符串匹配。基于该数据结构,可以实现许多软件中的各种自动校正特征。 BKTree算法上分两步: 1 构造 在词典里面随便找一个词作为root节点,然后与其他词计算编辑距离n。若已有相同编辑距离n的子节点,就挂在子节点下;若没有,就新建边为n的子节点。如此递归下去。 2 查询 这里重点来了,编辑距离符合三角不等式...

我是一只程序⚪的技术交流平台 2256

基于树编辑距离的相似度(TEDS)

最近由于要对OCR文字识别系统的表格识别部分做指标评测分析。评测方法之前是将ground truth 和recognition result 展平后统计非空单元格之间的两两关系,得到非空单元格的关系矩阵。然后基于这个矩阵去统计Recall,Precision和 F1 score。但是这样的评测方式是有问题的:只检查非空单元格之间的直接关系,而对于由空单元格和非直接关系单元格之间未对齐引起的错误无法检测。另一个问题是无法同时对单元格的内容进行评测经过一番搜索发现了TEDS评价方法。

GitHub质检员 740

BK树

原文链接:http://blog.jobbole.com/78811/ 这是『超酷算法』系列的第一篇文章。基本上,任何一种算法我觉得都很酷,尤其是那些不那么明显简单的算法。 BK树或者称为Burkhard-Keller树,是一种基于树的数据结构,被设计于快速查找近似字符串匹配,比方说拼写检查器,或模糊查找,当搜索”aeek”时能返回”seek”和”peek”。为何BK-Trees这么酷

Aiphis的博客 3879
上一篇: hdu - 4322 - Candy - 网络流
下一篇: hdu - 4324 - Triangle LOVE - 深搜
Julyana_Lin
博客等级 码龄15年 36粉丝 177原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值