对报文进行重传和重排序是常用的可靠性机制,重传缓中区内有一定数量的子报文,每个子报文在原始报文中的顺序已知,现在需要恢复出原始报文。
输入第一行为N,表示子报文的个数,0 <N ≤ 1000。
输入第二行为N个子报文,以空格分开,子报文格式为:
字符审报文内容+后缀顺序索引
字符串报文内容由[a-z,A-Z]组成,后缀为整型值,表示顺序。
顺序值唯一,不重复。
输出恢复出的原始报文,按照每个子报文的顺序的升序排序恢复出原始报文,顺序后缀需要从恢复出的报文中删除掉
输入
4
rolling3 stone4 like1 a2
输出
like a rolling stone
说明
4个子报文的内容分别为 “rolling”,“stone”,“like”,“a”,顺序值分别为3,4,1,2,按照顺序值升序并删除顺序后缀,得到恢复的原始报文:“like a rolling stone”
输入
8
gifts6 and7 Exchanging1 all2 precious5 things8 kinds3 of4
输出
Exchanging all kinds of precious gifts and things
考察字符串操作。
以下是 JavaScript 代码的详细中文注释和讲解:
/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline"); // 引入 readline 模块,用于读取控制台输入
// 创建 readline 接口
const rl = readline.createInterface({
input: process.stdin, // 输入流为标准输入
output: process.stdout, // 输出流为标准输出
});
const lines = []; // 用于存储输入的行数据
// 监听输入事件
rl.on("line", (line) => {
lines.push(line); // 将输入的行数据存入 lines 数组
// 当输入的行数达到 2 行时,开始处理数据
if (lines.length === 2) {
const n = parseInt(lines[0]); // 解析第一行输入为整数 n
const arr = lines[1].split(" "); // 将第二行输入按空格分割为数组 arr
// 调用 getResult 方法处理数据并输出结果
console.log(getResult(n, arr));
// 清空 lines 数组,以便处理下一组输入
lines.length = 0;
}
});
// 处理输入数据的函数
function getResult(n, arr) {
const ans = []; // 用于存储解析后的结果
// 定义正则表达式,用于匹配字符串中的字母部分和数字部分
const reg = /([a-zA-Z]+)(\d+)/;
// 遍历输入数组中的每个字符串
for (let s of arr) {
// 使用正则表达式匹配字符串
const res = reg.exec(s);
// 如果匹配结果不完整,则跳过当前字符串
if (res.length < 3) continue;
// 提取匹配结果中的字母部分和数字部分
const content = res[1]; // 字母部分
const i = parseInt(res[2]) - 1; // 数字部分,并转换为索引(从 0 开始)
// 将索引和字母部分存入 ans 数组
ans.push([i, content]);
}
// 对 ans 数组按索引排序,并提取字母部分拼接成字符串返回
return ans
.sort((a, b) => a[0] - b[0]) // 按索引升序排序
.map((x) => x[1]) // 提取字母部分
.join(" "); // 将字母部分拼接成字符串,用空格分隔
}
const readline = require("readline"); // 引入 readline 模块,用于读取控制台输入
// 创建 readline 接口
const rl = readline.createInterface({
input: process.stdin, // 输入流为标准输入
output: process.stdout, // 输出流为标准输出
});
const lines = []; // 用于存储输入的行数据
// 监听输入事件
rl.on("line", (line) => {
lines.push(line); // 将输入的行数据存入 lines 数组
// 当输入的行数达到 2 行时,开始处理数据
if (lines.length === 2) {
const n = parseInt(lines[0]); // 解析第一行输入为整数 n
const arr = lines[1].split(" "); // 将第二行输入按空格分割为数组 arr
// 调用 getResult 方法处理数据并输出结果
console.log(getResult(n, arr));
// 清空 lines 数组,以便处理下一组输入
lines.length = 0;
}
});
readline
模块读取控制台输入。n
和字符串数组 arr
。rl.on("line", (line) => { ... })
监听输入事件,每次输入一行时触发。lines.push(line)
将输入的行数据存入 lines
数组。lines
数组的长度为 2 时,表示输入完成,开始处理数据。lines[0]
是第一行输入,解析为整数 n
。lines[1]
是第二行输入,按空格分割为数组 arr
。function getResult(n, arr) {
const ans = []; // 用于存储解析后的结果
// 定义正则表达式,用于匹配字符串中的字母部分和数字部分
const reg = /([a-zA-Z]+)(\d+)/;
// 遍历输入数组中的每个字符串
for (let s of arr) {
// 使用正则表达式匹配字符串
const res = reg.exec(s);
// 如果匹配结果不完整,则跳过当前字符串
if (res.length < 3) continue;
// 提取匹配结果中的字母部分和数字部分
const content = res[1]; // 字母部分
const i = parseInt(res[2]) - 1; // 数字部分,并转换为索引(从 0 开始)
// 将索引和字母部分存入 ans 数组
ans.push([i, content]);
}
// 对 ans 数组按索引排序,并提取字母部分拼接成字符串返回
return ans
.sort((a, b) => a[0] - b[0]) // 按索引升序排序
.map((x) => x[1]) // 提取字母部分
.join(" "); // 将字母部分拼接成字符串,用空格分隔
}
reg = /([a-zA-Z]+)(\d+)/
定义正则表达式,用于匹配字符串中的字母部分和数字部分。reg.exec(s)
使用正则表达式匹配字符串,返回匹配结果。res[1]
是字母部分,res[2]
是数字部分。ans
数组。ans
数组按索引升序排序,提取字母部分并拼接成字符串。输入:
3
a1 b2 c3
输出:
a b c
解释:
["a1", "b2", "c3"]
。a1
→ 索引 0
,字母部分 a
。b2
→ 索引 1
,字母部分 b
。c3
→ 索引 2
,字母部分 c
。["a", "b", "c"]
,拼接为 "a b c"
。输入:
4
z3 x1 y2 w4
输出:
x y z w
解释:
["z3", "x1", "y2", "w4"]
。z3
→ 索引 2
,字母部分 z
。x1
→ 索引 0
,字母部分 x
。y2
→ 索引 1
,字母部分 y
。w4
→ 索引 3
,字母部分 w
。["x", "y", "z", "w"]
,拼接为 "x y z w"
。功能:
优点:
适用场景:
如果您有其他问题,欢迎随时提问!
以下是Java代码的详细注释和讲解:
import java.util.ArrayList;
import java.util.Scanner;
import java.util.StringJoiner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
// 定义一个内部类 Word,用于存储单词的内容和编号
static class Word {
int id; // 单词的编号
String content; // 单词的内容
// 构造函数,用于初始化 Word 对象
public Word(int id, String content) {
this.id = id;
this.content = content;
}
}
public static void main(String[] args) {
// 创建一个 Scanner 对象,用于从标准输入读取数据
Scanner sc = new Scanner(System.in);
// 读取输入的整数 n,表示单词的数量
int n = Integer.parseInt(sc.nextLine());
// 读取一行输入,并将其按空格分割成字符串数组 arr
String[] arr = sc.nextLine().split(" ");
// 调用 getResult 方法处理输入,并输出结果
System.out.println(getResult(n, arr));
}
// 处理输入并返回结果的函数
public static String getResult(int n, String[] arr) {
// 创建一个 ArrayList 用于存储 Word 对象
ArrayList<Word> ans = new ArrayList<>();
// 定义一个正则表达式,用于匹配单词内容和编号
// 正则表达式分为两部分:
// ([a-zA-Z]+) 匹配一个或多个字母(单词内容)
// (\\d+) 匹配一个或多个数字(单词编号)
Pattern pattern = Pattern.compile("([a-zA-Z]+)(\\d+)");
// 遍历输入的字符串数组 arr
for (String s : arr) {
// 使用正则表达式匹配当前字符串
Matcher matcher = pattern.matcher(s);
if (matcher.find()) {
// 如果匹配成功,提取单词内容和编号
String content = matcher.group(1); // 提取单词内容
int i = Integer.parseInt(matcher.group(2)) - 1; // 提取编号并减1(转换为0-based索引)
// 将提取的内容和编号封装为 Word 对象,并添加到 ans 列表中
ans.add(new Word(i, content));
}
}
// 对 ans 列表中的 Word 对象按 id 进行升序排序
ans.sort((a, b) -> a.id - b.id);
// 使用 StringJoiner 将排序后的单词内容拼接成一个字符串,单词之间用空格分隔
StringJoiner sj = new StringJoiner(" ");
for (Word an : ans) {
sj.add(an.content);
}
// 返回拼接后的字符串
return sj.toString();
}
}
输入部分:
Scanner
对象从标准输入读取两个部分:
n
,表示单词的数量。arr
,每个字符串包含一个单词内容和编号。正则表达式匹配:
([a-zA-Z]+)(\\d+)
匹配每个字符串:
([a-zA-Z]+)
:匹配一个或多个字母,表示单词内容。(\\d+)
:匹配一个或多个数字,表示单词编号。Matcher
对象提取单词内容和编号,并将其封装为Word
对象。排序:
Word
对象按id
进行升序排序,确保单词按编号顺序排列。拼接结果:
StringJoiner
将排序后的单词内容拼接成一个字符串,单词之间用空格分隔。输出结果:
假设输入如下:
5
apple3 banana1 cherry2 date5 elderberry4
程序会提取每个单词的内容和编号,并按编号排序后输出:
banana cherry apple elderberry date
该代码的主要功能是从输入中提取单词内容和编号,按编号排序后输出单词内容。通过正则表达式匹配和排序算法,代码实现了对输入数据的处理和格式化输出。
以下是 Python 代码的详细中文注释和讲解:
# 输入获取
import re # 导入正则表达式模块
n = int(input()) # 读取第一行输入,解析为整数 n
arr = input().split() # 读取第二行输入,按空格分割为数组 arr
# 算法入口
def getResult():
ans = [] # 用于存储解析后的结果
# 定义正则表达式,用于匹配字符串中的字母部分和数字部分
reg = re.compile(r"([a-zA-Z]+)(\d+)")
# 遍历输入数组中的每个字符串
for s in arr:
# 使用正则表达式匹配字符串
matcher = reg.search(s)
# 如果匹配失败,则跳过当前字符串
if matcher is None:
continue
# 提取匹配结果中的字母部分和数字部分
content = matcher.group(1) # 字母部分
i = int(matcher.group(2)) - 1 # 数字部分,并转换为索引(从 0 开始)
# 将索引和字母部分存入 ans 数组
ans.append([i, content])
# 对 ans 数组按索引排序
ans.sort(key=lambda x: x[0])
# 提取字母部分并拼接成字符串返回
return " ".join(map(lambda x: x[1], ans))
# 算法调用
print(getResult())
import re # 导入正则表达式模块
n = int(input()) # 读取第一行输入,解析为整数 n
arr = input().split() # 读取第二行输入,按空格分割为数组 arr
n
。arr
。input()
读取一行输入。split()
按空格分割字符串为数组。def getResult():
ans = [] # 用于存储解析后的结果
# 定义正则表达式,用于匹配字符串中的字母部分和数字部分
reg = re.compile(r"([a-zA-Z]+)(\d+)")
# 遍历输入数组中的每个字符串
for s in arr:
# 使用正则表达式匹配字符串
matcher = reg.search(s)
# 如果匹配失败,则跳过当前字符串
if matcher is None:
continue
# 提取匹配结果中的字母部分和数字部分
content = matcher.group(1) # 字母部分
i = int(matcher.group(2)) - 1 # 数字部分,并转换为索引(从 0 开始)
# 将索引和字母部分存入 ans 数组
ans.append([i, content])
# 对 ans 数组按索引排序
ans.sort(key=lambda x: x[0])
# 提取字母部分并拼接成字符串返回
return " ".join(map(lambda x: x[1], ans))
reg = re.compile(r"([a-zA-Z]+)(\d+)")
定义正则表达式,用于匹配字符串中的字母部分和数字部分。reg.search(s)
使用正则表达式匹配字符串,返回匹配结果。matcher.group(1)
是字母部分,matcher.group(2)
是数字部分。ans
数组。ans
数组按索引升序排序。# 算法调用
print(getResult())
getResult
方法处理数据并输出结果。输入:
3
a1 b2 c3
输出:
a b c
解释:
["a1", "b2", "c3"]
。a1
→ 索引 0
,字母部分 a
。b2
→ 索引 1
,字母部分 b
。c3
→ 索引 2
,字母部分 c
。["a", "b", "c"]
,拼接为 "a b c"
。输入:
4
z3 x1 y2 w4
输出:
x y z w
解释:
["z3", "x1", "y2", "w4"]
。z3
→ 索引 2
,字母部分 z
。x1
→ 索引 0
,字母部分 x
。y2
→ 索引 1
,字母部分 y
。w4
→ 索引 3
,字母部分 w
。["x", "y", "z", "w"]
,拼接为 "x y z w"
。功能:
优点:
适用场景:
如果您有其他问题,欢迎随时提问!
以下是 C++ 和 C 代码的详细中文注释和讲解:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring> // 用于字符串操作
using namespace std;
// 定义 Word 结构体,存储单词内容和索引
struct Word {
int id; // 索引
string content; // 单词内容
};
// 比较函数,用于排序
bool cmp(const Word &a, const Word &b) {
return a.id < b.id; // 按索引升序排序
}
int main() {
int n;
cin >> n; // 读取输入的数字 n
cin.ignore(); // 忽略第一行结尾的换行符
vector<Word> words(n); // 定义存储 Word 结构体的动态数组
// 读取每个单词及其索引
for (int i = 0; i < n; i++) {
string s;
getline(cin, s); // 读取一行输入
// 解析字符串,提取字母部分和数字部分
size_t pos = s.find_last_not_of("01234567"); // 找到最后一个非数字字符的位置
words[i].content = s.substr(0, pos + 1); // 提取字母部分
words[i].id = stoi(s.substr(pos + 1)); // 提取数字部分并转换为整数
}
// 对 words 数组按索引排序
sort(words.begin(), words.end(), cmp);
// 拼接结果字符串
string res;
for (const auto &word : words) {
res += word.content + " "; // 将单词内容和空格拼接到结果字符串中
}
// 去掉最后一个多余的空格
if (!res.empty()) {
res.pop_back();
}
// 输出结果
cout << res << endl;
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 100 // 定义单词内容的最大长度
// 定义 Word 结构体,存储单词内容和索引
typedef struct {
int id; // 索引
char content[MAX_LEN]; // 单词内容
} Word;
// 比较函数,用于排序
int cmp(const void *a, const void *b) {
return ((Word *) a)->id - ((Word *) b)->id; // 按索引升序排序
}
int main() {
int n;
scanf("%d", &n); // 读取输入的数字 n
getchar(); // 忽略第一行结尾的换行符
Word *words = (Word *) calloc(n, sizeof(Word)); // 动态分配存储 Word 结构体的数组
// 读取每个单词及其索引
for (int i = 0; i < n; i++) {
scanf("%[^0-9]%d", words[i].content, &words[i].id); // 读取字母部分和数字部分
getchar(); // 忽略空格或换行符
}
// 对 words 数组按索引排序
qsort(words, n, sizeof(Word), cmp);
// 拼接结果字符串
char res[100000] = ""; // 定义结果字符串
for (int i = 0; i < n; i++) {
strcat(res, words[i].content); // 将单词内容拼接到结果字符串中
strcat(res, " "); // 拼接空格
}
// 去掉最后一个多余的空格
if (strlen(res) > 0) {
res[strlen(res) - 1] = '\0';
}
// 输出结果
puts(res);
// 释放动态分配的内存
free(words);
return 0;
}
C++:
int n;
cin >> n; // 读取输入的数字 n
cin.ignore(); // 忽略第一行结尾的换行符
C:
int n;
scanf("%d", &n); // 读取输入的数字 n
getchar(); // 忽略第一行结尾的换行符
功能:
n
。C++:
struct Word {
int id; // 索引
string content; // 单词内容
};
C:
typedef struct {
int id; // 索引
char content[MAX_LEN]; // 单词内容
} Word;
功能:
Word
结构体,用于存储单词内容和索引。C++:
for (int i = 0; i < n; i++) {
string s;
getline(cin, s); // 读取一行输入
// 解析字符串,提取字母部分和数字部分
size_t pos = s.find_last_not_of("01234567"); // 找到最后一个非数字字符的位置
words[i].content = s.substr(0, pos + 1); // 提取字母部分
words[i].id = stoi(s.substr(pos + 1)); // 提取数字部分并转换为整数
}
C:
for (int i = 0; i < n; i++) {
scanf("%[^0-9]%d", words[i].content, &words[i].id); // 读取字母部分和数字部分
getchar(); // 忽略空格或换行符
}
功能:
content
,数字部分存入 id
。C++:
sort(words.begin(), words.end(), cmp);
C:
qsort(words, n, sizeof(Word), cmp);
功能:
words
数组按索引升序排序。C++:
string res;
for (const auto &word : words) {
res += word.content + " "; // 将单词内容和空格拼接到结果字符串中
}
// 去掉最后一个多余的空格
if (!res.empty()) {
res.pop_back();
}
C:
char res[100000] = ""; // 定义结果字符串
for (int i = 0; i < n; i++) {
strcat(res, words[i].content); // 将单词内容拼接到结果字符串中
strcat(res, " "); // 拼接空格
}
// 去掉最后一个多余的空格
if (strlen(res) > 0) {
res[strlen(res) - 1] = '\0';
}
功能:
C++:
cout << res << endl;
C:
puts(res);
功能:
输入:
3
a1 b2 c3
输出:
a b c
解释:
["a1", "b2", "c3"]
。a1
→ 索引 1
,字母部分 a
。b2
→ 索引 2
,字母部分 b
。c3
→ 索引 3
,字母部分 c
。["a", "b", "c"]
,拼接为 "a b c"
。输入:
4
z3 x1 y2 w4
输出:
x y z w
解释:
["z3", "x1", "y2", "w4"]
。z3
→ 索引 3
,字母部分 z
。x1
→ 索引 1
,字母部分 x
。y2
→ 索引 2
,字母部分 y
。w4
→ 索引 4
,字母部分 w
。["x", "y", "z", "w"]
,拼接为 "x y z w"
。功能:
优点:
适用场景:
如果您有其他问题,欢迎随时提问!
华为OD(Outsourcing Developer,外包开发工程师)是华为针对软件开发工程师岗位的一种招聘形式,主要包括笔试、技术面试以及综合面试等环节。尤其在笔试部分,算法题的机试至关重要。
机试是进入技术面的第一关:
华为OD机试(常被称为机考)主要考察算法和编程能力。只有通过机试,才能进入后续的技术面试环节。
技术面试需要手撕代码:
技术一面和二面通常会涉及现场编写代码或算法题。面试官会注重考察候选人的思路清晰度、代码规范性以及解决问题的能力。因此提前刷题、多练习是通过面试的重要保障。
入职后的可信考试:
入职华为后,还需要通过“可信考试”。可信考试分为三个等级:
2024年8月14日之后,华为OD机试的题库转为 E卷,由往年题库(D卷、A卷、B卷、C卷)和全新题目组成。刷题时可以参考以下策略:
关注历年真题:
适应新题目:
掌握常见算法:
华为OD考试通常涉及以下算法和数据结构:
保持编程规范:
官方参考:
加入刷题社区:
寻找系统性的教程:
刷题的过程可能会比较枯燥,但它能够显著提升编程能力和算法思维。无论是为了通过华为OD的招聘考试,还是为了未来的职业发展,这些积累都会成为重要的财富。
本地编写代码
调整心态,保持冷静
输入输出完整性
快捷键使用
Ctrl+D
,复制、粘贴和撤销分别为 Ctrl+C
,Ctrl+V
,Ctrl+Z
,这些可以正常使用。Ctrl+S
,以免触发浏览器的保存功能。浏览器要求
交卷相关
时间和分数安排
考试环境准备
技术问题处理
祝你考试顺利,取得理想成绩!
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- huatuo8.com 版权所有 湘ICP备2023022238号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务