IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> B - Combine String (思维,不用DP直接for干就完事了) -> 正文阅读

[数据结构与算法]B - Combine String (思维,不用DP直接for干就完事了)

目录

题目如下:

?中文翻译:

思路

我们可以发现什么:

AC代码如下(带简单的注释)

代码 单独拉出 边界特判(再次强调一下)


题目如下:

Given three strings a, b and c, your mission is to check whether c is the combine string of aaa and bbb.
A string c is said to be the combine string of a and b if and only if c can be broken into two subsequences, when you read them as a string, one equals to aaa, and the other equals to bbb.
For example, ``adebcf'' is a combine string of ``abc'' and ``def''.

Input

Input file contains several test cases (no more than 20). Process to the end of file.
Each test case contains three strings a, b and c (the length of each string is between 1 and 2000).

Output

For each test case, print ``Yes'', if c is a combine string of a and b, otherwise print ``No''.

Sample

InputOutput
 
abc def adebcf abc def abecdf 
 
Yes No 

?中文翻译:

给定三个字符串a、b和c,你的任务是检查c是否是a和b的组合字符串。 字符串c被称为a和b的组合字符串,当且仅当c可以被分解为两个子序列时,当你将它们作为字符串读取时,一个等于a,另一个等于b。 例如,“adebcf”是“abc”和“def”的组合字符串。

输入文件包含几个测试用例(不超过20个)。处理到文件末尾。 每个测试用例包含三个字符串a、b和c(每个字符串的长度在1到2000之间)。

对于每个测试用例,如果c是a和b的组合字符串,则打印“是”,否则打印“否”。

思路

我们可以把a串所有元素拆开,然后按相对位置关系固定起来,再把b串所有元素拆开按相对位置关系插入进去

如果不好理解,我直接上图帮助大家理解这个思路 (:? Q^Q

读者大大们可以多弄几个,理解一下这个思想!!!

我们可以发现什么:

如果可以满足题意(c串切成两个子串,两个子串正好分别等于a串,b串)

从左到右依次匹配a,b串,一定可以匹配成功的

证明:

我们可以结合上面,按相对位置关系固定a串元素,将b串元素按相对位置关系插入到里面 这个思想去证明!

简单来说(用人话来说):如果可以满足题意,c串一定是可以按照上面的方式构造出来,我们按照上面方式依次匹配,如果可以匹配完成则是Yes,否则是No。

似乎上面说的是很好,但是聪明的你会发现

如果是:

a:ab

b:ba

c:abab

a串先匹配一个后变成下面情况:

a:b

b:ba

c:bab

不难发现,a串与b串都可以匹配c串的b

那怎么办?

如果存在歧义(两串都可以匹配到),我们就接着往下看(看之后的匹配状态)

b串的a可以匹配c串的a并且b串无法匹配成功,那我们就解决了上面的歧义,我们可以把c串的b给b串

这样做一定是正确的嘛?

下面是简单的证明:

因为我们要保证a与b串自身的相对位置关系,所以我们解决 歧义 要在 相对位置关系的保持不变的前提下进行解决,这恰恰就是这个题的核心 & 操纵正确性的证明

举个例子:

如果c串的b给a串,a已完全匹配成功,c串剩下ab,b串剩下ba,发现b串已经无法匹配c串,但这个样例明明是Yes啊(可以完全匹配成功),这是因为我们已经破环了a与b串自身的相对位置关系了。

ps:可能讲的有点模糊,自身水平有限,希望您可以多看几遍思想,按这个思想多模拟几个样例,我想聪明的读者应该可以粗略的理解这个思想的可行性与正确性!

(:(:(:

还有一点需要特别注意欧!!!

一定要特别注意一下边界问题

类似:

a:aaaa

b:aaaa

c:aaaaaaaa

因为一直存在歧义,如果都匹配到头还是存在歧义的话,那就随便让一个串匹配就好啦!

AC代码如下(带简单的注释)

#include <bits/stdc++.h>
#define buff                     \
    ios::sync_with_stdio(false); \
    cin.tie(0);                  \
    cout.tie(0)
using namespace std;
const int N = 2009;
char a[N], b[N], c[N], d[N];
int na, nb, nc;
bool flag;
int main()
{
    buff;
    while (cin >> a)
    {
        cin >> b;
        cin >> c;
        flag = 1;
        na = strlen(a);
        nb = strlen(b);
        nc = strlen(c);
        if (nc != (na + nb))
        {
            puts("No");
            continue;
        }
        int i = 0, j = 0;
        for (int k = 0; k < nc; k++)
        {
            if (a[i] == c[k] && b[j] != c[k])//a可以匹配上(无分歧)
                i++;
            else if (a[i] != c[k] && b[j] == c[k])//b可以匹配上(无分歧)
                j++;
            else if (a[i] != c[k] && b[j] != c[k])//a,b都匹配不上,匹配直接失败
            {
                flag = 0;
                break;
            }
            else//a,b都匹配上,出现分歧(不知道到底让谁匹配,开始进行讨论)
            {
                int x = i + 1, y = j + 1;
                int ok = 0;//无答案(匹配失败)
                int z = k + 1;
                while (1)
                {
                    //辅助作用
                    // //----------下面是边界特判
                    // if(z==nc)
                    // break;
                    // if (x == na && y == nb)//匹配到头还是有歧义,那就随便让一个串匹配成功
                    // {
                    //     ok = 1;
                    //     break;
                    // }
                    // else if (x == na && y != nb)//就剩b可以匹配
                    // {
                    //     ok = 2;
                    //     break;
                    // }
                    // else if (y == nb && x != na)//就剩a可以匹配
                    // {
                    //     ok = 1;
                    //     break;
                    // }
                    // //-----------上面是边界特判

                    if (a[x] == c[z] && b[y] != c[z])//a匹配成功&b匹配失败,歧义解决
                    {
                        ok = 1; // a匹配
                        break;
                    }
                    else if (a[x] != c[z] && b[y] == c[z])//b匹配成功&a匹配失败,歧义解决
                    {
                        ok = 2; // b匹配
                        break;
                    }
                    else if (a[x] != c[z] && b[y] != c[z])//没有匹配成功但c没有匹配完,匹配接着进行
                    {
                        z++;
                        continue;
                    }
                    else//还是存在歧义,再往后看,看是否可以解决这个歧义
                    {
                        x++, y++, z++;
                    }
                }
                if (ok == 0)//匹配失败
                {
                    flag = 0;
                    break;
                }
                else if (ok == 1)//a匹配
                {
                    i++;
                }
                else//b匹配
                {
                    j++;
                }
            }
        }
        if (flag)
            puts("Yes");
        else
            puts("No");
    }
}

代码 单独拉出 边界特判(再次强调一下)

if (a[x] == c[z] && b[y] != c[z]) // a匹配成功&b匹配失败,歧义解决
{
    ok = 1; // a匹配
    break;
}
else if (a[x] != c[z] && b[y] == c[z]) // b匹配成功&a匹配失败,歧义解决
{
    ok = 2; // b匹配
    break;
}
else if (a[x] != c[z] && b[y] != c[z]) //没有匹配成功但c没有匹配完,匹配接着进行
{
    z++;
    continue;
}
else //还是存在歧义,再往后看,看是否可以解决这个歧义
{
    x++, y++, z++;
}

?我们一路奋战,不是为了改变世界,而是为了不让世界改变我们。——《熔炉》

最后感谢您的阅读!!!

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-04-26 12:01:51  更:2022-04-26 12:01:57 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 8:49:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码