第五节、字符串
第一节 基础知识
1.每个字符都有对应的整数ASCII码,常用ASCII值,’A''Z'是6590,‘a''z'是97122,’0‘’9'是4857,字符可以参与运算,运算时会将其当作整数。(记住)
计算机里面的所有字符是-128~127的数字两者之间可以相互转换。
整数与ASCII码转换的关系
#include <iostream>
using namespace std;
int main()
{
//强制类型转换
char c = 'a';
cout<< (int)c <<endl;
int a=66;
cout << (char)a <<endl;
return 0;
for(int i=1;i<128;i++) printf("%d: %c\n",i,(char)i);
printf("%c\n",'a'+3);//输出d
printf("%d\n",'b'-'a');//输出差,1
int a='B'-'A';
int b='A'*'B';
char c='A'+2;
cout << a <<endl;//1
cout << b <<endl;//4290=65*66
cout << c <<endl;//C
return 0;
}
2.字符数组
字符串就是字符数组加上结束符‘\0’,可以使用字符串来初始化字符数组,但要注意,每个字符串结尾会暗含一个‘\0’字符,因此字符串数组的长度至少比字符串数组的长度多1
#include <string.h>为头文件
char a1[]={'C','+','+'};//列表初始化,没有空字符
char a2[]={'C','+','+','\0'};//列表初始化,含有显示的空字符
char a3[]='C++';//a2[]和a3[]一样都是四个都是字符数组,a1[]是字符串,\0是空字符。自动添加表示字符串结尾的空字符
printf("%s\n",a3);//输出:c++
cout<<a3<<endl;//输出c++
char a2[]={'A','B','C','\0'};
char a3[]="ABCDEF";
cout << a2+1<<endl;//输出BC,从1开始输出
printf("%s\n",a3+2);//输出CDEF,从第二个开始输出,跟指针类似
return 0;
char s[100]
scanf("%s",s);//一定不要加&符号,因为字符串s本身就是一个指针
cout << s <<endl;//读入abcdef,输出abcdef
return 0;
char s[100];
cout << s+2 << endl;//从下标2开始读
cout << s[1] <<endl;//是数组从第一个下标开始
return 0;
char str[100];
cin >> str;//输入字符串时,遇到空格或者回车就会停止。
cout << str <<endl;//输出字符串时,遇到空格和回车不会停止。
printf("%s\n",str);
char s[100];
fgets(s,100000000,stdin);//读入一整个字符串,包括空格
cout << s << endl;
//如果string 的话,这样可以用getline(cin,s)
string s;
getline(cin,s);
cout << s <<endl;
//或者用puts(s)读入
scanf("%s",s);
puts(s);
printf("%s\n",s);
return 0;
3.字符数组常用函数
需要引入头文件#include <string.h>
(1)strlen(s)求字符串长度
(2)strcmp(a,b),比较两个字符串的大小,a<b返回-1,a==b返回0,a>b返回1,这里的比较方式是字典序
(3)strcpy(a,b),将字符串b复制给从a开始的字符串数组
//(2)例如
#include <cstdio>
#include <iostream>
#include <cstring>
int main()
{
char s1[100],s2[100];
scanf("%s",s1);
cout << strcmp(s1,"abc") << endl;//例如输入abc则输出0,输入abb输出-1,输入abd输出1
}
4.string
if(str[i]==c)//判断是否为c,用c而不是'c'
读入字符串,最好不要用scanf报错,输出用printf。
注意:fgets函数会把回车也读进来,getline()会把空格读进来
b.pop_back();是把最后一个字符(空格)删除掉
stringstream ssin(a) ssin和cin等价
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
string s1;//默认空的字符串
string s2=s1;//s2是s1的一个副本
string s3="hiya";//s3是该字符串面值的一个副本
string s4(10,'c');//s4的内容是:ccccccccccc
string s1,s2;
cin>>s1;
printf("%s\n",s1.c_str());//或者puts(s1.c_str())
return 0;
//读入一行
string s1,s2;
getline(cin,s1);
cout <<s1<<endl;//例如读入23snl skk输出23snl skk,但是如果为cin>>s1;则输出23snl
s3+="is great";//string 可以直接加字符串
}
string s="Hello World!";
for(char c:s)cout<<c<<endl;
return 0;
这样输出为
H
e
l
……
!
//或者输出这样写也行
for(int i=0;i<s.size();i++)
cout <<s[i]<<endl;
//如果想要改变数组的值
for(char &c:s)
{
c='a';
}
cout << s <<endl;
//输出全为a了,在char后面加一个&符号
5.双指针
for(int i=0;i<sin;i++)
.back是字符串的最后一个字符
.pop_back()是去掉字符串的最后一个字符
第二节、例题
1.判断只出现一次的字母
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
int cnt[26];
char str[100010];
int main()
{
cin >> str;
int len=strlen(str);
for(int i=0;i<strlen(str);i++) cnt[str[i]-'a']++;//读入数组里面每一个字符
for(int i=0;i<strlen(str);i++)//是不是出现字符只出现了一次
if(cnt[str[i]-'a']==1)
{
cout << str[i] <<endl;
return 0;
}
puts("no");
return 0;
}
2.判断字符串中数字的个数
#include <cstdio>
int main()
{
char str[101];//定义字符串
fgets(str,101,stdin);//读入字符串
int cnt=0;
for(int i=0;str[i];i++)
if(str[i]>='0'&&str[i]<='9')//判断是不是数字
cnt++;
printf("%d\n",cnt);
return 0;
}
3.字符串插入
#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
string a,b;
while(cin>>a>>b)
{
int p=0;
for(int i=1;i<a.size();i++)
if(a[i]>a[p])
p=i;//先找出最大的
cout<<a.substr(0,p+1)+b+a.substr(p+1)<<endl;//从0到p+1,加b加p+1到最后
}
return 0;
}
4.忽略大小写比较字符串大小(较难)
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int main()
{
char a[100],b[100];
fgets(a,100,stdin);
fgets(b,100,stdin);
if (a[strlen(a) - 1] == '\n') a[strlen(a) - 1] = 0; // 去掉末尾回车
if (b[strlen(b) - 1] == '\n') b[strlen(b) - 1] = 0; // 去掉末尾回车
for(int i=0;a[i];i++)
if(a[i]>='A'&&a[i]<='Z')
a[i]+=32;
for(int i=0;b[i];i++)
if(b[i]>='A'&&b[i]<='Z')
b[i]+=32;
int t=strcmp(a,b);
if(t==0)puts("=");
else if(t<0)puts("<");
else puts(">");
return 0;
}
5.去掉多余的空格
#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;
}
6.字符串移位 难!!(没有思路)
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
string a, b;
cin >> a >> b;
if (a.size() < b.size()) swap(a, b);
for (int i = 0; i < a.size(); i ++ )//每循环一次移位一次
{
a = a.substr(1) + a[0];
for (int j = 0; j + b.size() <= a.size(); j ++ )//找起点每一段都枚举一遍
{
int k = 0;
for (; k < b.size(); k ++ )
if (a[j + k] != b[k])
break;
if (k == b.size())
{
puts("true");
return 0;
}
}
}
puts("false");
return 0;
}
7.字符串乘方 难!!!(没有思路)
输出 1 4 3
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
string str;
while (cin>>str,str != ".")
{
int len=str.size();
for(int n=len;n;n--)
if(len%n==0)//一定要满足n是len的约数
{
int m=len/n;//先枚举len与n的约数
string s=str.substr(0,m);
string r;//在用一个字符串,用str的前m个字符拼接n次得到新的字符串与原来字符串进行比较看是否相等
for(int i=0;i<n;i++) r+=s;//重复n次拼接起来
if(r==str)
{
cout<<n<<endl;
break;
}
}
}
return 0;
}
7.字符串最大跨距 难!!
输出18
#include <iostream>
using namespace std;
int main()
{
string s, s1, s2;
char c;
while (cin >> c, c != ',') s += c;//只要不属于,就加过去
while (cin >> c, c != ',') s1 += c;
while (cin >> c) s2 += c;//当文件没有结束一直读下去
if (s.size() < s1.size() || s.size() < s2.size()) puts("-1");//如果字符串较小则没有相应的字符串可以找到
else
{
int l = 0;//设置一个起点,从l开始的这一段是否与s1相等
while (l + s1.size() <= s.size())
{
int k = 0;
while (k < s1.size())//当k小于这一段时
{
if (s[l + k] != s1[k]) break;//不等于时break,一直加
k ++ ;
}
if (k == s1.size()) break;//如果等于的话就是一样了,break
l ++ ;
}
int r = s.size() - s2.size();//定义r从起点开始枚举
while (r >= 0)
{
int k = 0;
while (k < s2.size())
{
if (s[r + k] != s2[k]) break;
k ++ ;
}
if (k == s2.size()) break;//相等
r -- ;
}
l += s1.size() - 1;//第一个字符串最后一个位置
if (l >= r) puts("-1");//s1不完全在s2左边,说明不能输出相差多少个
else printf("%d\n", r - l - 1);//反之输出多少个
}
return 0;
}
8.最长公共字符串后缀 难!!
输出ba
a
#include <iostream>
using namespace std;
const int N = 200;//const 是N的值不能变,是个常量。
int n;//枚举字符串的后n个字符
string str[N];
int main()
{
while (cin >> n, n)
{
int len = 1000;
for (int i = 0; i < n; i ++ )
{
cin >> str[i];
if (len > str[i].size()) len = str[i].size();
}
while (len)//枚举后面是否一样
{
bool success = true;
for (int i = 1; i < n; i ++ )
{
bool is_same = true;
for (int j = 1; j <= len; j ++ )
if (str[0][str[0].size() - j] != str[i][str[i].size() - j])
{//如果不等于则输出false
is_same = false;
break;
}
if (!is_same)
{//如果不一样时的输出
success = false;
break;
}
}
if (success) break;
len -- ;
}
cout << str[0].substr(str[0].size() - len) << endl;//输出最长的公共后缀
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)