【方法一:二分+字符串哈希 优化】【dp——取不取问题-背包】最长公共子串【上海交通大学考研机试题】

news2024/9/20 0:57:29

最长公共子串

    • 二分方法
        • 字符串哈希的复习
            • 字符串哈希 如何理解
        • 二分代码
    • dp方法
            • 字符串str1中以第i个字符为结尾的子串 与字符串str2中以第i个字符为结尾的子串的连续公共子串
        • 二维
        • 一维优化

二分方法

  1. 由于这个题是要求求子串,而子串是连续的一段,所以用二分长度,找到最长的公共子串长度即可
  2. 那么用二分,我们就需要比较上下两个字符串,怎么对比两个字符串呢?经过演算,比较好的方法就是,把两个字符串,二分长度的时候,都把相应的字符串丢到 map里,当进行第一个字符串,把长度为x的子串丢到map后,再次把第二个字符串丢进去,如果出现重复,那么返回true,都没重复返回false
  3. 但是在map中会进行字符串比较,这个效率比较低,所以用 字符串哈希,把字符串的子串用 数字表示,这样在map里比较时,就会更方便
  4. 出现数字,把数字转成 两个字符串分别转成各自固定特殊符号,这样就不会重复

字符串哈希的复习

原题链接

字符串哈希 如何理解

首先我们理解在 123456中 如何取出456

我们把每个位置上的分别对应求出相应位置的总和
位置
1 ——》1
2 ——》12
3 ——》123
4 ——》 1234
5 ——》12345
6 ——》123456

那么我们把 123456 - 123*100 = 456

字符串也如此
ABCDEF
位置
1——》对应A的数字 同理如下即可

#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
typedef unsigned long long ULL;
const int N = 1e5+5,P = 131;//131 13331
ULL h[N],p[N];

// h[i]前i个字符的hash值
// 字符串变成一个p进制数字,体现了字符+顺序,需要确保不同的字符串对应不同的数字
// P = 131 或  13331 Q=2^64,在99%的情况下不会出现冲突
// 使用场景: 两个字符串的子串是否相同
ULL query(int l,int r){
    return h[r] - h[l-1]*p[r-l+1];
}
int main(){
    int n,m;
    cin>>n>>m;
    string x;
    cin>>x;

    //字符串从1开始编号,h[1]为前一个字符的哈希值
    p[0] = 1;
    h[0] = 0;
    for(int i=0;i<n;i++){
        p[i+1] = p[i]*P;            
        h[i+1] = h[i]*P +x[i];      //前缀和求整个字符串的哈希值
    }

    while(m--){
        int l1,r1,l2,r2;
        cin>>l1>>r1>>l2>>r2;
        if(query(l1,r1) == query(l2,r2)) printf("Yes\n");
        else printf("No\n");

    }
    return 0;
}

二分代码

#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_set>

using namespace std;

typedef unsigned long long ULL;

const int N = 20010, P = 131;

int n, m;
char str[N];
ULL p[N], h[N];

ULL get(int l, int r)
{
    return h[r] - h[l - 1] * p[r - l + 1];
}

bool check(int mid)
{
    unordered_set<ULL> hash;
    for (int i = 1; i + mid - 1 <= n; i ++ )
        hash.insert(get(i, i + mid - 1));

    for (int i = n + 1; i + mid - 1 <= n + m; i ++ )
        if (hash.count(get(i, i + mid - 1)))
            return true;
    return false;
}

int main()
{
    scanf("%s", str + 1);
    n = strlen(str + 1);
    scanf("%s", str + n + 1);
    m = strlen(str + n + 1);

    p[0] = 1;
    for (int i = 1; i <= n + m; i ++ )
    {
        p[i] = p[i - 1] * P;

        char c = str[i];
        if (isdigit(c))
        {
            if (i <= n) c = '#';
            else c = '$';
        }
        h[i] = h[i - 1] * P + c;
    }

    int l = 0, r = min(n, m);
    while (l < r)
    {
        int mid = l + r + 1 >> 1;
        if (check(mid)) l = mid;
        else r = mid - 1;
    }

    printf("%d\n", r);

    return 0;
}

作者:yxc
链接:https://www.acwing.com/activity/content/code/content/6308090/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

dp方法

字符串str1中以第i个字符为结尾的子串 与字符串str2中以第i个字符为结尾的子串的连续公共子串

在这里插入图片描述

二维

#include <iostream>
#include <cstring>
using namespace std;

const int N = 1e4 + 10;
char str1[N], str2[N];

int f[N][N];//注意空间限制为256MB,即为2^(8 + 20) = 2^28个字节,
//而一个int型变量占4个字节,那么最多有2^26个int变量,大约为64000000个变量,而此时定义f[N][N]最多有大于1e8个变量,会爆内存
//更何况还有存字符串的空间

int main()
{
    cin >> str1 + 1 >> str2 + 1;    

    int len1 = strlen(str1 + 1), len2 = strlen(str2 + 1);

    int res = 0;
    for (int i = 1; i <= len1; i++)
    {
        //如果最后一位为数字
        if (str1[i] >= '0' && str1[i] <= '9')
        {
            for (int j = 1; j <= len2; j++)
            f[i][j] = 0;
            continue;    
        }

        for (int j = 1; j <= len2; j++)
        {
            //如果最后一位相同且不为数字
            if (str1[i] == str2[j])
                f[i][j] = f[i - 1][j - 1] + 1;

            else f[i][j] = 0;

            res = max(res, f[i][j]);
        }
    }

    cout << res << endl;

    return 0;
}

在这里插入图片描述

一维优化

#include <iostream>
#include <cstring>
using namespace std;

const int N = 1e4 + 10;
char str1[N], str2[N];

int f[N];

int main()
{
    cin >> str1 + 1 >> str2 + 1;    

    int len1 = strlen(str1 + 1), len2 = strlen(str2 + 1);

    int res = 0;//用于保存答案
    for (int i = 1; i <= len1; i++)
    {
        //如果最后一位为数字
        if (str1[i] >= '0' && str1[i] <= '9')
        {
            for (int j = 1; j <= len2; j++)
            f[j] = 0;
            continue;    
        }

        for (int j = len2; j >= 1; j--)
        {
            //如果最后一位相同且不为数字
            if (str1[i] == str2[j])
                f[j] = f[j - 1] + 1;

            else f[j] = 0;

            res = max(res, f[j]);
        }
    }

    cout << res << endl;

    return 0;
}

作者:a_zi_ge
链接:https://www.acwing.com/solution/content/185166/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/448459.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在微信小程序中怎么使用vant框架?

目录标题 首先介绍什么是vant一、第一步&#xff0c;打开我们小程序项目目录&#xff0c;找到所在的位置&#xff0c;打开终端二、对项目进行初始化三、进行安装依赖1、通过npm安装vant/weapp2、安装miniprogram 四、修改app.json五、修改project.config.json六、然后构建npm 需…

使用Word的一些技巧记录

本文主要用于记录书写毕业论文时&#xff0c;遇到的Word的使用技巧。 设置样式及多级列表 每个学校必然会对论文中的字体、字号、行间距提出要求&#xff0c;设置Word中样式解决此问题。 例如&#xff0c;本校的格式要求为&#xff1a; 正文中的一级标题&#xff08;章目&a…

【C#】GridControl动态更换DataSource,查询数据异常处理

系列文章 【C#】单号生成器&#xff08;编号规则、固定字符、流水号、产生业务单号&#xff09; 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/129129787 【C#】日期范围生成器&#xff08;开始日期、结束日期&#xff09; 本文链接&#xff1a;h…

适应大、中、小型医院的手术麻醉临床信息管理系统源码

手术麻醉管理系统是一款专门用于医院手术麻醉管理的软件系统&#xff0c;它可以帮助医院和医生更好地管理手术麻醉过程&#xff0c;提高手术麻醉的质量和安全性。本文将介绍手术麻醉管理系统的实现、功能概述、主要功能、系统设置、麻醉管理、术中记录、苏醒室记录、PCA实施及管…

【微服务笔记20】微服务组件之Nacos配置中心基础环境搭建、配置持久化、动态刷新配置

这篇文章&#xff0c;主要介绍微服务组件之Nacos配置中心基础环境搭建、配置持久化、动态刷新配置。 目录 一、搭建Nacos配置中心环境 1.1、Nacos配置中心介绍 1.2、搭建Nacos配置中心客户端 &#xff08;1&#xff09;引入依赖 &#xff08;2&#xff09;添加配置信息 &…

图书管理系统的开发与设计(论文+源码)_kaic

摘 要 随着科学技术的快速发展&#xff0c;尤其是计算机技术的突飞猛进&#xff0c;计算机技术普及到日常生活、学习生活的方方面面。由此想到学校的相对于传统的图书管理系统&#xff0c;帮助到学校的读者和学校的图书管理员的系统。提升图书管工作人员的效率&#xff0c;满足…

【C++类和对象】类和对象(中):构造函数 {六个默认成员函数;构造函数的概念及特性;编译器自动生成的构造函数;默认构造函数}

一、类的六个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么都没有吗&#xff1f;并不是&#xff0c;任何类在什么都不写时&#xff0c;编译器会自动生成以下6个默认成员函数。 默认成员函数&#xff1a;用户没有显式实现&#xff0c;编译器…

Pytorch深度学习笔记(六)用pytorch实现线性回归

目录 1.数据准备 2.设计模型 3.构造损失函数和优化器 4.训练周期&#xff08;前馈—>反馈—>更新&#xff09; 课程推荐&#xff1a;05.用PyTorch实现线性回归_哔哩哔哩_bilibili 线性通常是指变量之间保持等比例的关系&#xff0c;从图形上来看&#xff0c;变量之间…

为什么要学习微服务?

文章目录 1.认识微服务1.1微服务由来1.2为什么需要微服务&#xff1f; 2.两种架构2.1.单体架构2.2.分布式架构 3.微服务的特点4.SpringCloud5.总结最后说一句 1.认识微服务 随着互联网行业的发展&#xff0c;对服务的要求也越来越高&#xff0c;服务架构也从单体架构逐渐演变为…

类和对象(上篇)

类和对象----上篇 &#x1f506;面向过程和面向对象的初步认识&#x1f506;类的引入&#x1f506;类的定义&#x1f506;类的访问限定符及封装访问限定符封装 &#x1f506;类的作用域&#x1f506;类的实例化&#x1f506;类的对象大小的计算如何计算一个类的大小结构体内存对…

15天学习MySQL计划(多表联查)第四天

15天学习MySQL计划&#xff08;多表联查&#xff09;第四天 1.多表查询 1.1概述 ​ 指从多张表中查询数据 ​ 在项目开发中&#xff0c;在进行数据库表结构设计时&#xff0c;会根据业务需求及业务模块之间的关系&#xff0c;分析并设计表结构&#xff0c;由于业务之间相互…

【HCIP】Huawei设备下IPV4IPV6共存实验

目录 方法一、普通的GRE将V6基于V4通讯 方法二、6to4的tunnel 方法三、双栈 方法一、普通的GRE将V6基于V4通讯 //方法一和方法二的前提&#xff0c;搭个简单的V4网络就行 [r1]int g0/0/0 [r1-GigabitEthernet0/0/0]ip address 12.1.1.1 24 [r1]router id 1.1.1.1 [r1-Gigabi…

Spring Security 05 密码加密

目录 DelegatingPasswordEncoder 使用 PasswordEncoder 密码加密实战 密码自动升级 实际密码比较是由PasswordEncoder完成的&#xff0c;因此只需要使用PasswordEncoder 不同实现就可以实现不同方式加密。 public interface PasswordEncoder {// 进行明文加密String encod…

如何搭建自己的博客网站(手把手教你搭建免费个人博客网站)

没有前言直接开始正文&#xff0c;搭建一个博客需要服务器&#xff0c;域名&#xff0c;博客程序。 博客程序常用的有wordpress&#xff0c;z-blog&#xff0c;typecho等等&#xff0c;其中wordpress和z-blog最为简单&#xff0c;typecho需要一定的技术含量&#xff0c;这里暂…

使用NPOI做Excel简单报表

文章目录 前言初版表格&#xff0c;单元格的合并进阶表格&#xff0c;单元格美化小结 前言 前面介绍了NPOI单元格样式的使用、单元格合并&#xff0c;以及NPOI提供的颜色。现在用上前面的一些知识点&#xff0c;做一个测试结果表格。 1、 介绍NPOI 的颜色卡、名称以及索引 ht…

图片去摩尔纹简述实现python代码示例

这篇文章主要为大家介绍了图片去摩尔纹简述实现的python代码示例&#xff0c;有需要的朋友可以借鉴参考下&#xff0c;希望能够有所帮助&#xff0c;祝大家多多进步&#xff0c;早日升职加薪 1、前言 当感光元件像素的空间频率与影像中条纹的空间频率接近时&#xff0c;可能产生…

分布式系统需要关注的技术点和面试经常问的点

1、分布式系统概述 关于什么是分布式系统&#xff0c;有很多文章介绍&#xff0c;其实这个并不难理解&#xff0c;大白话讲就是&#xff1a;工厂活多了一个人撑不住&#xff0c;那就多找些工人一起干&#xff0c;要让这么多人为了一个目标干得快干得好&#xff0c;就需要一些规…

自主可控智能网联汽车操作系统

开发自主可控智能网联汽车操作系统的必要性 当下&#xff0c;传统汽车操作系统行业的核心技术几乎由国外的黑莓、谷歌、风河、Vector、ETAS等垄断。操作系统已成为我国智能网联汽车发展过程中的关键卡脖子技术&#xff0c;开发自主可控的智能网联汽车操作系统势在必行。 操作…

CVPR 2023 | 达摩院REALY头部重建榜单冠军模型HRN解读

团队模型、论文、博文、直播合集&#xff0c;点击此处浏览 前言 高保真 3D 头部重建在许多场景中都有广泛的应用&#xff0c;例如 AR/VR、医疗、电影制作等。尽管大量的工作已经使用 LightStage 等专业硬件实现了出色的重建效果&#xff0c;从单一或稀疏视角的单目图像估计高精…

微服务架构设计与实践

随着互联网的发展&#xff0c;软件开发已经成为各种企业发展的重要手段。然而&#xff0c;单体应用在长时间的维护中会变得复杂、难以扩展、难以修改。因此&#xff0c;为了满足业务需求&#xff0c;微服务架构应运而生。本篇文章将深入探讨微服务架构的设计与实践。 一、微服务…