【蓝桥】契合匹配

news2024/11/19 0:38:56

一、题目

1、题目描述

小蓝有很多齿轮,每个齿轮的凸起和凹陷分别用一个字符表示,一个字符串表示一个齿轮。

在这里插入图片描述
如果这两个齿轮的对应位分别是同一个字母的大小写,我们称这个两个齿轮是契合的。

例如:AbCDeFghaBcdEfGH 就是契合的,但是 abcaBC不是契合的。

这天,小蓝的弟弟小桥从抽屉里拿来了两个齿轮,小蓝想知道,这两个齿轮是不是契合的。

特别需要注意的是,齿轮是环形的,所以是可以旋转的(顺时针和逆时针均可),如果是契合的,小蓝还想让你告诉他,最少将第一个齿轮旋转多少位,两个齿轮可以完全契合在一起。

例如:AbbCdBcDaB,在将第一个齿轮逆时针旋转两位后,变成 bCdAb,两个齿轮就完全契合在一起了。

输入格式

第一行输入一个正整数 n n n,代表两个齿轮的长度。

第二行输入一个长度为 n n n 的字符串 S S S,代表第一个齿轮。

第三行输入一个长度为 n n n 的字符串 T T T,代表第二个齿轮。

输出格式

第一行输出一个字符串:Yes 或者 No。代表两个齿轮是否契合。

如果可以契合,第二行输出一个整数,代表需要旋转的位数。

如果不可以契合,不用多余输出。

样例输入

5
AbbCd
BcDaB

样例输出

Yes
2

评测数据范围

数据范围: 1 ≤ n ≤ 1 0 6 1 \le n \le 10^6 1n106

保证字符串只包含大小写字母。

2、基础框架

#include <iostream>
using namespace std;
int main()
{
  // 请在此输入您的代码
  return 0;
}

3、原题链接

契合匹配

二、解题报告

1、思路分析

首先可以做的事是将 S S S 串大小写转换,那么就变成了两个字符串的完全匹配。

首先,使用破环成链的思想,将 S S S 串扩大两倍成为 S ′ S' S,将 T T T 串与 S ′ S' S 做匹配。如下代码:

// 将S串扩大两倍
for (int i = 1; i <= n; ++i) {
    if (s[i] >= 'a' && s[i] <= 'z') {
        s[i] += 'A' - 'a';
    } else if (s[i] >= 'A' && s[i] <= 'Z') {
        s[i] += 'a' - 'A';
    }
    s[i + n] = s[i];
}

然后使用 KMP 算法进行匹配,提供 KMP 算法代码:

void get_next(char *s, int *next, int n) {
    next[1] = 0;
    for (int i = 2, j = 0; i <= n; ++i) {
        while (j > 0 && s[j + 1] != s[i]) j = next[j];
        if (s[i] == s[j + 1]) ++j;
        next[i] = j;
    }
}

之后考虑匹配到的最前与最后的位置: P o s b e g i n Pos_{begin} Posbegin P o s e n d Pos_{end} Posend

然后对于两个位置,考虑顺时针与逆时针旋转需要的步数,取最优解即可。

算法本身并不复杂,主要考虑破环成链思想和 KMP 算法。

接下来简单介绍破环成链:

如果一个字符串 S S Sabcdef )扩展成两倍 S ′ S' Sabcdefabcdef ),那么从 S ′ S' S 的第二个字符开始 6 6 6 个字符组成的子串( bcdefa ),实际上就是 S S S 逆时针旋转 1 1 1 位的字符串,同时也是顺时针旋转 5 5 5 位的情况。

本题实质上就是 判断两个字符串是否互为旋转字符串。

对于KMP的讲解与实现见博客 KMP算法讲解与实现。

2、时间复杂度

O ( N ) O(N) O(N)

3、代码详解

/*************************************************************************
	> File Name: my5_契合匹配.cpp
	> Author: Maureen 
	> Mail: Maureen@qq.com 
	> Created Time: 日 10/15 18:48:14 2023
 ************************************************************************/

#include <iostream>
using namespace std;

//大写转换成小写,小写转换成大写
void strConvert(string &s) {
    for (int i = 0; i < s.size(); i++) {
        if (s[i] >= 'A' && s[i] <= 'Z') {
            s[i] += 'a' - 'A'; 
        } else if (s[i] >= 'a' && s[i] <= 'z') {
            s[i] += 'A' - 'a'; 
        }
    }
}

int *getNextArray(string &t) { 
    int *next = new int[t.size()];

    if (t.size() == 1) {
        next[0] = -1;
        return next;
    }
    
    next[0] = -1;
    next[1] = 0;

    int ind = 2; //当前待求信息的位置
    int cn = 0; //前缀的下一个位置,也是要与ind-1位置进行匹配的位置

    while (ind < t.size()) {
        if (t[cn] == t[ind - 1]) {
            next[ind++] = ++cn;
        } else if (cn > 0) {
            cn = next[cn];
        } else {
            next[ind++] = 0;
        }
    }

    return next;
}

int kmp(string &s, string &t) {

    int si = 0;
    int ti = 0;
    
    int *next = getNextArray(t);

    while (si < s.size() && ti < t.size()) {
        if (s[si] == t[ti]) {
            si++;
            ti++;
        } else if (next[ti] == -1) {
            si++;
        } else {
            ti = next[ti];
        }
    }
    
    return ti == t.size() ? si - ti : -1;
}

int main() {
    int n;
    cin >> n;

    string s;
    string t;
    cin >> s >> t;

    int oldSize = s.size();

    //s字符串进行大小写转换
    strConvert(s);

    //扩充为两倍
    s += s;
    
    int posBegin = kmp(s, t);
    int posEnd = oldSize + posBegin; 

    if (posBegin != -1) {
        cout << "Yes" << endl;
        cout << min(posBegin - 0, 2 * oldSize - posEnd);
    } else {
        cout << "No" << endl;
    }
    return 0;
}

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

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

相关文章

基于html+js编写的生命游戏

前言 本文将介绍一个基于htmljs的生命游戏&#xff0c;该项目只有一个html代码&#xff0c;无任何其他以来&#xff0c;UI方面采用了vueelement-plus进行渲染&#xff0c;游戏的界面基于canvas进行渲染&#xff0c;先来看一下成果。 我不知道游戏规则有没有写错&#xff0c;感…

Vue-3.2自定义创建项目

基于VueCli自定义创建项目架子 选择第三个 空格选中&#xff0c;再空格取消 选择vue2 其实就是mode模式&#xff0c;之后再去修改就可以&#xff0c;history和hash 选择less 无分号规范&#xff08;标准化&#xff09;&#xff0c;目前最流行的 将配置文件放在单独的文件中 是否…

Linux环境配置安装Redis

Windows版本因官网不在提供与支持&#xff0c;以下基于linux环境安装 前提&#xff1a; 1.一台linux服务器 2.服务器已安装gcc 安装 1、官网下载 https://redis.io/download/ 对应压缩包 2、上传压缩包至服务器并解压缩 tar -zxvf redis-stable.tar.gz3、cd 至该目录下 4、…

双周总结#002 - 红树林

红树林公园&#xff0c;一棵单独生长在海岸边的树&#xff0c;下面一根根树立的幼苗&#xff0c;是从它的根茎上生长出来的。傍晚落潮后&#xff0c;会有一只只小螃蟹在这里浪荡。当然&#xff0c;也会有海鸟在这里进食。 文档 深入了解 Commonjs 和 Es Module1 Web 开发中&am…

两道关于顺序表的经典算法

文章目录 力扣&#xff1a;[移除元素](https://leetcode.cn/problems/remove-element/)[力扣&#xff1a;88. 合并两个有序数组](https://leetcode.cn/problems/merge-sorted-array/) 力扣&#xff1a;移除元素 题目 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移…

JAVA实战项目 超市商品管理系统

师傅开发的实战项目&#xff0c;感觉不错&#xff0c;拿出来分享分享。 目录 一、摘要1.1 简介1.2 项目录屏 二、研究内容三、系统设计3.1 用例图3.2 时序图3.3 类图3.4 E-R图 四、系统实现4.1 登录4.2 注册4.3 主页4.4 超市区域管理4.5 超市货架管理4.6 商品类型管理4.7 超市商…

JDBC操作BLOB类型字段

JDBC中Statement接口本身不能直接操作BLOB数据类型 操作BLOB数据类型需要使用PreparedStatement或者CallableStatement(存储过程) 这里演示通过PreparedStatement操作数据库BLOB字段 设置最大传入字节 一般是4M 可以通过以下命令修改 set global max_allowed_packet1024*1…

C语言,洛谷题,赦免战俘

先上答案&#xff0c;再对答案进行解释&#xff1a; #include <stdio.h> int arr[1025][1025] { 0 }; void fun(int bian,int x ,int y) {if (bian 2)//进入if再出去if之后&#xff0c;结束递归&#xff0c;因为递归在else里面{arr[x][y] 0;}else{int i 0;int j 0;…

【Linux】:Linux中Shell命令及其运行原理/权限的理解

Shell命令以及运行原理 Linux严格意义上说的是一个操作系统&#xff0c;我们称之为“核心&#xff08;kernel&#xff09;“ &#xff0c;但我们一般用户&#xff0c;不能直接使用kernel 而是通过kernel的“外壳”程序&#xff0c;也就是所谓的shell&#xff0c;来与kernel沟通…

SpringCloud之Gateway整合Sentinel服务降级和限流

1.下载Sentinel.jar可以图形界面配置限流和降级规则 地址:可能需要翻墙 下载jar文件 2.引入maven依赖 <!-- spring cloud gateway整合sentinel的依赖--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-s…

从基础到卷积神经网络(第14天)

1. PyTorch 神经网络基础 1.1 模型构造 1. 块和层 首先&#xff0c;回顾一下多层感知机 import torch from torch import nn from torch.nn import functional as Fnet nn.Sequential(nn.Linear(20, 256), nn.ReLU(), nn.Linear(256, 10))X torch.rand(2, 20) # 生成随机…

苍穹外卖(七) Spring Task 完成订单状态定时处理

Spring Task 完成订单状态定时处理, 如处理支付超时订单 Spring Task介绍 Spring Task 是Spring框架提供的任务调度工具&#xff0c;可以按照约定的时间自动执行某个代码逻辑。 应用场景: 信用卡每月还款提醒 火车票售票系统处理未支付订单 入职纪念日为用户发送通知 点外…

C++:多态讲解

多态 1.多态的概念2.多态的定义和实现2.1多态构成条件2.2虚函数2.3虚函数的重写(覆盖)2.4 C11 override 和 final2.5重载、重写(覆盖)、隐藏(重定义)的对比 3.抽象类4.多态的原理5.单继承和多继承关系的虚函数表5.1单继承5.2多继承5.3菱形继承和多态 1.多态的概念 多态的概念&…

【Vue面试题二十三】、你了解vue的diff算法吗?说说看

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;你了解vue的diff算法吗&…

MFC-对话框

目录 1、模态和非模态对话框&#xff1a; &#xff08;1&#xff09;、对话框的创建 &#xff08;2&#xff09;、更改默认的对话框名称 &#xff08;3&#xff09;、创建模态对话框 1&#xff09;、创建按钮跳转的界面 2&#xff09;、在跳转的窗口添加类 3&#xff0…

树莓派:64位 RPI OS(Bookworm) 更换国内源

几天前新的RPI OS发布了。官方的发版说明里明确注明已经基于Debian Bookworm了。总的来说切到国内源&#xff08;清华&#xff09;跟Bullseye差不多&#xff0c;细节上只有一丢丢不同&#xff08;non-free变成了non-free-firmware&#xff09;。 老规矩&#xff0c;仍然是修改…

二、深度测试(Z Test)

1.是什么 ①从渲染管线出发 ②书面上理解 所谓深度测试&#xff0c;就是针对当前对象在屏幕上&#xff08;更准确的说是frame buffer&#xff09;对应的像素点&#xff0c;讲对象自身的深度值与当前该像素点缓存的深度值进行比较&#xff0c;如果通过了&#xff0c;本对象再改…

七、三层交换机不同网段通信实验

拓扑图&#xff1a; 首先将所有端口ip配置完毕&#xff0c;之后对SW1三层交换机进行配置 创建Vlan10 20网段 进入g0/0/1物理端口&#xff0c;只允许vlan10通过 再进入到g0/0/2端口配置允许通过vlan20的数据包 之后进入vlan的虚拟接口去配置网关ip&#xff0c;一定要先配置物理…

vue:diff库实现文本对比

官方文档 https://www.npmjs.com/package/diff 安装&#xff1a;npm install diff 内容 <template><div><div style"white-space: pre-line;display: flex;"><div><span class"default">{{oldStr}}</span></div&…

游游的字母串 (环形数组两点之间的位置)

题目链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 题目&#xff1a; 样例&#xff1a; 输入 yab 输出 3 思路&#xff1a; 暴力枚举&#xff0c;全部变成对应的26个字母字符需要的操作步数&#xff0c;取最少的一个操作步数&#xff0c; 这里的操作步数&#xff0…