【华为OD-E卷 - 敏感字段加密 100分(python、java、c++、js、c)】

【华为OD-E卷 - 敏感字段加密 100分(python、java、c++、js、c)】

题目

给定一个由多个命令字组成的命令字符串:
字符串长度小于等于127字节,只包含大小写字母,数字,下划线和偶数个双引号; 命令字之间以一个或多个下划线_进行分割; 可以通过两个双引号””来标识包含下划线_的命令字或空命令字(仅包含两个双引号的命令字),双引号不会在命令字内部出现; 请对指定索引的敏感字段进行加密,替换为
****(6个*),并删除命令字前后多余的下划线_。 如果无法找到指定索引的命令字,输出字符串ERROR**

输入描述

  • 输入为两行,第一行为命令字索引K(从0开始),第二行为命令字符串S

输出描述

  • 输出处理后的命令字符串,如果无法找到指定索引的命令字,输出字符串ERROR

用例

用例一:
输入:
1
password__a12345678_timeout_100
输出:
password_******_timeout_100
用例二:
输入:
password_******_timeout_100
输出:
aaa_password_******_timeout_100_""

python解法

  • 解题思路:
  • 这段代码的目标是处理一段字符串,根据输入的索引 k,将字符串中的第 k 个部分替换为 “******”,并返回替换后的字符串。字符串的分割规则如下:

分割规则:
双引号内的内容作为一个整体,不会被进一步分割。
其他部分根据下划线 _ 分割。
索引范围检查:
如果 k 超出分割后的部分数量,返回 “ERROR”。
替换部分:
将索引为 k 的部分替换为 “******”。
重新拼接字符串:
使用下划线 _ 将处理后的部分重新拼接成一个字符串。

import re

# 输入参数
k = int(input())  # 要替换的部分索引
s = input()       # 输入的字符串

# 处理字符串的函数
def process_command(k, s):
    # 使用正则表达式分割字符串
    # pattern:
    # - `"[^"]*"` 匹配双引号内的内容,包括引号
    # - `|` 表示或
    # - `[^_]+` 匹配非下划线的连续字符
    pattern = re.compile(r'"[^"]*"|[^_]+')
    matches = pattern.findall(s)  # 查找所有匹配的部分

    # 检查索引 k 是否有效
    if k >= len(matches):  # 如果 k 超出范围
        return "ERROR"     # 返回错误信息

    # 将第 k 个部分替换为 "******"
    matches[k] = "******"

    # 使用下划线将所有部分重新拼接成字符串
    return "_".join(matches)

# 调用函数并输出结果
print(process_command(k, s))

java解法

  • 解题思路
  • 这段代码的目标是处理一段字符串,根据输入的索引 idx,将字符串中的第 idx 个部分替换为 “******”,并返回替换后的结果。如果 idx 超出字符串的部分数量,返回 “ERROR”。字符串的分割规则如下:

分割规则:
双引号内的内容作为一个整体,不会被进一步分割。
其他部分根据下划线 _ 分割。
索引范围检查:
如果 idx 超出分割后的部分数量,返回 “ERROR”。
替换部分:
将索引为 idx 的部分替换为 “******”。
重新拼接字符串:
使用下划线 _ 将所有部分重新拼接成一个字符串

import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in); // 创建 Scanner 对象读取输入
        int idx = Integer.parseInt(in.nextLine()); // 读取第一个输入行作为索引
        String cmd = in.nextLine(); // 读取第二个输入行作为字符串

        System.out.println(procCmd(idx, cmd)); // 调用处理函数并输出结果
    }

    // 处理命令字符串
    public static String procCmd(int idx, String cmd) {
        // 定义正则表达式:
        // - `\"[^\"]*\"` 匹配双引号内的内容,包括双引号
        // - `[^_]+` 匹配非下划线的连续字符
        Pattern pat = Pattern.compile("\"[^\"]*\"|[^_]+");
        Matcher mat = pat.matcher(cmd); // 使用正则表达式匹配输入字符串
        StringBuilder res = new StringBuilder(); // 用于存储结果字符串

        int cnt = 0; // 记录当前部分的索引
        while (mat.find()) { // 遍历所有匹配的部分
            if (cnt++ == idx) { // 如果当前部分的索引等于目标索引
                res.append("******"); // 替换为 "******"
            } else {
                res.append(mat.group()); // 否则将原始部分加入结果
            }
            res.append("_"); // 在每部分后添加下划线
        }

        // 检查索引是否超出范围
        if (idx >= cnt) {
            return "ERROR"; // 如果目标索引大于等于总部分数,返回 "ERROR"
        }

        // 删除结果末尾多余的下划线并返回
        return res.substring(0, res.length() - 1);
    }
}

C++解法

  • 解题思路
  • 这段代码的目标是根据输入的索引 index,将字符串中的第 index 个部分替换为 “******”,并输出处理后的字符串。如果 index 超出了分割部分的数量,输出 “ERROR”。

字符串分割规则:

双引号包裹的内容:
双引号中的内容被视为一个整体,不会被分割。
双引号可以成对出现,也可以嵌套字符。
下划线 _ 分割部分:
未被双引号包裹的内容以下划线 _ 为分隔符分割为多个部分。
处理步骤:

遍历字符串,维护一个临时变量 part 用于存储当前部分。
使用标志变量 insideQuotes 记录当前是否在双引号范围内。
每当遇到下划线 _ 且不在双引号范围时,将当前部分加入结果,并根据索引判断是否替换为 “******”。
遍历结束后,处理最后一部分内容。
检查是否超出索引范围:
如果超出范围,输出 “ERROR”。
如果未超出范围,输出拼接后的结果。

#include 
#include 

int main() {
    int index; // 用于存储输入的目标索引
    std::cin >> index; // 读取目标索引
    std::string line;
    std::cin.ignore(); // 忽略上一次输入的换行符
    std::getline(std::cin, line); // 读取完整的一行字符串

    std::string part; // 用于存储当前解析的部分
    int count = 0; // 记录当前部分的索引
    bool insideQuotes = false; // 标记当前是否在双引号范围内
    std::string result; // 用于存储最终的拼接结果

    // 遍历整个字符串
    for (size_t i = 0; i < line.size(); ++i) {
        if (line[i] == '\"') {
            // 遇到双引号时切换 insideQuotes 状态
            insideQuotes = !insideQuotes;
            part.push_back(line[i]); // 将双引号加入当前部分
        }
        else if (!insideQuotes && line[i] == '_') {
            // 遇到下划线且不在双引号范围时
            if (!part.empty()) { // 当前部分非空
                if (count == index) { // 如果当前部分是目标索引
                    result += "******"; // 替换为 "******"
                }
                else {
                    result += part; // 否则加入原部分
                }
                result += "_"; // 添加下划线分隔符
                count++; // 增加部分计数
                part.clear(); // 清空当前部分
            }
        }
        else {
            part.push_back(line[i]); // 将字符加入当前部分
        }
    }

    // 处理最后一部分
    if (!part.empty()) { // 如果最后一部分非空
        if (count == index) {
            result += "******"; // 替换为 "******"
        }
        else {
            result += part; // 加入原部分
        }
    }
    else if (result.back() == '_') {
        result.pop_back(); // 删除结果末尾多余的下划线
    }

    // 检查是否超出索引范围
    if (count >= index) {
        std::cout << result << std::endl; // 输出处理后的结果
    }
    else {
        std::cout << "ERROR" << std::endl; // 索引超出范围时输出 "ERROR"
    }

    return 0;
}

C解法

  • 解题思路

更新中

JS解法

  • 解题思路

  • 这段代码实现了一个命令处理器,用于处理两个输入:

输入的第一个行:一个整数 k,表示要替换的部分索引。
输入的第二行:一个命令字符串,由 "_” 分隔多个部分,部分内容可能用双引号 " 包裹,双引号包裹的内容视为一个整体。
目标是:

按规则解析命令字符串。
如果索引 k 超出解析的部分数量,返回 “ERROR”。
否则,将索引为 k 的部分替换为 “******”,并返回处理后的字符串。

const readline = require("readline");

// 创建 CommandProcessor 类
class CommandProcessor {
    constructor() {
        this.lines = []; // 用于存储输入的两行内容
    }

    // 处理输入,每次读取一行
    processInput(line) {
        this.lines.push(line); // 将当前行添加到 `lines`
        if (this.lines.length === 2) { // 当读取到两行时开始处理
            const k = parseInt(this.lines[0]); // 第一行是索引 k
            const commandStr = this.lines[1]; // 第二行是命令字符串
            console.log(this.encryptSensitiveField(commandStr, k)); // 输出处理结果
            this.lines.length = 0; // 重置 `lines`,以便处理下一组输入
        }
    }

    // 将索引为 `index` 的部分替换为 "******"
    encryptSensitiveField(commandStr, index) {
        const commandList = this.parseCommands(commandStr); // 解析命令字符串为部分列表
        if (index >= commandList.length) { // 如果索引超出部分数量,返回 "ERROR"
            return "ERROR";
        }
        commandList[index] = "******"; // 替换目标部分为 "******"
        return commandList.join("_"); // 使用下划线将部分拼接为字符串返回
    }

    // 解析命令字符串为部分列表
    parseCommands(str) {
        let parts = []; // 存储解析后的部分
        let current = []; // 存储当前部分的字符
        for (let i = 0; i < str.length; i++) {
            if (str[i] === "_" && current[0] !== '"') {
                // 遇到下划线且当前部分不在双引号内时,将当前部分加入列表
                parts.push(current.join(""));
                current = [];
            } else if (str[i] === '"' && current.length !== 0) {
                // 遇到双引号且当前部分非空时,结束当前部分并加入列表
                parts.push(current.join("") + '"');
                current = [];
            } else {
                current.push(str[i]); // 将字符加入当前部分
            }
        }
        if (current.length) parts.push(current.join("")); // 处理最后一部分
        return parts.filter((part) => part !== ""); // 过滤掉空部分
    }
}

// 创建 `readline` 接口,用于读取输入
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
});

// 创建命令处理器实例
const processor = new CommandProcessor();

// 监听每行输入
rl.on("line", (line) => {
    processor.processInput(line); // 调用 `processInput` 处理当前输入行
});

注意:

如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏

你可能感兴趣的:(算法题,华为od,(A+B+C+D+E,卷)收录分享,华为od,python,java,c++,javascript)