{ }codelper
列表包含重复字符串P0194

遮住聊天里的违禁词

游戏聊天室用星号遮住违禁词。
第一行给出违禁词个数 n,第二行给出用空格隔开的 n 个违禁词。
第三行给出一行聊天内容,由小写英文单词组成,单词之间各隔一个空格。
聊天中与违禁词列表里某个单词完全相同的单词,换成与它字母数相同个数的星号(*)。
如果违禁词只是作为别的单词的一部分出现,那个单词不替换。
例如即使 cat 是违禁词,category 也保持原样。
违禁词列表里同一个单词可能出现两次。
输出替换后的聊天内容,单词之间各隔一个空格,占一行。

输入
1 ≤ n ≤ 100,聊天单词数 1 到 1,000,违禁词和单词都是 1 到 20 个小写字母
输出
一行,遮住后的聊天内容
样例 1 · stdin
2
cat dog
the cat sat on a category of dogs with a dog
stdout
the *** sat on a category of dogs with a ***
main.py
输入(stdin)

运行时这些行会依次作为 input()/标准输入传入(运行中不会等待输入)。

$ 就绪

请在电脑上打开以编写和运行代码。在手机上可以查看题目和题解。

其他语言怎么写?查看各语言题解 · 8 种语言题解

这道题的陷阱是把"在列表里吗"和"在字符串里吗"搞混。
同名的操作有两种意思。
Python 的 in 在列表里找相等的元素,在字符串里找子串。
如果违禁词那一行不 split() 而直接当字符串,"at" in "cat dog" 就是真。
JS/TS 的 includes 也一样:数组是相等的元素,字符串是子串。
Craykon 的 包含 在列表和字符串上也有同样的区别。
Java 用 List.contains,C# 用 List.Contains(数组可用 LINQ 的 Contains 或 Array.IndexOf),C++ 用 std::find(v.begin(), v.end(), w) != v.end()。
std::vector 没有 contains 成员(C++23 起另有算法 std::ranges::contains(v, w))。
C 没有列表查找,要用循环和 strcmp 自己找。
C 中用 == 比较的是地址而不是内容,所以一个也匹配不上。
对整行用 replace 会把 category 里的 cat 也遮住,所以要按单词判断。
生成星号:Python "*" * len(w),JS/TS/Java "*".repeat(n),C# new string('*', n),C++ std::string(n, '*'),Craykon "*".重复(n),C 则 putchar n 次。

Pythonmain.py · 10 行
n = int(input())banned = input().split()   # 문자열이 아니라 낱말 목록으로 둔다words = input().split()out = []for w in words:    if w in banned:        # 목록에서 통째로 같은 낱말을 찾는다        out.append("*" * len(w))    else:        out.append(w)print(" ".join(out))
JavaScriptmain.js · 6 行
const lines = require("fs").readFileSync(0, "utf8").split("\n");const banned = lines[1].trim().split(/\s+/); // 낱말 배열const words = lines[2].trim().split(/\s+/);// 배열의 includes는 같은 낱말을 찾는다(문자열의 includes는 부분 문자열을 찾는다)const out = words.map((w) => (banned.includes(w) ? "*".repeat(w.length) : w));console.log(out.join(" "));
TypeScriptmain.ts · 7 行
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const banned: string[] = lines[1].trim().split(/\s+/); // 낱말 배열const words: string[] = lines[2].trim().split(/\s+/);// 배열의 includes는 같은 낱말을 찾는다(문자열의 includes는 부분 문자열을 찾는다)const out: string[] = words.map((w) => (banned.includes(w) ? "*".repeat(w.length) : w));console.log(out.join(" "));
JavaMain.java · 20 行
import java.io.BufferedReader;import java.io.InputStreamReader;import java.util.Arrays;import java.util.List; public class Main {    public static void main(String[] args) throws Exception {        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));        in.readLine();        List<String> banned = Arrays.asList(in.readLine().trim().split(" "));        String[] words = in.readLine().trim().split(" ");        StringBuilder out = new StringBuilder();        for (int i = 0; i < words.length; i++) {            if (i > 0) out.append(' ');            // List.contains는 equals로 비교한다(==는 같은 객체인지를 본다)            out.append(banned.contains(words[i]) ? "*".repeat(words[i].length()) : words[i]);        }        System.out.println(out);    }}
C#Main.cs · 21 行
using System;using System.Collections.Generic; class Program{    static void Main()    {        Console.ReadLine();        var banned = new List<string>(Console.ReadLine().Trim().Split(' '));        string[] words = Console.ReadLine().Trim().Split(' ');        for (int i = 0; i < words.Length; i++)        {            // List.Contains는 낱말이 통째로 같은지 본다            if (banned.Contains(words[i]))            {                words[i] = new string('*', words[i].Length);            }        }        Console.WriteLine(string.Join(" ", words));    }}
C++main.cpp · 21 行
#include <algorithm>#include <iostream>#include <string>#include <vector> int main() {    int n;    std::cin >> n;    std::vector<std::string> banned(n);    for (auto& b : banned) std::cin >> b;    std::string w;    bool first = true;    while (std::cin >> w) {        if (!first) std::cout << ' ';        first = false;        // std::find로 같은 낱말을 찾는다(vector에는 contains 멤버가 없다)        bool hit = std::find(banned.begin(), banned.end(), w) != banned.end();        std::cout << (hit ? std::string(w.size(), '*') : w);    }    std::cout << '\n';}
Cmain.c · 31 行
#include <stdio.h>#include <string.h> static char banned[100][21];static int n; /* 목록에 같은 낱말이 있나: 내용 비교는 strcmp(==는 주소를 비교한다) */int contains(const char *w) {    for (int i = 0; i < n; i++) {        if (strcmp(banned[i], w) == 0) return 1;    }    return 0;} int main(void) {    char w[21];    scanf("%d", &n);    for (int i = 0; i < n; i++) scanf("%20s", banned[i]);    int first = 1;    while (scanf("%20s", w) == 1) {        if (!first) putchar(' ');        first = 0;        if (contains(w)) {            for (size_t k = 0; k < strlen(w); k++) putchar('*');        } else {            fputs(w, stdout);        }    }    putchar('\n');    return 0;}
Craykonmain.cray · 17 行
n = 控制台.读行().转数字();banned = 控制台.读行().去空白().分割(); // 낱말 목록words = 控制台.读行().去空白().分割();out = [];遍历 (w 在 words){    // 목록의 있나는 같은 낱말을 찾는다(문자열의 있나는 부분 문자열을 찾는다)    如果 (banned.包含(w))    {        out.添加("*".重复(w.长度));    }    否则    {        out.添加(w);    }}控制台.输出(out.连接(" "));