字符串相关问题
字符串的相关语法问题
1.字符串中的数字个数
输入一行字符,长度不超过 100,请你统计一下其中的数字字符的个数
#include<iostream>
using namespace std;
int main(){
char c;
int numbers=0;
while(cin>>c){
if(c<='9'&&c>='0') numbers++;
}
cout<<numbers<<endl;
}
//I am 18 years old this year.
cin和scanf读入字符串时遇到空格、回车、结束均会停止
//字符串就是字符数组加上结束符‘\0’。
char a[]="c++";
cout<<sizeof a<<endl;
输出结果:
4
读入一行(可接受空格)
char s[100];
fgets(s,100,stdin);//仅针对字符数组,且必须留一个位置给结束符
cout<<s;
char c;
string s;
while(cin>>c,c!=',') s+=c;
输出字符串
char s[100];
puts(s);//puts只针对字符数组有效,自带换行
字符数组中常用函数
//需要加
#include<string.h>
char s[100];
fgets(s,45,stdin);
cout<<strlen(s)<<endl; //此函数只能用于字符数组,不能用于string,输出的是正常字符长度,不包括结束符
strcmp(str1,str2);//str1和str2比较 大于是1,小于是-1等于是0
char s1[100],s2[100];
cin>>s1>>s2;
cout<<strcpy(s1,s2)<<endl; //先把s1清空,后将s2的内容赋值给s1
2.只出现一次的字符
给你一个只包含小写字母的字符串。
请你判断是否存在只在字符串中出现过一次的字符。
如果存在,则输出满足条件的字符中位置最靠前的那个。
如果没有,输出 no
输入格式
共一行,包含一个由小写字母构成的字符串。
数据保证字符串的长度不超过 100000。
输出格式
输出满足条件的第一个字符。
如果没有,则输出 no
。
输入样例:
abceabcd
输出样例:
e
//思路:因为总的数字是有限的,不妨开辟一个26个字母的数组,进行每个字母的统计,输出靠前的即可。
#include<iostream>
#include<cstring>
using namespace std;
const int N=1e5+10;
char a[N];
int cnt[26];
int main(){
cin>>a;
int len=strlen(a);
for(int i=0;i<len;i++){
cnt[a[i]-'a']++; //后面的折回来和前面的一合并,统计的是出现的总次数
}
for(int i=0;i<len;i++){
if(cnt[a[i]-'a']==1)
{
cout<<a[i]<<endl;
return 0; //直接退出程序,不必设置旗帜
}
}
puts("no");
return 0;
}
3.替换字符
给定一个由大小写字母构成的字符串。
把该字符串中特定的字符全部用字符 #
替换。
请你输出替换后的字符串。
输入格式
输入共两行。
第一行包含一个长度不超过 30 的字符串。
第二行包含一个字符,表示要替换掉的特定字符。
输出格式
输出共一行,为替换后的字符串。
输入样例:
hello
l
输出样例:
he##o
#include<iostream>
#include<string.h>
using namespace std;
char a[35];
int main(){
cin>>a; //不包含空格,直接用cin和scanf读入即可
char c;
cin>>c;
int len=strlen(a);
for(int i=0;i<len;i++){
if(a[i]==c)
a[i]='#';
}
puts(a);
return 0;
}
string动态开空间
string s1; //默认为空字符串
string s2=s1;
string s3="hiya";
string s4(10,'c');
//输入
getline(cin,s1);
cin.getline(s2,1000);
getline(cin,s,',');//以第一个逗号之前的结尾
//示例
//sadklkdf,skafljk,safkjl,sfkdl;sf
//sadklkdf
//输出
printf("%s\n",s1.c_str());
//长度,比strlen快
s.size();
//相加,其中一个必须是string类型
s3=s1+s2;
//也可以加字符串
//遍历
for(int i=0;i<s.size();i++)
cout<<s[i]<<endl;
for(char c:s) cout<<c<<endl;
//顺次遍历,c是变量副本
for(char &c:s) c='a';
//顺次遍历,加取地址符可改变s的内容
//插入字符串
s1.insert(3,s2);//某个位置后插入字符串
//分割字符串
s.substr(0,5); //获得字符串s中从第0位开始的长度为5的字符串
4.信息加密
在传输信息的过程中,为了保证信息的安全,我们需要对原信息进行加密处理,形成加密信息,从而使得信息内容不会被监听者窃取。
现在给定一个字符串,对其进行加密处理。
加密的规则如下:
- 字符串中的小写字母,a 加密为 b,b 加密为 c,…,y 加密为 z,z 加密为 a。
- 字符串中的大写字母,A 加密为 B,B 加密为 C,…,Y 加密为 Z,Z 加密为 A。
- 字符串中的其他字符,不作处理。
请你输出加密后的字符串。
输入格式
共一行,包含一个字符串。注意字符串中可能包含空格。
输出格式
输出加密后的字符串。
数据范围
输入字符串的长度不超过 100。
输入样例:
Hello! How are you!
输出样例:
Ifmmp! Ipx bsf zpv!
#include<iostream>
using namespace std;
int main(){
string s;
getline(cin,s);
for(auto &c:s)
{
if(c>='a'&&c<='y'||c>='A'&&c<='Y')
c=c+1;
else if(c=='z')
c='a';
else if(c=='Z')
c='A';
}
cout<<s;
return 0;
}
5.循环相克
循环相克令是一个两人玩的小游戏。
令词为“猎人、狗熊、枪”,两人同时说出令词,同时做出一个动作——猎人的动作是双手叉腰;狗熊的动作是双手搭在胸前;枪的动作是双手举起呈手枪状。
双方以此动作判定输赢,猎人赢枪、枪赢狗熊、狗熊赢猎人,动作相同则视为平局。
现在给定你一系列的动作组合,请你判断游戏结果。
输入格式
第一行包含整数 T,表示共有 T 组测试数据。
接下来 T 行,每行包含两个字符串,表示一局游戏中两人做出的动作,字符串为 Hunter
, Bear
, Gun
中的一个,这三个单词分别代表猎人,狗熊和枪。
输出格式
如果第一个玩家赢了,则输出 Player1
。
如果第二个玩家赢了,则输出 Player2
。
如果平局,则输出 Tie
。
数据范围
1≤N≤100
输入样例
3
Hunter Gun
Bear Bear
Hunter Bear
输出样例
Player1
Tie
Player2
#include<iostream>
using namespace std;
int main(){
string s1,s2;
int n;
cin>>n;
while(n--)
{
cin>>s1>>s2;
if(s1==s2){
cout<<"Tie"<<endl;
}
else if(s1=="Hunter"&&s2=="Bear"||s1<s2&&(s1!="Bear"||s2!="Hunter")){
cout<<"Player2"<<endl;
}
else
cout<<"Player1"<<endl;
}
return 0;
}
6.字符串加空格
给定一个字符串,在字符串的每个字符之间都加一个空格。
输出修改后的新字符串。
输入格式
共一行,包含一个字符串。注意字符串中可能包含空格。
输出格式
输出增加空格后的字符串。
数据范围
1≤字符串长度≤100
输入样例:
test case
输出样例:
t e s t c a s e
#include<iostream>
using namespace std;
int main(){
string s;
getline(cin,s);
for(auto &c:s){
cout<<c<<" ";
}
cout<<endl;
return 0;
}
7.字符串插入
有两个不包含空白字符的字符串 str 和 substr,str 的字符个数不超过 10,substr 的字符个数为 3。(字符个数不包括字符串结尾处的 \0
。)
将 substr 插入到 str 中 ASCII 码最大的那个字符后面,若有多个最大则只考虑第一个。
输入格式
输入包括若干行,每一行为一组测试数据,格式为
str substr
输出格式
对于每一组测试数据,输出插入之后的字符串。
输入样例:
abcab eee
12343 555
输出样例:
abceeeab
12345553
#include<iostream>
#include<string>
using namespace std;
int main(){
string s1,s2;
while(cin>>s1>>s2){
int t=0;
char c=s1[0];
for(int i=1;i<s1.size();i++){
if(s1[i]>c){
t=i;
c=s1[i];
}
}
s1.insert(t+1,s2); //字符串插入函数
cout<<s1<<endl;
}
return 0;
}
8.字符串匹配
给定两个长度相同的字符串 a 和字符串 b。
如果在某个位置 i 上,满足字符串 a 上的字符 a[i] 和字符串 b 上的字符 b[i] 相同,那么这个位置上的字符就是匹配的。
如果两个字符串的匹配位置的数量与字符串总长度的比值大于或等于 k,则称两个字符串是匹配的。
现在请你判断给定的两个字符串是否匹配。
输入格式
第一行包含一个浮点数 k,第二行包含字符串 a,第三行包含字符串 b。
输入的字符串中不包含空格。
输出格式
如果两个字符串匹配,则输出 yes
。
否则,输出 no
。
数据范围
0≤k≤1,
字符串的长度不超过 100。
输入样例:
0.4
abcde
xbacd
输出样例:
no
#include<iostream>
using namespace std;
float cnt;
int main(){
float x;
cin>>x;
string s1,s2;
cin>>s1>>s2;
for(int i=0;i<s1.size();i++){
if(s1[i]==s2[i])
cnt++;
}
if(cnt/s1.size()>=x) cout<<"yes"<<endl;
else cout<<"no"<<endl;
return 0;
}
9.忽略大小写比较字符串大小
一般我们用 strcmp 可比较两个字符串的大小,比较方法为对两个字符串从前往后逐个字符相比较(按 ASCII 码值大小比较),直到出现不同的字符或遇到 \0
为止。
如果全部字符都相同,则认为相同;如果出现不相同的字符,则以第一个不相同的字符的比较结果为准。
但在有些时候,我们比较字符串的大小时,希望忽略字母的大小,例如 Hello
和 hello
在忽略字母大小写时是相等的。
请写一个程序,实现对两个字符串进行忽略字母大小写的大小比较。
输入格式
输入为两行,每行一个字符串,共两个字符串。注意字符串中可能包含空格。
数据保证每个字符串的长度都不超过 80。
输出格式
如果第一个字符串比第二个字符串小,输出一个字符 <
。
如果第一个字符串比第二个字符串大,输出一个字符 >
。
如果两个字符串相等,输出一个字符 =
。
输入样例:
Hello
hello
输出样例:
=
#include<iostream>
using namespace std;
int main(){
string s1,s2;
getline(cin,s1);
getline(cin,s2);
for(int i=0;i<s1.size();i++){
if(s1[i]<='Z'&&s1[i]>='A'){
s1[i]=s1[i]-'A'+'a';
}
}
for(int i=0;i<s2.size();i++){
if(s2[i]<='Z'&&s2[i]>='A'){
s2[i]=s2[i]-'A'+'a';
}
}
if(s1>s2) cout<<">"<<endl;
else if(s1==s2) cout<<"="<<endl;
else cout<<"<"<<endl;
return 0;
}
10. 去掉多余的空格
输入一个字符串,字符串中可能包含多个连续的空格,请将多余的空格去掉,只留下一个空格。
输入格式
共一行,包含一个字符串。
输出格式
输出去掉多余空格后的字符串,占一行。
数据范围
输入字符串的长度不超过 200。
保证输入字符串的开头和结尾没有空格。
输入样例:
Hello world.This is c language.
输出样例:
Hello world.This is c language.
//1.利用c++机制
#include<iostream>
using namespace std;
int main(){
string s;
while(cin>>s){
cout<<s<<" ";
}
return 0;
}
//2.双指针算法
//新开一个字符串,赋值即可
#include<iostream>
using namespace std;
int main(){
string s;
getline(cin,s);
string r;
for(int i=0;i<s.size();i++){
if(s[i]!=' ') r+=s[i];
else{
r+=" ";
int j=i;
while(j<s.size()&&s[j]==' ') j++; //指针指到没有连续空格的地方
i=j-1;
}
}
cout<<r<<endl;
return 0;
}
11.输出字符串
给定一个字符串 a,请你按照下面的要求输出字符串 b。
给定字符串 a 的第一个字符的 ASCII 值加第二个字符的 ASCII 值,得到 b 的第一个字符;
给定字符串 a 的第二个字符的 ASCII 值加第三个字符的 ASCII 值,得到 b 的第二个字符;
…
给定字符串 a 的倒数第二个字符的 ASCII 值加最后一个字符的 ASCII 值,得到 b 的倒数第二个字符;
给定字符串 a 的最后一个字符的 ASCII 值加第一个字符的 ASCII 值,得到 b 的最后一个字符。
输入格式
输入共一行,包含字符串 a。注意字符串中可能包含空格。
数据保证字符串内的字符的 ASCII 值均不超过 63。
输出格式
输出共一行,包含字符串 b。
数据范围
2≤a的长度≤100
输入样例:
1 2 3
输出样例:
QRRSd
#include<iostream>
#include<string>
using namespace std;
int main(){
string s,s1(100,' '); //动态开数组
getline(cin,s);
for(int i=0;i<s.size()-1;i++){
s1[i]=s[i]+s[i+1];
}
s1[s.size()-1]=s[s.size()-1]+s[0];
cout<<s1<<endl;
return 0;
}
12.单词替换
输入一个字符串,以回车结束(字符串长度不超过100)。
该字符串由若干个单词组成,单词之间用一个空格隔开,所有单词区分大小写。
现需要将其中的某个单词替换成另一个单词,并输出替换之后的字符串。
输入格式
输入共 3 行。
第 1 行是包含多个单词的字符串 s;
第 2 行是待替换的单词 a(长度不超过 100);
第 3 行是 a 将被替换的单词 b(长度不超过 100)。
输出格式
共一行,输出将 s 中所有单词 a 替换成 b 之后的字符串。
输入样例:
You want someone to help you
You
I
输出样例:
I want someone to help you
#include<iostream>
#include<string>
using namespace std;
string a[1000];
int main(){
int i=0;
while(cin>>a[i]) i++; //利用cin遇到空格中断机制,核心代码
for(int k=0;k<i-2;k++){
if(a[k]==a[i-2]) cout<<a[i-1];
else cout<<a[k];
cout<<" ";
}
return 0;
}
13. 字符串中最长的连续出现的字符
求一个字符串中最长的连续出现的字符,输出该字符及其出现次数,字符串中无空白字符(空格、回车和 tabtab),如果这样的字符不止一个,则输出第一个。
输入格式
第一行输入整数N
,表示测试数据的组数。
每组数据占一行,包含一个不含空白字符的字符串,字符串长度不超过 200。
输出格式
共一行,输出最长的连续出现的字符及其出现次数,中间用空格隔开。
输入样例:
2
aaaaabbbbbcccccccdddddddddd
abcdefghigk
输出样例:
d 10
a 1
#include<iostream>
#include<string>
using namespace std;
int main(){
int n;
cin>>n;
while(n--){
string str;
cin>>str;
char c;
int cnt=0;
for(int i=0;i<str.size();i++){
int j=i;
while(j<str.size()&&str[i]==str[j]) j++;
if(j-i>cnt) {cnt=j-i;c=str[i];}
i=j-1;
}
cout<<c<<" "<<cnt<<endl;
}
return 0;
}
14.最长单词
一个以 .
结尾的简单英文句子,单词之间用空格分隔,没有缩写形式和其它特殊形式,求句子中的最长单词。
输入格式
输入这个简单英文句子,长度不超过 500500。
输出格式
该句子中最长的单词。如果多于一个,则输出第一个。
输入样例:
I am a student of Peking University.
输出样例:
University
#include<iostream>
#include<string>
using namespace std;
string a[505];
int main(){
int k=0,cnt=0,t;
while(cin>>a[k]) k++;
for(int i=0;i<k-1;i++){
if(a[i].size()>cnt) {cnt=a[i].size(); t=i;}
}
if((a[k-1].size()-1)>cnt)
cout<<a[k-1].substr(0,a[k-1].size()-1)<<endl; //字符串分割从0开始,取a[k-1].size()-1个元素
else
cout<<a[t]<<endl;
return 0;
}
15.倒排单词
编写程序,读入一行英文(只包含字母和空格,单词间以单个空格分隔),将所有单词的顺序倒排并输出,依然以单个空格分隔。
输入格式
输入为一个字符串(字符串长度至多为 100100)。
输出格式
输出为按要求排序后的字符串。
输入样例:
I am a student
输出样例:
student a am I
#include<iostream>
using namespace std;
string a[110];
int main(){
int k=0;string s;
while(cin>>a[k]) k++;
for(int i=k-1;i>=0;i--){
cout<<a[i]<<" ";
}
return 0;
}
16. 字符串移位包含问题
对于一个字符串来说,定义一次循环移位操作为:将字符串的第一个字符移动到末尾形成新的字符串。
给定两个字符串 s1 和 s2,要求判定其中一个字符串是否是另一字符串通过若干次循环移位后的新字符串的子串。
例如 CDAA
是由 AABCD
两次移位后产生的新串 BCDAA
的子串,而 ABCD
与 ACBD
则不能通过多次移位来得到其中一个字符串是新串的子串。
输入格式
共一行,包含两个字符串,中间由单个空格隔开。
字符串只包含字母和数字,长度不超过 30。
输出格式
如果一个字符串是另一字符串通过若干次循环移位产生的新串的子串,则输出 true
,否则输出 false
。
输入样例:
AABCD CDAA
输出样例:
true
//自己琢磨的粗暴做法
//令每个字符串循环len次(len为自己的长度)
//13ms
#include<iostream>
#include<string>
using namespace std;
int main(){
string a1,s1,s2;
cin>>s1>>s2;
if(s1.size()<s2.size()) swap(s1,s2);
for(int i=0;i<s1.size();i++){
a1+=s1;
}
for(int i=0;i<a1.size();i++){
int j=i,t=0;
while(j<a1.size()&&a1[j]==s2[t]) {j++;t++;}
if(t==s2.size())
{ cout<<"true"<<endl;
return 0;}
}
cout<<"false"<<endl;
return 0;
}
//简单做法
#include<iostream>
using namespace std;
int main(){
string s1,s2;
cin>>s1>>s2;
if(s1.size()<s2.size()) swap(s1,s2);
//移位s1.size()次
for(int i=0;i<s1.size();i++){
s1=s1.substr(1)+s1[0];
int j;
//搜索s1串
for(int k=0;k+s2.size()<=s1.size();k++){
//匹配s2串
for(j=0;j<s2.size();j++){
if(s1[k+j]!=s2[j]) break;
}
if(j==s2.size()) { puts("true");return 0;}
}
}
puts("false");
return 0;
}
17.字符串乘方
给定两个字符串 a 和 b,我们定义 a×b 为他们的连接。
例如,如果 a=abc
而 b=def
, 则 a×b=abcdef
。
如果我们将连接考虑成乘法,一个非负整数的乘方将用一种通常的方式定义:a0=``(空字符串),a(n+1)=a×(a(n))。
输入格式
输入包含多组测试样例,每组测试样例占一行。
每组样例包含一个字符串 s,s的长度不超过 100。
最后的测试样例后面将是一个点号作为一行。
输出格式
对于每一个 s,你需要输出最大的 n,使得存在一个字符串 a,让 s=a(n)。
输入样例:
abcd
aaaa
ababab
.
输出样例:
1
4
3
#include<iostream>
using namespace std;
int main(){
string s;
while(cin>>s,s!="."){
int len=s.size();
for(int n=len;n>=1;n--){
if(len%n==0){
int m=len/n;
string s1,s2;
s1=s.substr(0,m);
for(int i=0;i<n;i++) s2+=s1;
if(s2==s) {
cout<<n<<endl;
break; //跳出for循环
}
}
}
}
return 0;
}
18.字符串最大跨距
有三个字符串 S,S1,S2,其中,S 长度不超过 300,S1 和S2 的长度不超过 10。
现在,我们想要检测 S1 和S2 是否同时在 S 中出现,且 S1 位于 S2 的左边,并在 S 中互不交叉(即,S1 的右边界点在 S2 的左边界点的左侧)。
计算满足上述条件的最大跨距(即,最大间隔距离:最右边的 S2 的起始点与最左边的 S1 的终止点之间的字符数目)。
如果没有满足条件的 S1,S2 存在,则输出 −1。
例如,S= abcd123ab888efghij45ef67kl
, S1= ab
, S2= ef
,其中,S1 在 S 中出现了 2 次,S2 也在 S 中出现了 2 次,最大跨距为:18。
输入格式
输入共一行,包含三个字符串S,S1,S2,字符串之间用逗号隔开。
数据保证三个字符串中不含空格和逗号。
输出格式
输出一个整数,表示最大跨距。
如果没有满足条件的 S1 和 S2 存在,则输出 −1。
输入样例:
abcd123ab888efghij45ef67kl,ab,ef
输出样例:
18
//求最大跨距,分两侧遍历即可
#include<iostream>
#include<cstdio>
using namespace std;
int main(){
string s,s1,s2;
int l=-1,r=-1;
//输入
getline(cin,s,',');//以第一个逗号之前的结尾
getline(cin,s1,',');
getline(cin,s2);
//求最左边位置
int k=0;
for(int i=0;i<s.size();i++){
int j=i;
//检测最右端点
while(j<s.size()&&s[j]==s1[k]) {j++;k++;}
if(k==s1.size()) { l=j-1;break;}
else k=0;
}
//求最右边位置
int t=s2.size();
for(int i=s.size();i>=0;i--){
int j=i;
//t-1是考虑从下标计数
while(j>=0&&t>=0&&s[j]==s2[t-1]) {j--;t--;}
if(t==0) { r=j+1;break;}
else t=s2.size();
}
if(r>l&&l>=0)
cout<<r-l-1<<endl;
else cout<<-1<<endl;
return 0;
}
19.最长公共字符串后缀
给出若干个字符串,输出这些字符串的最长公共后缀。
输入格式
由若干组输入组成。
每组输入的第一行是一个整数 N。
N 为 0 时表示输入结束,否则后面会继续有 N 行输入,每行是一个字符串(字符串内不含空白符)。
每个字符串的长度不超过 200。
输出格式
共一行,为 N 个字符串的最长公共后缀(可能为空)。
数据范围
1≤N≤200
输入样例:
3
baba
aba
cba
2
aa
cc
2
aa
a
0
输出样例:
ba
a
#include<iostream>
using namespace std;
const int N=200;
string str[N];
int n;
int main(){
while(cin>>n,n){
int len=200;
for(int i=0;i<n;i++) {
cin>>str[i];
if(len>str[i].size())
len=str[i].size();
}
while(len){
int i;
//判断除第一个外是否满足条件
for(i=1;i<n;i++){
int j;
for(j=1;j<=len;j++)
{
//不成功跳出其他剩余字母匹配
if(str[0][str[0].size()-j]!=str[i][str[i].size()-j]){
break;
}
}
//说明是终止,并不匹配跳出与其他几个的字母匹配
if(j<=len){
break;
}
}
//不成功继续搜索,缩小字符的数量
if(i!=n) {len--;}
//成功跳出while循环
else break;
}
cout<<str[0].substr(str[0].size()-len)<<endl;
}
return 0;
}
第一类双指针算法
int j=i;
while(j<s.size()&&s[j]==' ') j++; //指针指到没有连续空格的地方
i=j-1;
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程