2024 团体程序设计天梯赛 L1-101 猫娘

1. 原题链接:

L1-101 别再来这么多猫娘了!

2. 题意:

按照违禁词输入顺序,从左到右查找字符串中每个违禁词出现次数并将违禁词替换为<censored>

3. 思路:

按照违禁词输入的顺序逐一统计字符串中每个违禁词出现的次数,并把该次数计入总count中,并将违禁词用___替换(因为有的违禁词就是censored, 直接替换会导致count统计错误,最后把___替换为<censored>

3.1 替换:

如何将将字符串str中的子串sub替换为另一个字符串replaceStr呢?
在java的String类中replace这样的方法,但c++中并没有这样的API,于是我们可以手动实现一个。

3.1.1 实现方法1:
// 函数用于将字符串str中的子串sub替换为另一个字符串replaceStr
/*
其中find方法为从pos开始查找字符串s在当前串中的位置 
int find(const string &s,int pos = 0) const;

其中replace方法为删除从p0开始的n0个字符,然后在p0处插入串s
string &replace(int p0, int n0,const string &s);
*/
string replaceStr(string str,string sub,string replaceStr){
    int pos = 0;
    while((pos = str.find(sub,pos)) != -1){
        str.replace(pos,sub.size(),replaceStr);
        pos += replaceStr.size(); // 更新起始位置
    }
    return str;
}
3.1.2 实现方法2:
/*
find方法为查找字符串s在当前串中的位置,若没有找到返回-1 
int find(const string &s) const;

//erase方法为删除pos开始的n个字符,返回修改后的字符串。
string &erase(int pos = 0, int n = npos);

//insert方法为在p0位置插入字符串s,返回插入后的字符串
string &insert(int p0,const string &s);
*/
string replaceStr(string str,string sub,string replaceStr){
    int pos = 0;
    while((pos = str.find(sub)) != -1){
        str.erase(pos,sub.size());
        str.insert(pos,replaceStr);
    }
    return str;
}

3.2 统计次数:

计算字符串str中子串sub出现的次数:

// 函数用于计算字符串str中子串sub出现的次数
int countSub(string str, string sub) {  
    int count = 0;  
    int pos = 0;  
    while ((pos = str.find(sub, pos)) != -1) {  
        count ++;  
        pos += sub.size(); // 更新起始位置 
    }  
    return count;  
} 

4. 本题完整代码:

c++代码1:

#include <iostream>
#include <string>
using namespace std;

const int N = 110;

int n,k;
string strs[N],str;

// 函数用于将字符串str中的子串sub替换为另一个字符串replaceStr
/*
其中find方法为从pos开始查找字符串s在当前串中的位置 
int find(const string &s,int pos = 0) const;

其中replace方法为删除从p0开始的n0个字符,然后在p0处插入串s
string &replace(int p0, int n0,const string &s);
*/
string replaceStr(string str,string sub,string replaceStr){
    int pos = 0;
    while((pos = str.find(sub,pos)) != -1){
        str.replace(pos,sub.size(),replaceStr);
        pos += replaceStr.size(); // 更新起始位置
    }
    return str;
}

// 函数用于计算字符串str中子串sub出现的次数
int countSub(string str, string sub) {
    int count = 0;
    int pos = 0;
    while ((pos = str.find(sub, pos)) != -1) {
        count ++;
        pos += sub.size(); // 更新起始位置
    }
    return count;
}

int main(){
    cin >> n;
    //不然会读入空格
    cin.ignore();
    for(int i = 0;i < n;i ++){
        getline(cin,strs[i]);
    }
    cin >> k;
    cin.ignore();
    getline(cin,str);
    int count = 0;
    for(int i = 0;i < n;i ++){
        //按照违禁词输入的顺序逐一统计字符串中每个违禁词出现的次数,并把该次数计入总count中
        count += countSub(str,strs[i]);
        //将违禁词用___替换
        str = replaceStr(str,strs[i],"___");
    }
    if(count < k){
        str = replaceStr(str,"___","<censored>");
        cout << str << endl;
    }else{
        printf("%d\nHe Xie Ni Quan Jia!",count);
    }
    return 0;
}

c++代码2:

只需一个replaceStr函数,不需要countSub函数

因为每替换一次就代表有一个违禁词,count加1。将count定义为全局变量,以上的replaceStr函数稍作修改即可

#include <iostream>
#include <string>
using namespace std;

const int N = 110;

//将count定义在全局变量
int n,k,count;
string strs[N],str;

// 函数用于将字符串str中的子串sub替换为另一个字符串replaceStr
/*
其中find方法为从pos开始查找字符串s在当前串中的位置 
int find(const string &s,int pos = 0) const;

其中replace方法为删除从p0开始的n0个字符,然后在p0处插入串s
string &replace(int p0, int n0,const string &s);
*/
string replaceStr(string str,string sub,string replaceStr){
    int pos = 0;
    while((pos = str.find(sub,pos)) != -1){
        count ++;//每替换一次就代表有一个违禁词,count加1
        str.replace(pos,sub.size(),replaceStr);
        pos += replaceStr.size(); // 更新起始位置
    }
    return str;
}


int main(){
    cin >> n;
    //不然会读入空格
    cin.ignore();
    for(int i = 0;i < n;i ++){
        getline(cin,strs[i]);
    }
    cin >> k;
    cin.ignore();
    getline(cin,str);
    for(int i = 0;i < n;i ++){
        str = replaceStr(str,strs[i],"___");
    }
    if(count < k){
        str = replaceStr(str,"___","<censored>");
        cout << str << endl;
    }else{
        printf("%d\nHe Xie Ni Quan Jia!",count);
    }
    return 0;
}

java代码:

java中由于有replace的API,所以自己实现个countSub方法即可

import java.util.*;

public class Main {
    public static int countSub(String str, String sub) {
        int count = 0;
        int pos = 0;
        while ((pos = str.indexOf(sub, pos)) != -1) {
            count++;
            pos += sub.length(); // 移动到子字符串之后的位置
        }
        return count;
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        String[] strs = new String[n];
        for(int i = 0;i < n;i ++){
            strs[i] = sc.next();
        }

        int k = sc.nextInt();
        //不然会读入空格
        sc.nextLine();
        String str = sc.nextLine();
        int count = 0;
        for(int i = 0;i < n;i ++){
            count += countSub(str,strs[i]);
            str = str.replace(strs[i],"_____");
        }
        if(count < k){
            str = str.replace("_____","<censored>");
            System.out.println(str);
        }else{
            System.out.printf("%d\nHe Xie Ni Quan Jia!",count);
        }
    }
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值