机试指南练习-第八章

机试指南练习总结第八章-标准模板库STL

熟悉STL中常用的stringmap等数据结构的使用

  1. 对于string对象,可以直接使用=实现深拷贝,同时对于string还有以下几个需要熟悉的函数
str.size(); //求字符串的大小
str1 = str1 + "a"; //直接拼接字符串
str.insert(index, str1); //在index的位置插入字符串str1
str.insert(index, count, s); //在index的位置插入cout个字符s
str.erase(index, cout); //从index位置开始删除cout个字符
str.find(str1, startPos); //从startPos位置开始查找字符串str1,若找到则返回第一次出现的下标,若不能找到,则返回string::npos

  1. STL中map模板的使用
map<string, int> mp; //初始化
mp.clear(); //清空map
mp.find(b); //查找mp中使用有b的映射,如果有的话返回对应的迭代器,如果没有的话返回mp.end()
mp.cout(b); //查找元素b,是否存在,有0,1两个值

例8.1:字符串的查找删除

未找到提交OJ

题目描述
给定一个短字符串(不含空格),再给定若干字符串,在这些字符串中删除所含有的短字符串

输入描述

输入只有1组数据。
输入一个短字符串(不含空格),再输入若干字符串直到文件结束为止。

输出描述:

删除输入的短字符串(不区分大小写)并去掉空格,输出

示例1

输入:

in
#include 
int main()
{

printf(" Hi ");
}

输出:

#clude
tma()
{

prtf("Hi");
}

解题思路

本题主要有两个难点,第一个是数据的读入,可知本题中输入数据是一行一行读入的,可以使用getline(cin, str),或者gets(str),第一个函数是C++中的,第二个函数是C中的(str必须是字符指针)
第二个难点就是要忽略大小写,这一点就使得不能直接使用string中的find函数来进行查找。我的解决思路就是直接回归最原始方法,一个一个遍历字符来查找字符串,同时在查找到之后对字符串进行删除。代码如下:

#include <iostream>
#include <stdio.h>
#include <string>

#define MAX 1000

using namespace std;

//判断是否到文件结尾

int main()
{
    string str;
    cin>>str;
    cin.ignore(1);
    int s1 = str.size();
    string tar;
    int i, j;
    while(!cin.eof())
    {
        getline(cin, tar);
        int s2 = tar.size();
        j = 0;
        for(i=0; i<s2; i++)
        {
            while(tar[i] == str[j] || 'A' + (tar[i] - 'a') == str[j] || 'a' + (tar[i] - 'A') == str[j])
            {
                if(j == s1 - 1)
                {
                    int temp1 = i - (s1 - 1);
                    i = temp1;
                    tar.erase(temp1, s1);
                    s2 = tar.size();
                    j = 0;
                    continue;
                }
                i++;
                j++;
            }
            if(tar[i] != str[j] && 'A' + (tar[i] - 'a') != str[j] && 'a' + (tar[i] - 'A') == str[j])
                i--;
            j = 0;
        }
        s2 = tar.size();
        for(i=0; i<s2; i++)
        {
            if(tar[i] == ' ')
                tar.erase(i, 1);
        }
        cout<<tar<<endl;
    }
    return 0;
}

其他思路

  • 对于忽略大小写的处理方式,书中的处理方式也值得借鉴,不容易出错。书中是将字符串拷贝一份,然后将目标字符串和拷贝的字符串都全部转为小写字母,在这两个字符串之间做查找,然后在原来的字符串中做删除,这样的话也就能够达到忽略大小写查找删除的目的。

需要总结的一些知识点

  • C/C++中自带的字母大小写转换函数,tolower(),toupper(),包含在头文件<ctype.h>或者< cctype >中,能够把单个字符转换为大写或者小写,如果要转换字符串,则需要使用循环。

练习题1:单词替换

提交OJ

题目描述
输入一个字符串,以回车结束(字符串长度<=100)。该字符串由若干个单词组成,单词之间用一个空格隔开,所有单词区分大小写。现需要将其中的某个单词替换成另一个单词,并输出替换之后的字符串。

输入描述

多组数据。每组数据输入包括3行, 第1行是包含多个单词的字符串 s, 第2行是待替换的单词
a,(长度<=100)3行是a将被替换的单词b。(长度<=100) s, a, b 最前面和最后面都没有
空格.

输出描述:

每个测试数据输出只有 1 行, 将s中所有单词a替换成b之后的字符串。

示例1

输入:

You want someone to help you
You
I

输出:

I want someone to help you

解题思路

本题我是直接使用string类中的erasefind函数来解决的,解题过程中碰到两个坑点

  1. 需要注意题目中是将一个单词替换为另一个单词,同时单词和单词之间有空格分隔,这就意味着当CCC是CC的前缀表达式时不能被替换
  2. string类中find函数返回值的问题,stringfind函数在没有找到目标时返回的是string::npos,要注意的是,这个数的类型是string::size_type,不能使用unsigned int或者int来存,要不然就会出错。我一开始使用unsigned int来保存,在本题测试没问题,但是提交到OJ上之后就一直报数组越界,就是由于当使用unsigned int保存时会使t != string::npos失效。
#include <iostream>
#include <stdio.h>
#include <string>

using namespace std;

//发生越界错误

int main()
{
    string str, str1, str2;
    while(!cin.eof())
    {
        getline(cin, str);
        getline(cin, str1);
        getline(cin, str2);
        str.insert(0, " ");
        str = str + " ";
        string::size_type t = str.find(" " + str1 + " ", 0);
        while(t != str.npos)
        {
            if(str.size() == 0 || str1.size() == 0)
                break;
            str.erase(t, str1.size() + 2);
            str.insert(t, " " + str2 + " ");
            t = str.find(" " + str1 + " ");
        }
        str.erase(0, 1);
        str.erase(str.size() - 1, 1);
        cout<<str<<endl;
    }
    return 0;
}

其他思路

  • 也可以直接使用string中的replace函数来进行字符串替换

需要总结的一些知识点

//1,使用string::size_type类型来保存,然后在判断
string::size_type t = str.find(a);
while(t != string::npos)
//2,在判断是否为string::npos之后再使用int保存
while(str.find(a) != string::npos)
{
	int t = str.find(a);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值