说无可说

字符串相似度计算
本文介绍了一种计算字符串相似度的方法,使用DFS和DP算法解决特定条件下的字符串对数问题,并提供了一个具体的实现示例。

题面:

说无可说(say.pas/cpp/c)

题目描述

“What’s left to say when every word’s been spoken?”

“若沉默再无休止,是否已经说无可说?”

------来自网易云音乐<Golden Leaves-Passenger>

沉默之中,我已不懂言语。

幻觉中,有人在轻声低吟。

那是谁?

我听见,那个人说了N句话,然而好多话都是重复或者类似,比沉默更加让人不堪。

打破不堪,我想。

每句话是由若干个小写字母组成的字符串。

字符串A和B的相似度定义如下:

<字符串A通过以下三种操作:1、插入一个字符;2、删除一个字符;3、替换一个字符. 变成字符串B的最少操作次数>

比如字符串‘abcd’变成‘ccd’的最少次数是2:

首先,删掉字符“a”得到‘bcd’,然后,将‘b’变成‘c’,得到‘ccd’。

给出N个字符串,求出相似度分别为1,2,3,4,5,6,7,8的字符串对数。

输入

第一行一个正整数N

接下来N行,每行一个字符串

输出

一行输出八个数,表示相似度分别为1,2,3,4,5,6,7,8的字符串对数

样例输入1

5

asxglhxpjdczgmt

sxflkxppkcztnmt

sxglkxpjdzlmt

xglkxxepjdazelmzc

asxglkqmvjddalm

样例输出1

0 0 0 1 0 1 3 1

样例输入2\3\4\5\6

见下发文件

样例输出2\3\4\5\6

见下发文件

数据范围

对于10%的数据,1<=n<=20,1<=每个字符串的长度<=12

对于30%的数据,字符串的总长度<=5000

对于40%的数据,字符串的总长度<=12000

对于60%的数据,字符串的总长度<=100000

对于另外20%的数据,1<=n<=70

对于100%的数据,1<=n<=200,字符串的总长度<=1000000

思路:

DFS

别问我复杂度

反正我卡不掉

解题报告:

say

对于30%的数据,字符串的总长度<=5000”

DP,枚举两个串A和B,设f[i][j]表示A中以第i位开始的字符串变成B中以第j为开始的字符串的最小次数

对于40%的数据,字符串的总长度<=12000”

跟30%的一样,数组滚动就好了。

对于60%的数据,字符串的总长度<=100000”

所以DP时很多状态都是无用的,因为如果两个串的长度差大于8那么对答案没有贡献

对于另外20%的数据,1<=n<=70”

其实这档跟正解没有什么区别,好像也是可以过掉100分的,没有实测,但是分分钟跑的比正解快?!

由于只要求相似度小于等于8 的字符串对数,那么考虑递归的计算两个串的相似度,对于串A和B,假设当前我们已经匹配到x和y(x是A中的位置,y是B中的位置),那么首先跳过以这两个位置开头的LCS,然后三种操作继续递归下去,如果答案大于8就退出。

求LCS的时候就用hash+二分

对于100%的数据,1<=n<=200,字符串的总长度<=1000000”

其实我也不是很懂,怎么玄学就跑过去了呢?std的做法是...跳LCS的时候一个个跳...详情见标程...不要打我...wo shi la ji

//By SiriusRen
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n,k,lena,lenb,tempans,ans[10];
char a[1000500],b[1000500];
string str[205];
void dfs(int solvedx,int solvedy,int dep){
    if(dep+abs((lena-solvedx)-(lenb-solvedy))>=tempans)return;
    while(a[solvedx]==b[solvedy]&&solvedx<lena&&solvedy<lenb)solvedx++,solvedy++;
    if(solvedx==lena){tempans=min(tempans,dep+lenb-solvedy);return;}
    if(solvedy==lenb){tempans=min(tempans,dep+lena-solvedx);return;}
    dfs(solvedx+1,solvedy+1,dep+1);
    dfs(solvedx+1,solvedy,dep+1);
    dfs(solvedx,solvedy+1,dep+1);
}
bool cmp(string &a,string &b){return a.size()>b.size();}
int main(){
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)cin>>str[i];
    sort(str+1,str+1+n,cmp);
    for(int i=1;i<=n;i++){
        strcpy(a,str[i].c_str());
        lena=strlen(a);
        for(int j=i+1;j<=n;j++){
            if(abs((int)str[j].size()-(int)str[i].size())<9){
                strcpy(b,str[j].c_str());
                lenb=strlen(b);
                tempans=9;
                dfs(0,0,0);
                ans[tempans]++;
            }
        }
    }
    for(int i=1;i<=8;i++)printf("%d ",ans[i]);
}

 

转载于:https://www.cnblogs.com/SiriusRen/p/7089849.html

内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值