屏蔽敏感词

题目描述

为了净化网络环境,需要开发一个简易的敏感词屏蔽功能:给定敏感词,按如下规则,对待检查字符串进行匹配和替换:

  • 敏感词中的各字符顺序地出现在待检查字符串中,且第一个字符和最后一个字符之间的其它字符个数小于敏感词长度,连同其它字符一起替换为星号 *。如:敏感词 135 可匹配字符串1?3?5、1??35,不匹配1?3??5。
  • 支持贪婪匹配,即每次从左到右扫描,一旦遇到可匹配的情况就开始进行匹配,且匹配尽可能长的字符,例如:
    • 敏感词为 ab 时,字符串 abbc 应该替换成 *c ,而不是 *bc
    • 敏感词为 abc 时,字符串 aabcbc 应该替换成 *bc,而不是 a* (遇到首个 a 时就开始进行匹配)
  • 支持全量匹配,即:有多处符合匹配规则时,则需要全部进行匹配和替换。

请输出屏蔽后的字符串。

解答要求时间限制:1000ms, 内存限制:128MB
输入

第一行字符串,表示待检查字符串,仅含英文字母和数字,长度范围:[2,20]。
第二行字符串,表示敏感词,长度范围:[2,20]。

输出

屏蔽后的字符串

样例

输入样例 1 复制

ABCdfgABC
ABC

输出样例 1

*dfg*
提示样例 1

注意全量匹配,待检查字符串中有两处符合匹配规则,首个ABC以及最后一个ABC,都替换为*后,屏蔽后输出为 *dfg* 。



输入样例 2 复制

abbdefghjjk
bdfhj

输出样例 2

a*k
提示样例 2

注意贪婪匹配:从第二个字符b开始匹配到第十个字符j,中间干扰字符个数为4(含 begj),小于敏感词的长度5,因此屏蔽后输出为:a*k



输入样例 3 复制

abbbbbcde
abc

输出样例 3

abbbbbcde
提示样例 3

a 和 c之间的字符串 bbbbb 长度超过了敏感词的长度,因此无屏蔽。

 

 

考察正则算法:

贪婪匹配

 

/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
 * Description: 上机编程认证
 * Note: 缺省代码仅供参考,可自行决定使用、修改或删除
 * 只能import Go标准库
 */
package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
    "strings"
    "regexp"
)

// 待实现函数,在此函数中填入答题代码

func getMaskedStr(checkedStr string, sensitiveStr string) string {
    sens := strings.Join(strings.Split(sensitiveStr, ""), `\w*`)
    senStrLen := len(sensitiveStr)
    var result []string
    i := 0
    for i < len(checkedStr) {
        if checkedStr[i] == sens[0] {
            reGroup := regexp.MustCompile(sens).FindString(checkedStr[i:min(i+2*senStrLen-1, len(checkedStr))])
            if reGroup != "" {
                result = append(result, "*")
                i += len(reGroup)
                continue
            }
        }
        result = append(result, string(checkedStr[i]))
        i++
    }
    return strings.Join(result, "")
}

func min(a, b int) int {
    if a < b {
        return a
    }
    return b
}

func main() {
    reader := bufio.NewReader(os.Stdin)
    checkedStr, err1 := readInputString(reader)
    if err1 != nil {
        fmt.Println(err1.Error())
        return
    }
    sensitiveStr, err2 := readInputString(reader)
    if err2 != nil {
        fmt.Println(err2.Error())
        return
    }
    result := getMaskedStr(checkedStr, sensitiveStr)
    fmt.Println(result)
}
func readInputString(reader *bufio.Reader) (string, error) {
    lineBuf, err := reader.ReadString('\n')
    if err != nil && err != io.EOF {
        return "nil", err
    }
    lineBuf = strings.TrimRight(lineBuf, "\r\n")
    lineBuf = strings.TrimSpace(lineBuf)
    return lineBuf, nil
}
View Code

 

 

Demo:

 

package main

import (
    "fmt"
    "regexp"
    "strings"
)

func main() {
    checkedStr := "ABCdfgABC"
    sensitiveStr := "ABC"
    maskedStr := getMaskedStr(checkedStr, sensitiveStr)
    fmt.Println(maskedStr) // 输出:*dfg*
}

func getMaskedStr(checkedStr string, sensitiveStr string) string {
    sens := strings.Join(strings.Split(sensitiveStr, ""), `\w*`)
    senStrLen := len(sensitiveStr)
    var result []string
    i := 0
    for i < len(checkedStr) {
        if checkedStr[i] == sens[0] {
            reGroup := regexp.MustCompile(sens).FindString(checkedStr[i:min(i+2*senStrLen-1, len(checkedStr))])
            if reGroup != "" {
                result = append(result, "*")
                i += len(reGroup)
                continue
            }
        }
        result = append(result, string(checkedStr[i]))
        i++
    }
    return strings.Join(result, "")
}

func min(a, b int) int {
    if a < b {
        return a
    }
    return b
}
View Code

 

 
posted @ 2023-12-18 19:03  易先讯  阅读(20)  评论(0编辑  收藏  举报