字符串进阶-字符串函数

字符串进阶-字符串函数应用

c++提供了大量的字符串函数,供我们在解题时使用。

一、常用函数介绍

1-长度 (有返回值)

a.size()   或   a.length()

2-查找(有返回值)

a.find("hello")  //返回子串hello在a中第一次出现时开头字母h的下标
    
a.find('h') //返回字符h在a中第一次出现时的下标
    
a.find(b) //返回b在a中第一次出现时的相关下标信息(b可以是字符或字符串)
a.find('h',2)//表示从下标2开始查找字符h第一次出现的位置

关于find函数的返回值判定:

很明显a中存在待找字符(串)时,会返回相关下标值;

不存在的时候,会返回 string :: npos ;

if 条件表达式: a.find("hello") == string::npos 表示找不到

3-插入(无返回值)

a.insert(2,"hello"); //在a中下标2开始插入“Hello",使a的值变化

举例:string a="topscoding";
    a.insert(2,"hello"); 
        cout<<a;
运行结果:tohellopscoding

4-删除(无返回值)

a.erase(2,3); //在a中下标2开始,删除3个字符,使a的值变化

举例:string a="topscoding";
    a.erase(2,3);
        cout<<a;
运行结果:tooding

5-提取(有返回值)

a.substr(2,3);//提取a中下标2开始的3个字符(a本身值不变,这相当于是复制过程)

举例:string a="topscoding";
        cout<<a.substr(2,3);
运行结果:psc

6-翻转(无返回值)

reverse(a.begin(),a.end());//将字符串a的内容完全倒置,使a的值变化。

举例:string a="topscoding";
        reverse(a.begin(),a.end());
    cout<<a;
运行结果:gnidocspot

7-替换(无返回值)

a.replace(2,3,"hello");//将字符串a中,从下标2开始连续删除3个字符,并用”hello"替换(替换内容与待替换内容长度可以不同)

举例:string a="topscoding";
        a.replace(2,3,"hello");
    cout<<a;
运行结果:tohellooding

replace函数使用过程中,代替换内容可以是字符,但 替换内容 必须是字符串。

8-判空(有返回值)

a.empty() //串空返回1(true),非空返回0(false)。
    
举例:string a="topscoding";
        if(a.empty()==1) cout<<"haha";
    else cout<<"wuwu";
运行结果:wuwu

9-清空(无返回值)

a.clear(); //将a的内容清空,变为空串

举例:string a="topscoding";
        a.clear();
    cout<<a.size();
运行结果:0

10-追加(无返回值)

a.append("hello"); //将a的内容增添一截

举例:string a="topscoding";
        a.append("hello");
    cout<<a;
运行结果:tposcodinghello

函数相关题目

1、回文密码(点击题目名可转到题目详情页)(reverse()函数应用)

分析:

(1)first of all,这道题一上来要先确定字符串A是否回文,reverse函数可以派上大用场。

(2)奇数位、偶数位的处理,直接控制下标即可。比如奇数位的下标起点就是0,每次下标变化+2即可。

参考代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    string a;
    cin>>a;
    string b = a; //b存储a的内容 
    reverse(b.begin(),b.end()); //b此时就是a翻转后的内容 
    if(b==a) //翻转前后值一样,那一定是回文串 
    {
        for(int i=1;i<a.size();i+=2)//控制下标依次输出偶数位 
        {
            cout<<a[i];
        }
    }
    else
    {
        for(int i=0;i<a.size();i+=2)//控制下标依次输出奇数位 
        {
            cout<<a[i];
        }
    }
    return 0;
}

2、调皮的小数点(find()函数应用)

分析:

(1)这道题是典型的关于find函数的应用,整个字符串中只有一个小数点,只有找到小数点的位置,才能得到其后第n位的值。

(2)小数点后第n位可能并不存在,或者说此时的下标已经超出所输入字符串的下标范围,这种情况不能落下。

参考代码:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int t,n;//t代表t组数据,n代表小数点后第n位
    cin>>t;
    for(int i=1;i<=t;i++)
    {   
        string a;
        cin>>a>>n;
        int t=a.find('.');//记录小数点的下标
        t=t+n;//记录小数点后第n位的下标
        if(t<=a.size()-1) //下标在合法范围内
        {
            cout<<a[t]<<endl;
        }
        else
        {
            cout<<"Error"<<endl;
        }
    }
    return 0;
}

3、字母概率(大小写函数应用)

分析:

(1)概率 = 该字符出现总次数 / 字符总个数 。值得注意的是,这道题里,字母的大小写形式都要纳入讨论。

​ 这里要介绍两个新函数:

tolower() //把字母字符转换成小写,非字母字符不做处理
toupper()//把字母字符转换成大写,非字母字符不做处理

注意:上述两函数的返回值为整型(即返回ASCII码值)而非字符型。

应用这两个函数,可以轻松处理大小写讨论的问题。

(2)字符总个数》a.size()函数即可得到,该字符出现总次数》for循环计数。

参考代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    char a;
    string b;
    while(cin>>a>>b)//多组测试数据
    {
        int  s=0;// 注意s初始化的位置
        for(int i=0;i<b.size();i++)
        {
            if(b[i]==tolower(a) || b[i]==toupper(a)) //b[i]的值等于a的大写或小写形式都要纳入计数
            {
                s++;
            }
        }
        cout<<fixed<<setprecision(5)<<s*1.0/b.size()<<endl;
        // printf("%.5f\n",s*1.0/b.size());
    }
    return 0;
}

4、墓碑上的字符(insert()函数 / substr()函数应用)

分析:

(1)插入--》即insert( ) 函数,插入函数格式为:insert(插入起点下标,插入内容);只要找到插入的下标,就可以完成这个工作。

(2)对于任意偶数长度的字符串a,它的中间位置应当是a.size()/2。根据样例可得,插入是从a.size()/2这个位置后开始的。

(3)如果不用插入函数,这道题用substr()函数也完全可以搞定,-》分别提取第一个串的前半段、第二个串、第一个串的后半段,即可以在不改变两个串内容的基础上得到插入的效果。

参考代码:

方案一:insertt()函数
    
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    string a,b;
    cin>>n;
    while(n--)
    {
        cin>>a>>b;
        a.insert(a.size()/2,b); //将 b 的内容直接插入a中
        cout<<a<<endl; //输出插入后的a
    } 
    return 0;
}

方案二:substr()函数
    
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    cin>>n;
    while(n--)
    {
        string a,b,c;
        cin>>a>>b;
        int t=a.size()/2; //记录中间位置下标
        c=a.substr(0,t)+b+a.substr(t,t);//分别提取a的前半段,b,a的后半段,并赋值给c
        cout<<c<<endl;
    }
}

作业题:

子串的个数(substr)

我是第几个单词

奇偶位互换

二、stringstream流

stringstream是c++标准库提供的字符串流,和之前学过的iostream的操作类似。stringstream可以像cin和cout一样来使用>>、<<进行字符串流的输入输出。

stringstream一般用于将一个字符串分割,以及数据转换。使用stringstream需要加头文件:#include<sstream>

1、使用格式

stringstream sin;   //定义一个stringsteam 类型的变量sin
sin<<变量名1;       //向流中传值,把变量1的值输入到流中
sin>>变量名2;     //从流中取值,把流中的数据输入到变量2中
cout<<变量1;     sin<<变量1; 
cin>>变量2;     sin>>变量2; //尖头指向谁,就是将东西给谁

2、使用对象

(1)stringstream常用来进行字符串和其他类型之间的相互转换。

【举例一】:将字符串转换为其他类型
#include<bits/stdc++.h>
using namespace std;
int main()
{
    //string 转为 int
    string s="1234566";
    int a=0;
    stringstream sin;
    sin<<s;
    sin>>a;
    cout<<"a转换后为:"<<a;
    return 0;
}
运行结果:
a转换后为:1234566
【举例二】:将其他类型转换为字符串
#include<bits/stdc++.h>
using namespace std;
int main()
{
    //int 转为 string
    string s="abc";
    int a=12345;
    stringstream sin;
    sin<<a;
    sin>>s;
    cout<<"s转换后为:"<<s;
    return 0;
}
运行结果:
s转换后为: 12345

(2)stringstream可用于从整行或整段数据中拆分出字符串、整型、浮点型等数据。

【举例三】:读入一行数据,拆分出字符串、整型和浮点型数据并显示。
程序一:
#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s="Todayis 2020 12.31";
    string s1;
    int a;
    double b;
    stringstream sin;
    sin<<s;
    sin>>s1>>a>>b;
    cout<<"s1:"<<s1<<"   a:"<<a<<"   b:"<<b;
    return 0;
}

运行结果:
    s1:Todayis  a:2020  b:12.31
程序二:
#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s="Todayis 12.31 2020";
    string s1;
    int a;
    double b;
    stringstream sin;
    sin<<s;
    sin>>s1>>a>>b;
    cout<<"s1:"<<s1<<"   a:"<<a<<"   b:"<<b;
    return 0;
}

运行结果:
    s1:Todayis  a:12   b:0.31

上述两个程序的运行结果完全不同,这是因为:①stringstream读入数据时,以空格作为分隔符。②拆分的顺序会影响转换的结果。

字符串专题训练1:

幸运数字

国王的魔镜

查找子串并替换

隐藏的最大整数

字符串编辑

字符串专题训练2:

笨小猴

单词缩写

删除字符串中间的*

字符串分离

### 拓展题:
ISBN号码
字符串展开

### 字符串专题训练3:
字符统计
回文字符串
时间差
表达式的值
信息加密
信息解密

posted @ 2024-04-08 13:34  Befrepof  阅读(28)  评论(0编辑  收藏  举报