第二部分 字符串算法 (第一章 字符串的处理) 例题

本文详细介绍了五个字符串处理的例题,包括数字反转、移位包含、单词替换、字符串环和生日相同的问题。针对每个问题,提供了思路分析,涉及到字符串操作如翻转、查找、替换等技巧,以及巧妙的解决方案,例如利用排序来解决生日相同的问题。

例题1 :数字反转 link

在这里插入图片描述

思路:
对于该题,我们其实并没有用字符串进行处理哦。
考虑小学c++入门知识,对于一个数反转过来,
只用不断乘10取个位就行了!

该题程序是窝以前写的,太丑勿喷!
#include<cstdio>
#include<iostream> 
using namespace std;
int main()
{
	int n,sum=0;
	cin>>n;
	while(n)
	{
		sum=sum*10+n%10;
		n/=10;
	}
	cout<<sum<<endl;
	return 0;
}

例题2 :移位包含 link

在这里插入图片描述

思路:

依题意,叫我们求是否能将A在翻转过程中的子串是B。

对于该题, 书上尽然手动模拟过程?(太草了

考虑先将A翻转一个整体后求出来,最后用find函数再找不就行了?

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
using namespace std;
string a, b;
int l1, l2;
int main()
{
	cin >> a >> b;
	l1 = a.size(), l2 = b.size();
	if(l1 < l2) swap(a, b);
	a = a + a;  //预处理出A翻转一个整体后的状态
	if(a.find(b, 0) != string::npos) printf("true\n");
	else printf("false\n");
} 

例题3 :单词替换 link

在这里插入图片描述
在这里插入图片描述

思路:

考虑用find函数再A中不断查找B, 再使用replace(开始位置,替换长度,替换内容)进行替换。

#include <cstdio>
#include <iostream>
#include <string>
using namespace std;
string s, a, b;
int main()
{
	getline(cin, s);
	cin >> a >> b;
	int len = a.size(), k = s.find(a, 0), l = k;
	while(k != string::npos)
	//find()找不到所给的字符串的位置时,返回-1(但为了兼容C++各种版本,最好写成string::npos)
	{
		s.replace(k, len, b);
		k = s.find(a, l + 1);
		l = k;
	}
	cout << s << endl;
	return 0;
}

例题4 :字符串环 link

在这里插入图片描述

#include <cstdio>
#include <iostream>
using namespace std;
string s1, s2;
int ans, l1, l2;
int main()
{
	cin >> s1 >> s2;
	l1 = s1.size(), l2 = s2.size();
	if(l1 > l2) swap(s1, s2), s1 = s1 + s1, s2 = s2 + s2;
	l1 = s1.size();
	for(int i = 0; i < l1 / 2; i++)
	 for(int  j = 1; j <= l1 / 2; j++)
	  if(s2.find(s1.substr(i, j)) != -1) 
	 	ans = max(ans, j);	
	printf("%d\n", ans); 
	return 0;
} 

思路:
跟例题二的思路类似,预处理出环的状态,暴力枚举子串在较短环中的初始位置,然后枚举长度。
判断该子串是否存在于另一个环中,max打擂台。

#include <cstdio>
#include <iostream>
using namespace std;
string s1, s2;
int ans, l1, l2;
int main()
{
	cin >> s1 >> s2;
	l1 = s1.size(), l2 = s2.size();
	if(l1 > l2) swap(s1, s2), s1 = s1 + s1, s2 = s2 + s2;
	l1 = s1.size();
	for(int i = 0; i < l1 / 2; i++)
	 for(int  j = 1; j <= l1 / 2; j++)
	  if(s2.find(s1.substr(i, j)) != -1) 
	 	ans = max(ans, j);	
	printf("%d\n", ans); 
	return 0;
} 

例题5 :生日相同 link

在这里插入图片描述

思路:
此题我们用一个比较巧的方法。
现将同学按多关键字排序(出生月,出生日,名字长度,名字字典序)。
接着试着输出排完序后各位同学的information,你会神奇发现。
相同生日的人在一起了,信息也按顺序排好了,最后我们
将其输出即可。(具体看代码

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10;
struct node
{
	int m, d;
	string name;
} p[N];
int n;
bool flag;
bool cmp(node a, node b)
{
	if(a.m != b.m) return a.m < b.m;
	else if(a.d != b.d) return a.d < b.d;
	else if(a.name.size() != b.name.size()) return a.name.size() < b.name.size();
	else return a.name < b.name;
}
int main()
{
	scanf("%d", &n);
	for(int i = 1; i <= n; i++) cin >> p[i].name >> p[i].m >> p[i].d;
	sort(p + 1, p + 1 + n, cmp); 
	for(int i = 1; i <= n; i++)
	{
		if(p[i].m == p[i + 1].m && p[i].d == p[i + 1].d)
		{
			printf("%d %d ", p[i].m, p[i].d);
			cout << p[i].name << ' ';
			while(p[i].m == p[i + 1].m && p[i].d == p[i + 1].d)
			{
				cout << p[i + 1].name << ' ', i++, flag = 1;
			}
			printf("\n");
		}
	}
	if(!flag) printf("None\n");
 	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值