C/C++基础知识——字符串(三)

简介: C/C++基础知识——字符串

C/C++基础知识——字符串(二)https://developer.aliyun.com/article/1437435


14.最长单词

知识点:s.back()与s.pop_back();的用法

一个以 . 结尾的简单英文句子,单词之间用空格分隔,没有缩写形式和其它特殊形式,求句子中的最长单词。

输入格式

输入一行字符串,表示这个简单英文句子,长度不超过 500。

输出格式

该句子中最长的单词。如果多于一个,则输出第一个。

输入样例:

I am a student of Peking University.

输出样例:

University

(1)用cin过滤掉空格直接输入判断

#include <bits/stdc++.h>
 
using namespace std;
 
int main()
{
    string str,res;
    while(cin >> str)
    {
        if(str.back() == '.') str.pop_back();
        if(str.size() > res.size()) res = str;
    }
    cout << res;
    return 0;
}

(2)用sstream流

#include <bits/stdc++.h>
 
using namespace std;
 
int main()
{
    string s;
    getline(cin,s);
    
    stringstream ssin(s);
    string str,res;
    while(ssin >> str)
    {
        if(str.back() == '.') str.pop_back();
        if(str.size() > res.size()) res = str;
    }
    cout << res;
    return 0;
}

(3)双指针算法

//双指针算法
 
#include <bits/stdc++.h>
 
using namespace std;
 
int main()
{
    string str;
    getline(cin,str); 
    
    int x = 0,y = 0;
    int dix = 0;
    if(str.back() == '.') str.pop_back();
    
    for(int i = 0; i < str.size(); i++)
    {
        int j = i;
        
        while(j < str.size() && str[j] != ' ') j++;
        if(j - i > dix)
        {
            dix = j - i;
            x = i;
            y = j;
        }
        i = j;
    }
    for(int i = x; i < y && str[i] != '.'; i++)
        cout << str[i];
    
    return 0;
}

15.倒排单词

知识点: string s[1000]   s中存放的是字符串

编写程序,读入一行英文(只包含字母和空格,单词间以单个空格分隔),将所有单词的顺序倒排并输出,依然以单个空格分隔。

输入格式

输入为一个字符串(字符串长度至多为 100)。

输出格式

输出为按要求排序后的字符串。

输入样例:

I am a student

输出样例:

student a am I
#include <bits/stdc++.h>
 
using namespace std;
 
int main()
{
    string str[1000];
    int i = 1;
    while(cin >> str[i]) i++;
    for(int j = i - 1; j > 0; j--)
        cout << str[j] << " ";
    return 0;
}

16.字符串移位包含问题

知识点:去掉某个位置的字符:a.substr(1)   去掉了第一个位置的字符,循环暴力枚举

对于一个字符串来说,定义一次循环移位操作为:将字符串的第一个字符移动到末尾形成新的字符串。

给定两个字符串 s1 和 s2,要求判定其中一个字符串是否是另一字符串通过若干次循环移位后的新字符串的子串。

例如 CDAA 是由 AABCD 两次移位后产生的新串 BCDAA 的子串,而 ABCDACBD 则不能通过多次移位来得到其中一个字符串是新串的子串。

输入格式

共一行,包含两个字符串,中间由单个空格隔开。

字符串只包含字母和数字,长度不超过 30。

输出格式

如果一个字符串是另一字符串通过若干次循环移位产生的新串的子串,则输出 true,否则输出 false

输入样例:

AABCD CDAA

输出样例:

true
#include <bits/stdc++.h>
 
using namespace std;
 
int main()
{
    string str1,str2;
    cin >> str1 >> str2;
    if(str1.size() < str2.size()) swap(str1,str2);
    for(int i = 0; i < str1.size(); i++)
    {
        //将a中第一个字符删掉再后面加上a[0]
        str1 = str1.substr(1)+str1[0];
        //遍历起点
        int j = 0;
        for(; j + str2.size() <= str1.size(); j++)
        {
            int k = 0;
            //遍历b的每一个字符位置
            for(; k < str2.size(); k++)
            {
                if(str1[j + k] != str2[k])
                    break;
            }
            if(k == str2.size())
            {
                cout << "true" << endl;
                return 0;
            }
        }
    }
    cout << "false" << endl;
    return 0;
}

17.字符串最大跨距

知识点: 过滤,读入字符串a,b,c      字符串的遍历与判断

有三个字符串 S,S1,S2,其中,S 长度不超过 300,S1和 S2 的长度不超过 10。

现在,我们想要检测 S1 和 S2是否同时在 SS 中出现,且 S1 位于 S2的左边,并在 S 中互不交叉(即,S1的右边界点在 S2 的左边界点的左侧)。

计算满足上述条件的最大跨距(即,最大间隔距离:最右边的 S2 的起始点与最左边的 S1 的终止点之间的字符数目)。

如果没有满足条件的 S1,S2 存在,则输出 −1。

例如,S=S= abcd123ab888efghij45ef67kl, S1= ab, S2= ef,其中,S1 在 S中出现了 2 次,S2也在 S 中出现了 2 次,最大跨距为:18。

输入格式

输入共一行,包含三个字符串 S,S1,S2,字符串之间用逗号隔开。

数据保证三个字符串中不含空格和逗号。

输出格式

输出一个整数,表示最大跨距。

如果没有满足条件的 S1 和 S2存在,则输出 −1。

输入样例:

abcd123ab888efghij45ef67kl,ab,ef

输出样例:

18
#include <bits/stdc++.h>
 
using namespace std;
 
int main()
{
    string s,s1,s2;
    char c;
    //过滤,读入字符串s,s1,s2
    while(cin >> c && c != ',') s += c;
    while(cin >> c && c != ',') s1 += c;
    while(cin >> c ) s2 += c;
    //判断字符串s的长度是否包含了字符串s1,s2
    if(s1.size() > s.size() || s2.size() > s.size()) cout << "-1" << endl;
    else
    {
        int l = 0; 
        //从字符串s的第一个位置开始寻找字符串s1
        for(; l + s1.size() <= s.size() ;l++)//一直找到字符串s的末尾
        {
            int k = 0;
            //从字符串s1的第一个字符串开始比较是否与字符串s相等
            for(; k < s1.size() ;k++)//一直比较到字符串s1的末尾
            {
                //如果字符串s中的某个字符与字符串s1中某个字符不相等则跳出循环
                if(s[l + k] != s1[k])
                    break;
                //若相等则继续比较字符串b中的下一个字符
            }
            //证明从l开始的长度为s1.size()的子串与s1相等且是字符串s的最左侧出现的一个字符串s1
            if(k == s1.size())
                break;
            //继续从字符串s中寻找是否有子串为字符串s1
        }
        
        int r = s.size();
        //从字符串s的右边开始找子串是否为字符串s2
        for(; r >= 0; r--)//一直找到字符串s的最左侧
        {
            int k = 0;
            for(; k < s2.size(); k++)
            {
                if(s[r + k] != s2[k])
                    break;
            }
            if(k == s2.size())
                break;
        }
        //l为s中子串与字符串s1相等的子串的末尾一个字符
        l += s1.size() - 1;
        //判断字符串s2是否在字符串s1的右侧  是则输出最大的跨距
        if(r > l)
            cout << r - l - 1 << endl;
        else 
            cout << "-1" << endl;
    }
    return 0;
}

知识点:find大法    

s.find();    // 在字符串s上从前往后找        s.rfind();   // 从后往前

s.find(s1)的返回值为所查找的子串的第一个字符的位置,找不到返回 -1

#include <bits/stdc++.h> 
 
using namespace std;
 
int main()
{
    string s, s1, s2, a;
    getline(cin, a);
 
    int f1, f2;                      // 两个','的位置
    f1 = a.find(',');
    f2 = a.rfind(',');
    s = a.substr(0, f1);
    s1 = a.substr(f1 + 1, f2 - f1 - 1);
    s2 = a.substr(f2 + 1);
 
 
    int l, r;
    l = s.find(s1);                   // 在字符串s上从左往右找s1
    r = s.rfind(s2);                  // 在字符串s上从右往左找s2
 
    if (l == -1 || r == -1)           // s1 或 s2 不在 s 上
    { 
        cout << "-1";
        return 0;
    }
 
    l = s.find(s1) + s1.size() - 1;   // l为s1最右面的下标
 
    if ( l >= r )                      // s1 s2 交叉
        cout << "-1";
    else cout << r - l - 1;
 
    return 0;
}


目录
相关文章
|
14天前
|
存储 C++
C++(五)String 字符串类
本文档详细介绍了C++中的`string`类,包括定义、初始化、字符串比较及数值与字符串之间的转换方法。`string`类简化了字符串处理,提供了丰富的功能如字符串查找、比较、拼接和替换等。文档通过示例代码展示了如何使用这些功能,并介绍了如何将数值转换为字符串以及反之亦然的方法。此外,还展示了如何使用`string`数组存储和遍历多个字符串。
|
2月前
|
算法 C++
2730. 找到最长的半重复子字符串(c++,滑动窗口)
2730. 找到最长的半重复子字符串(c++,滑动窗口)
|
2月前
|
C++
567. 字符串的排列(c++)滑动窗口
567. 字符串的排列(c++)滑动窗口
|
2月前
|
编译器 C++
【C++】string类的使用④(字符串操作String operations )
这篇博客探讨了C++ STL中`std::string`的几个关键操作,如`c_str()`和`data()`,它们分别返回指向字符串的const char*指针,前者保证以&#39;\0&#39;结尾,后者不保证。`get_allocator()`返回内存分配器,通常不直接使用。`copy()`函数用于将字符串部分复制到字符数组,不添加&#39;\0&#39;。`find()`和`rfind()`用于向前和向后搜索子串或字符。`npos`是string类中的一个常量,表示找不到匹配项时的返回值。博客通过实例展示了这些函数的用法。
|
2月前
|
C语言 C++ 开发者
C++基础知识(一:命名空间的各种使用方法)
C++在C的基础上引入了更多的元素,例如类,类的私密性要比C中的结构体更加优秀,引用,重载,命名空间,以及STL库,模板编程和更多的函数,在面向对象的编程上更加高效。C语言的优势则是更加底层,编译速度会更快,在编写内核时大多数都是C语言去写。 在C++中,命名空间(Namespace)是一种组织代码的方式,主要用于解决全局变量、函数或类的命名冲突问题。命名空间提供了一种封装机制,允许开发者将相关的类、函数、变量等放在一个逻辑上封闭的区域中,这样相同的名字在不同的命名空间中可以共存,而不会相互干扰。
|
3月前
|
C++ 容器
C++字符串string容器(构造、赋值、拼接、查找、替换、比较、存取、插入、删除、子串)
C++字符串string容器(构造、赋值、拼接、查找、替换、比较、存取、插入、删除、子串)
|
3月前
|
编译器 C++
【C++进阶】深入STL之string:模拟实现走进C++字符串的世界
【C++进阶】深入STL之string:模拟实现走进C++字符串的世界
33 1
|
2月前
|
C++
C++基础知识(二:引用和new delete)
引用是C++中的一种复合类型,它是某个已存在变量的别名,也就是说引用不是独立的实体,它只是为已存在的变量取了一个新名字。一旦引用被初始化为某个变量,就不能改变引用到另一个变量。引用的主要用途包括函数参数传递、操作符重载等,它可以避免复制大对象的开销,并且使得代码更加直观易读。
|
2月前
|
算法 编译器 C++
C++基础知识(三:哑元和内联函数和函数重载)
在C++编程中,"哑元"这个术语虽然不常用,但可以理解为在函数定义或调用中使用的没有实际功能、仅作为占位符的参数。这种做法多见于模板编程或者为了匹配函数签名等场景。例如,在实现某些通用算法时,可能需要一个特定数量的参数来满足编译器要求,即使在特定情况下某些参数并不参与计算,这些参数就可以被视为哑元。
|
2月前
|
C++
C++基础知识(四:类的学习)
类指的就是对同一类对象,把所有的属性都封装起来,你也可以把类看成一个高级版的结构体。