这篇博客只是记录一下我在做题过程中碰到的一些关于字符串巧妙的处理方式(可能只对我这个菜鸡来说相对巧妙吧)
1、stringstream的使用
第一次碰到stringstream的使用是在紫书上面p112,题目是UVA10815。前几天补字符串的题目的时候在 洛谷P1308统计单词数 也碰到了一题可以使用stringstream的。
用法
有一个带空格的字符串s,现在需要从里面提取一个个的单词,那可以进行如下操作。从s字符串中提取出一个个单词,通过stringstream传递给word,然后输出每一个单词
string s, word;
stringstream ss(s);
while(ss>>word) cout<<word<<endl;
2、string库中函数的使用
这边将介绍的是find函数和replace函数
大水题poj3981 题目就是要你把字符串中所有的"you"替换成"we"
用法
string str, s;
int pos=str.find(s); //pos返回值是s首字母的下标位置
str.replace(pos, n, s); //把str字符串从第pos位开始后的n位换成字符串s
代码片
//poj-3981
#include<bits/stdc++.h>
using namespace std;
int main() {
string s;
int pos;
while(getline(cin,s)) {
while( (pos=s.find("you"))!=-1 )
s.replace(pos,3,"we");
cout<<str<<endl;
}
return 0;
}
3、substr的使用以及reverse
这个是前几天在codeforces上打比赛碰到的。场次是 CodeCraft-20 (Div. 2), 题目是 B. String Modification 。
题目描述
给定一个字符串s,给一个数字k表示以下操作:从该字符串 第1 到 第n-k+1 位,每次将字符串从第 i 位到第 i+k-1位进行反转。
求一个 k 使得该字符串最小,并输出反转的字符串
思路
可以发现就是进行k次操作表示将字符串第k位前移,把第1位到第k位放到后面去,而第1位到第k位放到后面去是有两种情况的,可能是正放,也可能是逆放。就看交换次数,奇数次逆放,偶数次正放。我就开了两个字符串暴力做。
用法
s.substr(n,m); //表示在s字符串中从第n位开始取m个字符
reverse(s.begin(), s.end()); //表示将整个字符串反转
代码片
#include<bits/stdc++.h>
using namespace std;
void solve() {
string s1,s2,str;
int n;
cin>>n;
cin>>s1;
reverse(s1.begin(), s1.end());
s2=s1; //让s2字符串逆序
reverse(s1.begin(), s1.end());
int ans=1;
str=s1;
string tmp;
for(int i=1; i<n; i++) {
//如果交换次数是奇数,后面部分就需要逆放了,此时用到s2字符串
if ( (n-i)&1 ) tmp=s1.substr(i,n-i)+s2.substr(n-i,i);
//正放就原处理就行了
else tmp=s1.substr(i,n-i)+s1.substr(0,i);
if ( tmp<str ) {
str=tmp;
ans=i+1;
}
}
cout<<str<<endl;
cout<<ans<<endl;
}
int main() {
// freopen("in.txt","r",stdin);
int t;
scanf("%d",&t);
while(t--) {
solve();
}
return 0;
}