语法基础之字符串

1、数字与字符的对应

48 ----字符0
65----A 差32
97----a
在这里插入图片描述

2.字符数组

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

2.1字符数组的大小

 char a[]="c++";
 cout<<sizeof(a);

在这里插入图片描述

2.2字符数组的输入与输出

在这里插入图片描述
在这里插入图片描述
scanf 输入字符数组不加& 区地址符号,本身就是地址。
在这里插入图片描述
scanf输入字符数组中的一个元素,需要加去地址符号。
在这里插入图片描述
对于 s+2不需要去地址符号。
在这里插入图片描述
从s[1]开始记录数据,s[0]没有数据。 数组下标从1开始
在这里插入图片描述
在这里插入图片描述
从s[2]开始记录数据。s[0],s[1]没数据。

2.3字符数组输出易错

对于未定义长度的字符数组和已经定义长度的字符数组。
(1)已经定义长度的会按预期输出。长度未字符长度+1(\0)
(2)对于没有定义长度的,接着下面尾部含有\0的输出
(3)使用字符数组结尾一定写\0,否则程序会有歧义。

(1)

#include<iostream>
#include<cstring>

using namespace std;
int main()
{
    //已经定义长度为4
    char a[4]={'c','+','+'};
    char b[]={'c','+','+','\0'};
    char c[]="c++";
    cout<<a;
    return 0;
}

结果
在这里插入图片描述
(2)

#include<iostream>
#include<cstring>

using namespace std;
int main()
{
    char a[]={'c','+','+'};
    char b[]={'c','+','+','\0'};
    char c[]="c++";
    cout<<a;
    return 0;
}

在这里插入图片描述
结果以\0结尾为分割。
在这里插入图片描述
(3)歧义

#include<iostream>
#include<cstring>

using namespace std;
int main()
{
    char a[]={'c','+','+'};
    int d=66;
    char b[]={'c','+','+','\0'};
    char c[]="c++";
    cout<<a;
    return 0;
}

在这里插入图片描述
int d=66; 则最后输出了B。对于字符数组末尾一定要加\0

2.4 字符数组任意位置输出

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

2.5 scanf读入字符数组的局限性

当遇到空格、回车、文件结束符时就不能读了。
在这里插入图片描述
在这里插入图片描述

2.5.1 读入一行字符数组

如何读入一行 且行内包含空格。
使用fgets读入字符数组。fgets(字符数组名,最多几个字符,stdin)
在这里插入图片描述

在这里插入图片描述
cin.getline 读入一行字符数组(字符数组名称,长度)
在这里插入图片描述

2.5.2 读入一行字符串

getline()读入字符串
getline(cin,字符串名称)
在这里插入图片描述

2.6字符数组的输出

在这里插入图片描述
以上两句话等价。

2.7字符数组常用的操作

也可以直接使用#include
在这里插入图片描述
对于 strcmp a>b 输出正数,a<b 输出负数,a=b,输出0.
加入按字典序比较数字。 2与10:
正常比较10>2.
按字典序(ASCII码)比较,2>10 10的第一位是1 ,2的第一位是2。
字典序与贪心相关。

2.7.1合理使用strlen

在这里插入图片描述
在初值阶段算出strlen,不能在循环中使用。因为每算一次strlen都会把字符数组遍历一遍。

2.8 练习1

题目:给定一个只包含小写字母的字符串,请你找到第一个仅出现一次的字符。如果没有,输出“no”。

代码
在这里插入图片描述

在for循环中 使用str[i]作为循环终止判断,当i为最后一个时,str[i]=’\0’ 循环就直接终止,不需要通过长度判断

字符之间可以执行±操作,且当前边的变量为int时,自动转为整形。

2.9 scanf 面对换行如何应对

在这里插入图片描述

在这里插入图片描述

3. 字符串处理字符

头文件
有iostream就能使用string iostream包含string

3.1定义和初始化

在这里插入图片描述

3.2string 上的操作

(1)string的读写:
在这里插入图片描述
注意:不能用printf直接输出string,需要写成:printf(“%s”, s.c_str());
不能用scanf输入string
使用put输出 必须有iostream头文件
string s2=“cdf”;
puts(s2.c_str());
使用put输出字符串和字符数组
string s2=“cdf”;
char a[3]={‘a’,‘b’,’\0’};
puts(s2.c_str());
puts(a);

(2)使用getline读取一整行 

在这里插入图片描述
(3)string的empty和size操作
字符串为空返回1,不为空返回0。 size返回字符串的长度。
Size 每次返回的是一个存储好的数值,不用像字符数组循环遍历数组后得到长度。

在这里插入图片描述
(4)string 的比较:
支持 > < >= <= == !=等所有比较操作,按字典序进行比较。

(5)为string对象赋值:

string s1(10, ‘c’), s2; // s1的内容是 cccccccccc;s2是一个空字符串
s1 = s2; // 赋值:用s2的副本替换s1的副本
// 此时s1和s2都是空字符串

(6)两个string对象相加:

string s1 = “hello, ”, s2 = “world\n”;
string s3 = s1 + s2; // s3的内容是 hello, world\n
s1 += s2; // s1 = s1 + s2
sring 可以加字符串 也可以加字符

(7)字面值和string对象相加:
做加法运算时,字面值和字符都会被转化成string对象,因此直接相加就是将这些字面值串联起来:

	string s1 = “hello”, s2 = “world”;		// 在s1和s2中都没有标点符号
	string s3 = s1 + “, “ + s2 + ‘\n’;

当把string对象和字符字面值及字符串字面值混在一条语句中使用时,必须确保每个加法运算符的两侧的运算对象至少有一个是string:

string s4 = s1 + “, “; // 正确:把一个string对象和有一个字面值相加
string s5 = “hello” +”, “; // 错误:两个运算对象都不是string

string s6 = s1 + “, “ + “world”; // 正确,每个加法运算都有一个运算符是string
string s7 = “hello” + “, “ + s2; // 错误:不能把字面值直接相加,运算是从左到右进行的

3.3 处理string对象中的字符

可以将string对象当成字符数组来处理:
在这里插入图片描述
或者使用基于范围的for语句:
在这里插入图片描述
不加& c=’a’ 输出c不会改变 加&后改变c输出c会改变
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4、auto的使用

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

5、信息加密

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

6、字符串长度

不用fgets读入字符数组
在这里插入图片描述

在这里插入图片描述

7、循环相克令

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

8.字符串加空格

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

9.字符串插入

在这里插入图片描述
求字符串中的某一段
在这里插入图片描述
substr (起始位置,长度/没有的话就到最后)
在这里插入图片描述

10.字符串匹配

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

11.忽略大小写比较字符串大小

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
一般不用fgets读入。

12、去掉多余的空格

在这里插入图片描述

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

在这里插入图片描述
希望i++之后变成j。

双指针算法
在这里插入图片描述

13、输出字符串

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
char 可以去掉 string类型会自动转换。

14、单词替换

在这里插入图片描述
在这里插入图片描述
使用 stringstream 需要sstream头文件。
将一个字符串放入stringstream后,命名变量的类型。
根据变量的类型,读出不同的数据。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以一直循环读。

使用sscanf一直读字符数组。 读取字符数组中个人所规定的类型。注意在操作面板中输入数据的类型与sscanf中写的顺序一致。
在这里插入图片描述
当不知道一行多少个数时,使用stringstream读入
在这里插入图片描述

15、对于streamstring和sscanf

streamstring对于字符串和字符数组都能使用,sscanf只对于字符数组。 不读空格,以空格为间断

在这里插入图片描述
在这里插入图片描述
两者等价。

16、字符串中最长的连续出现的字符

在这里插入图片描述
双指针
在这里插入图片描述

在这里插入图片描述

17 、最长单词

在这里插入图片描述

在这里插入图片描述
str.back() 字符串最后一个字符
str.pop_back() 去掉字符串最后一个字符

18、 倒排单词

在这里插入图片描述
解法一:字符串数组
在这里插入图片描述
解法二:翻转;

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
    string s;
    string s1;
    while(cin>>s)
    {
        //字符串翻转的方法
        reverse(s.begin(),s.end());
        s1+=s+' ';
    }
    reverse(s1.begin(),s1.end()) ;
    for(int i=1 ;i<s1.size();i++) cout<<s1[i];
    return 0;
}

19、 字符串移位包含问题

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

20、字符串乘方

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
string.substr(起始位置,个数)

21、字符串最大跨距

在这里插入图片描述

#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()) cout<<"-1";
    //左边左端点
    int l=0;
    while(l<=s.size()-s1.size())
    {
        int k=0;
        for(;k<s1.size();k++)
        {
            if(s[l+k]!=s1[k]) break;
        }
        if(k==s1.size()) break;
        l++;
    }
    //右边左端点
    int r=s.size()-s2.size();
    while(r>=0)
    {
        int k=0;
        for(;k<s2.size();k++)
        {
             if(s[r+k]!=s2[k]) break;
        }
        if(k==s2.size()) break;

        r--;
    }
    l+=s1.size()-1;
    
    if(l>=r) cout<<"-1";
    else cout<<r-l-1;
    
    return 0;
}

22、最长公共字符串后缀

在这里插入图片描述

#include<iostream>
using namespace std;

const int N =200;
int n;
string str[N];  //定义个字符串数组

int main(){
   while(cin >> n , n)
   {
       int len = 210 ;  
       //用来记录公共后缀的长度,写在while中,每次输入更新一次。
       for(int i = 0 ; i < n ; i++ )
       {
           cin >> str[i] ; //输入n个字符串
           if(len > str[i].size()) len = str[i].size();  
           //将公共后缀长度更新为最短的字符串的长度!
       }

       while(len)  //当len>0的时候,也就是有公共后缀的时候
       {
           bool is_success = true ; //标记是否匹配成功
           for(int i = 1 ; i < n ; i++ )  
           //让所有字符串与第一个字符串比较后缀
           {
               bool is_same = true ;//标记后缀是否相等
               for(int j = 1 ; j <= len ; j++)  
               // 后缀长度从1到len,每个字符逐个比较
               {
                    if(str[i][str[i].size() - j ] !=  str[0][str[0].size() - j])
                    {
                        is_same = false ;
                        break ;
                    }
               }
               if(!is_same)  //后缀不等跳出
               {
                   is_success = false ;
                   break;
               }
           }
            if(is_success) break ;  
            //匹配成功跳出while循环,输出长度为len的后缀
              len -- ;  //匹配失败,长度减1 
       }
       cout <<  str[0].substr(str[0].size() - len ) << endl ;
   }
    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值