c++可疑文件 一道字符串较新颖的题目(学过字符串的都看得懂!!)

这篇文章介绍了如何通过编程解决一个密码问题,即在模糊不清的字母中找到一个连续子串T,使得包含T的密码S在满足条件的情况下字典序最小。作者提供了C++代码示例和解题思路,强调了字符串操作和字典序的重要性。
摘要由CSDN通过智能技术生成

一.题目描述

基德发现了一个可能藏有宝藏的箱子。然而,箱子是锁着的。为了打开它,基德需要输入一个由小写英文字母组成的密码S。
基德在箱子边上发现了一张纸条,经过判断,发现这张纸条上记录了密码S',但是的一些字母因为年代原因模糊不清了,此处用'?'替换。
经过思考,基德找到了解密的方法:
1.密码S包含了一个连续的子串T
2.在满足1的所有字符串中,S是字典序最小的字符串。
如果存在这样的密码,输出S。否则输出UNRESTORABLE
输入
第一行一个字符串S'(长度不超过100),表示基德拿到的已经模糊不清的密码。
第二行一个字符串T(长度不超过100),表示密码S中的一个连续的子串。
输出
如果存在这样的密码,输出S。否则输出UNRESTORABLE
样例输入 Copy
【样例1】
?cmc????
coder
【样例2】
??p??d??
abc
样例输出 Copy
【样例1】
acmcoder
【样例2】
UNRESTORABLE

首先,先给各位介绍一个字符串的函数(只要是学过的人都应该懂啊),就是s.substr(i,L)。给不知道的读者简单介绍一下:substr()的功能是截取子串,比如说现在有一个字符串s为

  kidfover

那么s.substr(0,3)就是“kid”;substr()的用法如上所见是:substr(下标i,长度L),这样一来就可以截取从下标i开始长度为L的s的子串了。另外也是需要注意的是,当i + L >= s.size()时,substr就会在最后结尾,按照上面的例子来说就可以是:

   s.substr(5,8) = ver

有了上面的基础,这道题就变得很简单了。先上代码:

二.代码

#include<bits/stdc++.h>
#define MX 200000
using namespace std; 
int main()
{
    string s,t;
	int i,j;
	cin >> s >> t;
	int len = s.size(),lent = t.size(),f = 0;
	for (i = len - 1;i >= 0;i--)
    {
    	string st = s.substr(i,lent);
    	if (st == t)
		{
			int k2 = i,c2 = i + lent - 1;
			for (j = 0;j < k2;j++)
			{
				if (s[j] == '?')
				{
					cout << "a";
				}
				else
				{
					cout << s[j];
				}
		    }
		    cout << t;
		    for (j = c2 + 1;j < len;j++)
		    {
		    	if (s[j] == '?')
				{
					cout << "a";
				}
				else
				{
					cout << s[j];
				}
			}
			f = 1;
			break;
		}
	}
	if (f == 0)
	{
		for (i = len - 1;i >= 0;i--)
		{
			string st = s.substr(i,lent);
			int p = 0;
			for (j = 0;j < st.size();j++)
			{
				if (st[j] == t[j] || st[j] == '?')
				{
					p++;
				}
			}
			if (p == st.size() && st.size() == lent)
			{
				int k2 = i,c2 = i + lent - 1,p = -1;
				for (j = 0;j < k2;j++)
				{
					if (s[j] == '?')
					{
						cout << "a";
					}
					else
					{
						cout << s[j]; 
					}
			    }
			    cout << t;
			    for (j = c2 + 1;j < len;j++)
			    {
			    	if (s[j] == '?')
					{
						cout << "a";
					}
					else
					{
						cout << s[j]; 
					}
				}
				f = 1;
				break;
			}
		}
	}
	if (f == 0) 
	{
		cout << "UNRESTORABLE" << endl;
	}
    return 0;
}

三.程序部分

按照我的方法,就是要将整个程序分为三部分:第一部分是第10行-第42行,这一部分是来判断在不需要用到"?"的情况下,就可以找到一个字典序最小的字符串。比如说当s = kidtheik??   t = kid时,就不需要用到数据中的"?"了。为什么呢?因为虽然这个字符串可以变成kidtheikid(也就是将两个?变成id),但是字典序没有kidtheikaa大。也就是说,能不用“?”就不用,因为用了就会使字典序变大。

第二部分是43行-86行,这一部分是用来判断当需要用到“?”的情况下,找到一个字典序最小的字符串。比如说样例一。

第三部分是剩下的代码,这一部分是用来判断无法找到字符串的情况。比如样例二。

四.解题思路

贯通于第一,第二部分的思路就是利用刚刚给大家介绍的函数s.substr()来做题。

首先,让字符串st = s.substr(i,lent),也就是从s的下标i,长度为lent的子串;然后再利用第二层循环遍历st,看看st和字符串t是否一致,注意,当st[j] = '?'时,就可以不用管,也就是权当它与t[j]相同。如果st的一个字符都与t相同(?除外),就输出st。

最后的输出也要有技巧(我的输出只是一种,某些大神有比我更好的解法),当j是在st在s的初始端点的左边时(j < k2)遇到“?”就输出a(因为要保证字典序最小),如果不是“?”直接输出s[j],在(j >= k2 && j <= c2)时,直接输出t;在(j > c2)时,与在(j < k2)时一样。

此外还要有一个变量f充当“线索”贯穿整个程序,在f最后仍然等于0时,就说明没有结果(st),就输出“UNRESTORABLE”。

五.注意事项

字符串st表示的是字符串s中的一个子串(可能有“?”)t可以看成是st中除了“?”都与st相同的字符串(无“?”);这两点要区分好,否则就会想我一样没搞好关系,第一次错了85%。

六.

      

                                                  -加上这个才算完美-

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值