当前位置: 首页 > article >正文

【2024年华为OD机试】 (B卷,100分)- 敏感字段加密(Java JS PythonC/C++)

在这里插入图片描述

一、问题描述

题目描述

给定一个由多个命令字组成的命令字符串:

  1. 字符串长度小于等于 127 字节,只包含大小写字母、数字、下划线和偶数个双引号;
  2. 命令字之间以一个或多个下划线 _ 进行分割;
  3. 可以通过两个双引号 "" 来标识包含下划线 _ 的命令字或空命令字(仅包含两个双引号的命令字),双引号不会在命令字内部出现。

请对指定索引的敏感字段进行加密,替换为 ******(6 个 *),并删除命令字前后多余的下划线 _
如果无法找到指定索引的命令字,输出字符串 ERROR

输入描述

输入为两行:

  1. 第一行为命令字索引 K(从 0 开始);
  2. 第二行为命令字符串 S

输出描述

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

用例

用例 1

输入:

1
password__a12345678_timeout_100

输出:

password_******_timeout_100

说明:

  • 命令字符串被分割为 ["password", "a12345678", "timeout", "100"]
  • 索引 1 对应的命令字是 a12345678,替换为 ******
  • 最终输出为 password_******_timeout_100

用例 2

输入:

2
aaa_password_"a12_45678"_timeout__100_""_

输出:

aaa_password_******_timeout_100_""

说明:

  • 命令字符串被分割为 ["aaa", "password", "\"a12_45678\"", "timeout", "", "100", "\"\"", ""]
  • 过滤掉空串后为 ["aaa", "password", "\"a12_45678\"", "timeout", "100", "\"\""]
  • 索引 2 对应的命令字是 "a12_45678",替换为 ******
  • 最终输出为 aaa_password_******_timeout_100_""

题目解析

问题分析

我们需要处理一个命令字符串,将其分割为多个命令字,并对指定索引的命令字进行加密。命令字之间通过下划线 _ 分割,但包含在双引号 "" 中的下划线 _ 是命令字的一部分,而不是分隔符。

解题思路

  1. 分割命令字符串

    • 使用栈结构来遍历字符串,逐个字符处理。
    • 遇到下划线 _ 时,判断是否是命令字分隔符:
      • 如果栈底是双引号 ",则当前下划线是命令字的一部分,保留。
      • 否则,当前下划线是分隔符,将栈中的内容作为一个命令字保存,并清空栈。
    • 遇到双引号 " 时,判断是否是命令字的开始或结束:
      • 如果栈为空,则当前双引号是命令字的开始。
      • 否则,当前双引号是命令字的结束,将栈中的内容作为一个命令字保存,并清空栈。
    • 其他字符直接压入栈中。
  2. 过滤空命令字

    • 分割后的命令字列表中可能包含空字符串,需要过滤掉。
  3. 加密指定索引的命令字

    • 如果指定索引超出命令字列表的范围,输出 ERROR
    • 否则,将指定索引的命令字替换为 ******
  4. 拼接最终结果

    • 将处理后的命令字列表用下划线 _ 连接,形成最终的输出字符串。

关键点

  • 栈的使用:通过栈结构可以灵活处理包含在双引号中的下划线。
  • 双引号的处理:双引号用于标识包含下划线的命令字或空命令字。
  • 空命令字的过滤:分割后的命令字列表中可能包含空字符串,需要过滤掉。

示例解析

示例 1

输入:

1
password__a12345678_timeout_100

处理过程:

  1. 分割命令字符串:
    • ["password", "a12345678", "timeout", "100"]
  2. 加密索引 1 的命令字:
    • ["password", "******", "timeout", "100"]
  3. 拼接结果:
    • password_******_timeout_100

示例 2

输入:

2
aaa_password_"a12_45678"_timeout__100_""_

处理过程:

  1. 分割命令字符串:
    • ["aaa", "password", "\"a12_45678\"", "timeout", "", "100", "\"\"", ""]
  2. 过滤空命令字:
    • ["aaa", "password", "\"a12_45678\"", "timeout", "100", "\"\""]
  3. 加密索引 2 的命令字:
    • ["aaa", "password", "******", "timeout", "100", "\"\""]
  4. 拼接结果:
    • aaa_password_******_timeout_100_""

总结

通过栈结构可以有效地处理包含双引号的命令字符串,确保下划线在双引号内不被误认为分隔符。过滤空命令字后,对指定索引的命令字进行加密,最终拼接为处理后的字符串。

二、JavaScript算法源码

代码详细注释与讲解


1. 输入获取
const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

const lines = [];
rl.on("line", (line) => {
  lines.push(line);

  if (lines.length === 2) {
    const k = parseInt(lines[0]); // 解析命令字索引 K
    const s = lines[1]; // 获取命令字符串 S

    console.log(encryptSensitive(s, k)); // 调用核心逻辑并输出结果

    lines.length = 0; // 清空输入缓存
  }
});
  • 功能:从控制台读取输入并解析为命令字索引 K 和命令字符串 S
  • 关键点
    • readline 模块用于逐行读取输入。
    • lines 数组用于存储输入的两行数据。
    • 当输入行数为 2 时,解析 KS,并调用核心逻辑函数 encryptSensitive

2. 核心逻辑
function encryptSensitive(s, k) {
  let stack = []; // 用于存储当前命令字的字符
  let result = []; // 用于存储所有命令字

  for (let i = 0; i < s.length; i++) {
    if (s[i] === "_" && stack[0] !== '"') {
      // 如果当前字符是下划线且栈底不是双引号,则说明是分隔符
      result.push(stack.join("")); // 将栈中的字符拼接为命令字并存入结果
      stack.length = 0; // 清空栈
    } else if (s[i] === '"' && stack.length !== 0) {
      // 如果当前字符是双引号且栈不为空,则说明是命令字的结束
      result.push(stack.join("") + '"'); // 将栈中的字符拼接为命令字并存入结果
      stack.length = 0; // 清空栈
    } else {
      // 其他字符直接压入栈中
      stack.push(s[i]);
    }
  }
  if (stack.length) result.push(stack.join("")); // 处理最后一个命令字

  result = result.filter((ele) => ele !== ""); // 过滤掉空命令字

  if (k > result.length - 1) return "ERROR"; // 如果索引超出范围,返回 ERROR

  result[k] = "******"; // 加密指定索引的命令字

  return result.join("_"); // 将命令字用下划线连接并返回
}
  • 功能:对命令字符串进行处理,加密指定索引的命令字。
  • 关键点
    • 栈的使用
      • stack 用于存储当前命令字的字符。
      • 当遇到分隔符或双引号时,将栈中的字符拼接为命令字并存入 result
    • 命令字分割
      • 如果当前字符是下划线 _ 且栈底不是双引号 ",则说明是分隔符。
      • 如果当前字符是双引号 " 且栈不为空,则说明是命令字的结束。
    • 过滤空命令字
      • 使用 filter 方法过滤掉空字符串。
    • 索引检查
      • 如果索引 k 超出命令字列表的范围,返回 ERROR
    • 加密命令字
      • 将指定索引的命令字替换为 ******
    • 拼接结果
      • 使用 join("_") 将命令字用下划线连接并返回。

代码逻辑总结

  1. 输入处理

    • 从控制台读取输入并解析为命令字索引 K 和命令字符串 S
  2. 命令字分割

    • 使用栈结构遍历字符串,逐个字符处理。
    • 遇到分隔符或双引号时,将栈中的字符拼接为命令字并存入结果列表。
  3. 过滤空命令字

    • 过滤掉结果列表中的空字符串。
  4. 索引检查与加密

    • 如果索引 K 超出范围,返回 ERROR
    • 否则,将指定索引的命令字替换为 ******
  5. 拼接结果

    • 将处理后的命令字列表用下划线 _ 连接并返回。

示例运行

输入 1:
1
password__a12345678_timeout_100
输出 1:
password_******_timeout_100
解释:
  1. 命令字符串被分割为 ["password", "a12345678", "timeout", "100"]
  2. 索引 1 对应的命令字是 a12345678,替换为 ******
  3. 最终输出为 password_******_timeout_100

输入 2:
2
aaa_password_"a12_45678"_timeout__100_""_
输出 2:
aaa_password_******_timeout_100_""
解释:
  1. 命令字符串被分割为 ["aaa", "password", "\"a12_45678\"", "timeout", "", "100", "\"\"", ""]
  2. 过滤掉空串后为 ["aaa", "password", "\"a12_45678\"", "timeout", "100", "\"\""]
  3. 索引 2 对应的命令字是 "a12_45678",替换为 ******
  4. 最终输出为 aaa_password_******_timeout_100_""

总结

  • 通过栈结构可以有效地处理包含双引号的命令字符串,确保下划线在双引号内不被误认为分隔符。
  • 过滤空命令字后,对指定索引的命令字进行加密,最终拼接为处理后的字符串。
  • 代码逻辑清晰,易于理解和扩展。

三、Java算法源码

代码详细注释与讲解

以下是代码的逐行注释和逻辑讲解:


1. 输入获取
Scanner sc = new Scanner(System.in);

int k = Integer.parseInt(sc.nextLine()); // 读取命令字索引 K
String s = sc.nextLine(); // 读取命令字符串 S

System.out.println(getResult(k, s)); // 调用核心逻辑并输出结果
  • 功能:从控制台读取输入并解析为命令字索引 K 和命令字符串 S
  • 关键点
    • Scanner 用于读取输入。
    • sc.nextLine() 读取一行输入。
    • Integer.parseInt 将字符串转换为整数。

2. 核心逻辑
public static String getResult(int k, String s) {
    StringBuilder stack = new StringBuilder(); // 用于存储当前命令字的字符
    LinkedList<String> result = new LinkedList<>(); // 用于存储所有命令字

    for (int i = 0; i < s.length(); i++) {
        char c = s.charAt(i);

        if (c == '_' && (stack.length() == 0 || stack.charAt(0) != '"')) {
            // 如果当前字符是下划线且栈为空或栈底不是双引号,则说明是分隔符
            result.add(stack.toString()); // 将栈中的字符拼接为命令字并存入结果
            stack = new StringBuilder(); // 清空栈
        } else if (c == '"' && stack.length() != 0) {
            // 如果当前字符是双引号且栈不为空,则说明是命令字的结束
            stack.append('"'); // 将双引号加入栈中
            result.add(stack.toString()); // 将栈中的字符拼接为命令字并存入结果
            stack = new StringBuilder(); // 清空栈
        } else {
            // 其他字符直接加入栈中
            stack.append(c);
        }
    }

    if (stack.length() > 0) result.add(stack.toString()); // 处理最后一个命令字

    // 过滤掉空命令字
    List<String> ans = result.stream().filter(str -> !"".equals(str)).collect(Collectors.toList());

    if (k > ans.size() - 1) return "ERROR"; // 如果索引超出范围,返回 ERROR

    ans.set(k, "******"); // 加密指定索引的命令字

    // 将命令字用下划线连接并返回
    StringJoiner sj = new StringJoiner("_");
    for (String an : ans) sj.add(an);
    return sj.toString();
}
  • 功能:对命令字符串进行处理,加密指定索引的命令字。
  • 关键点
    • 栈的使用
      • StringBuilder 用于存储当前命令字的字符。
      • 当遇到分隔符或双引号时,将栈中的字符拼接为命令字并存入 result
    • 命令字分割
      • 如果当前字符是下划线 _ 且栈为空或栈底不是双引号 ",则说明是分隔符。
      • 如果当前字符是双引号 " 且栈不为空,则说明是命令字的结束。
    • 过滤空命令字
      • 使用 filter 方法过滤掉空字符串。
    • 索引检查
      • 如果索引 k 超出命令字列表的范围,返回 ERROR
    • 加密命令字
      • 将指定索引的命令字替换为 ******
    • 拼接结果
      • 使用 StringJoiner 将命令字用下划线 _ 连接并返回。

代码逻辑总结

  1. 输入处理

    • 从控制台读取输入并解析为命令字索引 K 和命令字符串 S
  2. 命令字分割

    • 使用 StringBuilder 遍历字符串,逐个字符处理。
    • 遇到分隔符或双引号时,将栈中的字符拼接为命令字并存入结果列表。
  3. 过滤空命令字

    • 过滤掉结果列表中的空字符串。
  4. 索引检查与加密

    • 如果索引 K 超出范围,返回 ERROR
    • 否则,将指定索引的命令字替换为 ******
  5. 拼接结果

    • 使用 StringJoiner 将处理后的命令字列表用下划线 _ 连接并返回。

示例运行

输入 1:
1
password__a12345678_timeout_100
输出 1:
password_******_timeout_100
解释:
  1. 命令字符串被分割为 ["password", "a12345678", "timeout", "100"]
  2. 索引 1 对应的命令字是 a12345678,替换为 ******
  3. 最终输出为 password_******_timeout_100

输入 2:
2
aaa_password_"a12_45678"_timeout__100_""_
输出 2:
aaa_password_******_timeout_100_""
解释:
  1. 命令字符串被分割为 ["aaa", "password", "\"a12_45678\"", "timeout", "", "100", "\"\"", ""]
  2. 过滤掉空串后为 ["aaa", "password", "\"a12_45678\"", "timeout", "100", "\"\""]
  3. 索引 2 对应的命令字是 "a12_45678",替换为 ******
  4. 最终输出为 aaa_password_******_timeout_100_""

总结

  • 通过 StringBuilderLinkedList 可以有效地处理包含双引号的命令字符串,确保下划线在双引号内不被误认为分隔符。
  • 过滤空命令字后,对指定索引的命令字进行加密,最终拼接为处理后的字符串。
  • 代码逻辑清晰,易于理解和扩展。

四、Python算法源码

代码详细注释与讲解

以下是代码的逐行注释和逻辑讲解:


1. 输入获取
k = int(input())  # 读取命令字索引 K
s = input()  # 读取命令字符串 S
  • 功能:从控制台读取输入并解析为命令字索引 K 和命令字符串 S
  • 关键点
    • input() 用于读取一行输入。
    • int() 将字符串转换为整数。

2. 核心逻辑
def getResult(k, s):
    stack = []  # 用于存储当前命令字的字符
    res = []  # 用于存储所有命令字

    for c in s:
        if c == '_' and (len(stack) == 0 or stack[0] != '"'):
            # 如果当前字符是下划线且栈为空或栈底不是双引号,则说明是分隔符
            res.append("".join(stack))  # 将栈中的字符拼接为命令字并存入结果
            stack = []  # 清空栈
        elif c == '"' and len(stack) != 0:
            # 如果当前字符是双引号且栈不为空,则说明是命令字的结束
            stack.append(c)  # 将双引号加入栈中
            res.append("".join(stack))  # 将栈中的字符拼接为命令字并存入结果
            stack = []  # 清空栈
        else:
            # 其他字符直接加入栈中
            stack.append(c)

    if len(stack) > 0:
        res.append("".join(stack))  # 处理最后一个命令字

    # 过滤掉空命令字
    ans = list(filter(lambda x: x != "", res))

    if k > len(ans) - 1:
        return "ERROR"  # 如果索引超出范围,返回 ERROR

    ans[k] = "******"  # 加密指定索引的命令字

    return "_".join(ans)  # 将命令字用下划线连接并返回
  • 功能:对命令字符串进行处理,加密指定索引的命令字。
  • 关键点
    • 栈的使用
      • stack 用于存储当前命令字的字符。
      • 当遇到分隔符或双引号时,将栈中的字符拼接为命令字并存入 res
    • 命令字分割
      • 如果当前字符是下划线 _ 且栈为空或栈底不是双引号 ",则说明是分隔符。
      • 如果当前字符是双引号 " 且栈不为空,则说明是命令字的结束。
    • 过滤空命令字
      • 使用 filter 方法过滤掉空字符串。
    • 索引检查
      • 如果索引 k 超出命令字列表的范围,返回 ERROR
    • 加密命令字
      • 将指定索引的命令字替换为 ******
    • 拼接结果
      • 使用 join("_") 将命令字用下划线 _ 连接并返回。

代码逻辑总结

  1. 输入处理

    • 从控制台读取输入并解析为命令字索引 K 和命令字符串 S
  2. 命令字分割

    • 使用栈结构遍历字符串,逐个字符处理。
    • 遇到分隔符或双引号时,将栈中的字符拼接为命令字并存入结果列表。
  3. 过滤空命令字

    • 过滤掉结果列表中的空字符串。
  4. 索引检查与加密

    • 如果索引 K 超出范围,返回 ERROR
    • 否则,将指定索引的命令字替换为 ******
  5. 拼接结果

    • 将处理后的命令字列表用下划线 _ 连接并返回。

示例运行

输入 1:
1
password__a12345678_timeout_100
输出 1:
password_******_timeout_100
解释:
  1. 命令字符串被分割为 ["password", "a12345678", "timeout", "100"]
  2. 索引 1 对应的命令字是 a12345678,替换为 ******
  3. 最终输出为 password_******_timeout_100

输入 2:
2
aaa_password_"a12_45678"_timeout__100_""_
输出 2:
aaa_password_******_timeout_100_""
解释:
  1. 命令字符串被分割为 ["aaa", "password", "\"a12_45678\"", "timeout", "", "100", "\"\"", ""]
  2. 过滤掉空串后为 ["aaa", "password", "\"a12_45678\"", "timeout", "100", "\"\""]
  3. 索引 2 对应的命令字是 "a12_45678",替换为 ******
  4. 最终输出为 aaa_password_******_timeout_100_""

总结

  • 通过栈结构可以有效地处理包含双引号的命令字符串,确保下划线在双引号内不被误认为分隔符。
  • 过滤空命令字后,对指定索引的命令字进行加密,最终拼接为处理后的字符串。
  • 代码逻辑清晰,易于理解和扩展。

五、C/C++算法源码:

以下是代码的 C++C 语言实现,并附带详细的中文注释和讲解。


C++ 实现

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;

// 核心逻辑函数
string getResult(int k, const string& s) {
    vector<char> stack; // 用于存储当前命令字的字符
    vector<string> res; // 用于存储所有命令字

    for (char c : s) {
        if (c == '_' && (stack.empty() || stack[0] != '"')) {
            // 如果当前字符是下划线且栈为空或栈底不是双引号,则说明是分隔符
            res.push_back(string(stack.begin(), stack.end())); // 将栈中的字符拼接为命令字并存入结果
            stack.clear(); // 清空栈
        } else if (c == '"' && !stack.empty()) {
            // 如果当前字符是双引号且栈不为空,则说明是命令字的结束
            stack.push_back(c); // 将双引号加入栈中
            res.push_back(string(stack.begin(), stack.end())); // 将栈中的字符拼接为命令字并存入结果
            stack.clear(); // 清空栈
        } else {
            // 其他字符直接加入栈中
            stack.push_back(c);
        }
    }

    // 处理最后一个命令字
    if (!stack.empty()) {
        res.push_back(string(stack.begin(), stack.end()));
    }

    // 过滤掉空命令字
    vector<string> ans;
    for (const string& str : res) {
        if (!str.empty()) {
            ans.push_back(str);
        }
    }

    // 如果索引超出范围,返回 ERROR
    if (k > ans.size() - 1) {
        return "ERROR";
    }

    // 加密指定索引的命令字
    ans[k] = "******";

    // 将命令字用下划线连接并返回
    string result;
    for (size_t i = 0; i < ans.size(); i++) {
        if (i != 0) {
            result += "_";
        }
        result += ans[i];
    }

    return result;
}

int main() {
    int k;
    string s;

    // 读取输入
    cin >> k;
    cin.ignore(); // 忽略换行符
    getline(cin, s);

    // 调用核心逻辑并输出结果
    cout << getResult(k, s) << endl;

    return 0;
}

C 语言实现

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

#define MAX_SIZE 1000

// 核心逻辑函数
char* getResult(int k, const char* s) {
    char stack[MAX_SIZE]; // 用于存储当前命令字的字符
    int stackSize = 0; // 栈的大小

    char* res[MAX_SIZE]; // 用于存储所有命令字
    int resSize = 0; // 结果数组的大小

    for (int i = 0; s[i] != '\0'; i++) {
        char c = s[i];

        if (c == '_' && (stackSize == 0 || stack[0] != '"')) {
            // 如果当前字符是下划线且栈为空或栈底不是双引号,则说明是分隔符
            stack[stackSize] = '\0'; // 添加字符串结束符
            res[resSize] = (char*)malloc((stackSize + 1) * sizeof(char));
            strcpy(res[resSize], stack); // 将栈中的字符拼接为命令字并存入结果
            resSize++;
            stackSize = 0; // 清空栈
        } else if (c == '"' && stackSize != 0) {
            // 如果当前字符是双引号且栈不为空,则说明是命令字的结束
            stack[stackSize++] = c; // 将双引号加入栈中
            stack[stackSize] = '\0'; // 添加字符串结束符
            res[resSize] = (char*)malloc((stackSize + 1) * sizeof(char));
            strcpy(res[resSize], stack); // 将栈中的字符拼接为命令字并存入结果
            resSize++;
            stackSize = 0; // 清空栈
        } else {
            // 其他字符直接加入栈中
            stack[stackSize++] = c;
        }
    }

    // 处理最后一个命令字
    if (stackSize > 0) {
        stack[stackSize] = '\0'; // 添加字符串结束符
        res[resSize] = (char*)malloc((stackSize + 1) * sizeof(char));
        strcpy(res[resSize], stack); // 将栈中的字符拼接为命令字并存入结果
        resSize++;
    }

    // 过滤掉空命令字
    char* ans[MAX_SIZE];
    int ansSize = 0;
    for (int i = 0; i < resSize; i++) {
        if (strlen(res[i]) > 0) {
            ans[ansSize++] = res[i];
        } else {
            free(res[i]); // 释放空字符串的内存
        }
    }

    // 如果索引超出范围,返回 ERROR
    if (k > ansSize - 1) {
        for (int i = 0; i < ansSize; i++) {
            free(ans[i]); // 释放内存
        }
        return "ERROR";
    }

    // 加密指定索引的命令字
    free(ans[k]); // 释放原命令字的内存
    ans[k] = (char*)malloc(7 * sizeof(char));
    strcpy(ans[k], "******");

    // 将命令字用下划线连接并返回
    char* result = (char*)malloc(MAX_SIZE * sizeof(char));
    result[0] = '\0'; // 初始化结果字符串
    for (int i = 0; i < ansSize; i++) {
        if (i != 0) {
            strcat(result, "_");
        }
        strcat(result, ans[i]);
    }

    // 释放内存
    for (int i = 0; i < ansSize; i++) {
        free(ans[i]);
    }

    return result;
}

int main() {
    int k;
    char s[MAX_SIZE];

    // 读取输入
    scanf("%d", &k);
    getchar(); // 忽略换行符
    fgets(s, MAX_SIZE, stdin);
    s[strcspn(s, "\n")] = '\0'; // 去掉换行符

    // 调用核心逻辑并输出结果
    char* result = getResult(k, s);
    printf("%s\n", result);

    // 释放内存
    free(result);

    return 0;
}

代码详细注释与讲解

1. 输入获取
  • C++
    • 使用 cin 读取命令字索引 k 和命令字符串 s
    • cin.ignore() 用于忽略换行符。
  • C
    • 使用 scanf 读取命令字索引 k
    • 使用 fgets 读取命令字符串 s,并去掉换行符。
2. 核心逻辑
  • 栈的使用
    • 使用栈结构遍历字符串,逐个字符处理。
    • 当遇到分隔符或双引号时,将栈中的字符拼接为命令字并存入结果列表。
  • 命令字分割
    • 如果当前字符是下划线 _ 且栈为空或栈底不是双引号 ",则说明是分隔符。
    • 如果当前字符是双引号 " 且栈不为空,则说明是命令字的结束。
  • 过滤空命令字
    • 过滤掉结果列表中的空字符串。
  • 索引检查与加密
    • 如果索引 k 超出范围,返回 ERROR
    • 否则,将指定索引的命令字替换为 ******
  • 拼接结果
    • 将处理后的命令字列表用下划线 _ 连接并返回。
3. 内存管理
  • C++
    • 使用 vectorstring 自动管理内存。
  • C
    • 使用 mallocfree 手动管理内存,避免内存泄漏。

示例运行

输入 1:
1
password__a12345678_timeout_100
输出 1:
password_******_timeout_100
解释:
  1. 命令字符串被分割为 ["password", "a12345678", "timeout", "100"]
  2. 索引 1 对应的命令字是 a12345678,替换为 ******
  3. 最终输出为 password_******_timeout_100

输入 2:
2
aaa_password_"a12_45678"_timeout__100_""_
输出 2:
aaa_password_******_timeout_100_""
解释:
  1. 命令字符串被分割为 ["aaa", "password", "\"a12_45678\"", "timeout", "", "100", "\"\"", ""]
  2. 过滤掉空串后为 ["aaa", "password", "\"a12_45678\"", "timeout", "100", "\"\""]
  3. 索引 2 对应的命令字是 "a12_45678",替换为 ******
  4. 最终输出为 aaa_password_******_timeout_100_""

总结

  • C++C 的实现逻辑一致,主要区别在于输入处理和内存管理。
  • C++ 使用 vectorstring 简化了数组和字符串的操作。
  • C 使用数组和指针手动处理字符串分割和内存管理。
  • 代码通过栈结构可以有效地处理包含双引号的命令字符串,确保下划线在双引号内不被误认为分隔符。

六、尾言

什么是华为OD?

华为OD(Outsourcing Developer,外包开发工程师)是华为针对软件开发工程师岗位的一种招聘形式,主要包括笔试、技术面试以及综合面试等环节。尤其在笔试部分,算法题的机试至关重要。

为什么刷题很重要?

  1. 机试是进入技术面的第一关:
    华为OD机试(常被称为机考)主要考察算法和编程能力。只有通过机试,才能进入后续的技术面试环节。

  2. 技术面试需要手撕代码:
    技术一面和二面通常会涉及现场编写代码或算法题。面试官会注重考察候选人的思路清晰度、代码规范性以及解决问题的能力。因此提前刷题、多练习是通过面试的重要保障。

  3. 入职后的可信考试:
    入职华为后,还需要通过“可信考试”。可信考试分为三个等级:

    • 入门级:主要考察基础算法与编程能力。
    • 工作级:更贴近实际业务需求,可能涉及复杂的算法或与工作内容相关的场景题目。
    • 专业级:最高等级,考察深层次的算法以及优化能力,与薪资直接挂钩。

刷题策略与说明:

2024年8月14日之后,华为OD机试的题库转为 E卷,由往年题库(D卷、A卷、B卷、C卷)和全新题目组成。刷题时可以参考以下策略:

  1. 关注历年真题:

    • 题库中的旧题占比较大,建议优先刷历年的A卷、B卷、C卷、D卷题目。
    • 对于每道题目,建议深度理解其解题思路、代码实现,以及相关算法的适用场景。
  2. 适应新题目:

    • E卷中包含全新题目,需要掌握全面的算法知识和一定的灵活应对能力。
    • 建议关注新的刷题平台或交流群,获取最新题目的解析和动态。
  3. 掌握常见算法:
    华为OD考试通常涉及以下算法和数据结构:

    • 排序算法(快速排序、归并排序等)
    • 动态规划(背包问题、最长公共子序列等)
    • 贪心算法
    • 栈、队列、链表的操作
    • 图论(最短路径、最小生成树等)
    • 滑动窗口、双指针算法
  4. 保持编程规范:

    • 注重代码的可读性和注释的清晰度。
    • 熟练使用常见编程语言,如C++、Java、Python等。

如何获取资源?

  1. 官方参考:

    • 华为招聘官网或相关的招聘平台会有一些参考信息。
    • 华为OD的相关公众号可能也会发布相关的刷题资料或学习资源。
  2. 加入刷题社区:

    • 找到可信的刷题交流群,与其他备考的小伙伴交流经验。
    • 关注知名的刷题网站,如LeetCode、牛客网等,这些平台上有许多华为OD的历年真题和解析。
  3. 寻找系统性的教程:

    • 学习一本经典的算法书籍,例如《算法导论》《剑指Offer》《编程之美》等。
    • 完成系统的学习课程,例如数据结构与算法的在线课程。

积极心态与持续努力:

刷题的过程可能会比较枯燥,但它能够显著提升编程能力和算法思维。无论是为了通过华为OD的招聘考试,还是为了未来的职业发展,这些积累都会成为重要的财富。

考试注意细节

  1. 本地编写代码

    • 在本地 IDE(如 VS Code、PyCharm 等)上编写、保存和调试代码,确保逻辑正确后再复制粘贴到考试页面。这样可以减少语法错误,提高代码准确性。
  2. 调整心态,保持冷静

    • 遇到提示不足或实现不确定的问题时,不必慌张,可以采用更简单或更有把握的方法替代,确保思路清晰。
  3. 输入输出完整性

    • 注意训练和考试时都需要编写完整的输入输出代码,尤其是和题目示例保持一致。完成代码后务必及时调试,确保功能符合要求。
  4. 快捷键使用

    • 删除行可用 Ctrl+D,复制、粘贴和撤销分别为 Ctrl+CCtrl+VCtrl+Z,这些可以正常使用。
    • 避免使用 Ctrl+S,以免触发浏览器的保存功能。
  5. 浏览器要求

    • 使用最新版的 Google Chrome 浏览器完成考试,确保摄像头开启并正常工作。考试期间不要切换到其他网站,以免影响考试成绩。
  6. 交卷相关

    • 答题前,务必仔细查看题目示例,避免遗漏要求。
    • 每完成一道题后,点击【保存并调试】按钮,多次保存和调试是允许的,系统会记录得分最高的一次结果。完成所有题目后,点击【提交本题型】按钮。
    • 确保在考试结束前提交试卷,避免因未保存或调试失误而丢分。
  7. 时间和分数安排

    • 总时间:150 分钟;总分:400 分。
    • 试卷结构:2 道一星难度题(每题 100 分),1 道二星难度题(200 分)。及格分为 150 分。合理分配时间,优先完成自己擅长的题目。
  8. 考试环境准备

    • 考试前请备好草稿纸和笔。考试中尽量避免离开座位,确保监控画面正常。
    • 如需上厕所,请提前规划好时间以减少中途离开监控的可能性。
  9. 技术问题处理

    • 如果考试中遇到断电、断网、死机等技术问题,可以关闭浏览器并重新打开试卷链接继续作答。
    • 出现其他问题,请第一时间联系 HR 或监考人员进行反馈。

祝你考试顺利,取得理想成绩!


http://www.kler.cn/a/510415.html

相关文章:

  • 【多线程】线程池
  • 蓝桥杯备考:堆和priority queue(优先级队列)
  • 考研计算机组成原理——零基础学习的笔记
  • C语言编程笔记:文件处理的艺术
  • cuda + cudnn安装
  • 楚慧杯Web
  • el-date-picker根据开始时间或结束时间禁用前后时间
  • C# 数据结构全面解析
  • 自动驾驶汽车目前面临的最大技术挑战是什么?
  • linux网络编程11——线程池
  • 【MySQL】事务(二)
  • 二叉树OJ题:挑战与突破
  • springboot自动配置原理(高低版本比较)spring.factories文件的作用
  • RISC-V精简指令集
  • 雷电9最新版安装Magisk+LSPosd(新手速通)
  • 基于SSM的家庭记账本小程序设计与实现(LW+源码+讲解)
  • Git实用指南:忽略文件、命令别名、版本控制、撤销修改与标签管理
  • 国产编辑器EverEdit - 文字对齐
  • Golang学习笔记_27——单例模式
  • S4 HANA凭证更改记录
  • Xilinx FPGA :开发使用及 Tips 总结
  • K8S-Pod资源清单的编写,资源的增删改查,镜像的下载策略
  • 基于无线传感器网络的森林防火设备远程监控系统(论文+源码)
  • 根据进程id查看服务使用的垃圾收集器
  • 论文阅读:CosAE Learnable Fourier Series for Image Restoration
  • 大数据面试——引入