华为OD机试真题 新系统 2026-06-10 Python&JS 实现【设备重排SN】
目录
题目
通信设备SN一般是包含:字母、数字,用'-'(破折号)进行分组分割,例如:8F-3T-1G-2n是一个有效的SN地址。
现在要对已经存在的SN 按照新的规则进行重排:
输入1:一个有效的SN地址字符串(字符串可以为空,长度小于10000),表示要被重新排列的SN地址;输入2:给定的一个数字m,1<=m<=10,表示要每个分组恰好包含m个字符,用'-'进行分组分割;
重排规则:
1.如果字母与数字的总和不是m的倍数,则特例(即小于m个字符的分组)放在第一个。
2.将所有的小写字母转换为大写字母。
3.如果出现异常场景,返回空字符串。样例1
输入
8F-3T-1G-2n
4输出
8F3T-1G2N
说明字符串S被分成了两个部分,每部分4个字符;
注意,两个额外的破折号需要删掉。
样例2输入
2-2g-5-g
2输出
2-2G-5G
思路
简单题。字符串处理
1. 预处理
将输入的 SN 字符串中所有-删除,得到纯字符序列merged。2. 合法性校验
遍历merged每个字符,只允许字母(a-zA-Z)和数字(0-9),否则返回空字符串。3. 小写转大写
所有字母转为大写。4. 分组逻辑
- 设
n = len(merged),若n = 0直接返回空字符串。- 若
n % m != 0,则第一个分组的长度为n % m(余数放最前面),后续每组m个。- 若
n % m == 0,全部按m个一组。5. 结果组装
各组用-连接,返回最终字符串。6. 复杂度
时间O(n),空间O(n),n ≤ 10000。
Code
import sys
def solve(sn, m):
"""
SN 地址重排核心算法
:param sn: 原始 SN 字符串(可能包含破折号)
:param m: 每个分组的字符数
:return: 重排后的 SN 字符串,异常场景返回空字符串
"""
# ---- 参数合法性校验 ----
# m 必须为正整数(1 ≤ m ≤ 10),m <= 0 属于异常场景,直接返回空
if m <= 0:
return ""
# ---- 第 1 步:移除所有破折号,得到纯字母数字序列 ----
# 例如 "8F-3T-1G-2n" -> "8F3T1G2n"
merged = sn.replace('-', '')
# ---- 第 2 步:空字符串处理 ----
# 移除破折号后如果为空(原始字符串为空或只有破折号),返回空字符串
if not merged:
return ""
# ---- 第 3 步:字符合法性校验 ----
# SN 中只允许字母(a-z A-Z)和数字(0-9),出现其他字符视为异常场景
for ch in merged:
if not (ch.isdigit() or ch.isalpha()):
return ""
# ---- 第 4 步:小写字母转大写 ----
# 将所有小写字母统一转换为大写形式
merged = merged.upper()
n = len(merged)
# ---- 第 5 步:按规则分组 ----
# 规则 1:如果总长度 n 不是 m 的倍数,余数 r = n % m 的部分作为第一个分组
# (即"余数在前"),后续每组恰好 m 个字符
# 规则 2:每组之间用 '-' 连接
groups = []
pos = 0
# 先处理余数部分(如果存在)
r = n % m
if r != 0:
groups.append(merged[:r]) # 前 r 个字符为第一个分组
pos = r # 游标移动到 r 位置
# 后续每 m 个字符为一组,直到字符串末尾
while pos < n:
groups.append(merged[pos:pos + m])
pos += m
# 用 '-' 将所有分组连接成最终的 SN 字符串
return '-'.join(groups)
def main():
"""
主函数:从标准输入读取两行数据,调用 solve 函数处理后输出
异常场景:任何异常(I/O 错误、格式错误等)都输出空行
"""
try:
# 读取第一行:SN 字符串
# rstrip('\n\r') 去除末尾的换行符(兼容 Windows CRLF 和 Linux LF)
sn = sys.stdin.readline().rstrip('\n\r')
# 读取第二行:分组数 m
# 跳过可能的空行,找到第一个非空行作为 m
m = 0
while True:
line = sys.stdin.readline()
if not line: # 读到文件末尾仍未找到 m,退出循环
break
line = line.strip() # 去除首尾空白字符
if line: # 非空行,即为 m 的值
m = int(line)
break
# 调用核心求解函数并输出结果
print(solve(sn, m))
except Exception:
# 任何异常场景(如 int() 转换失败等),输出空行
print()
if __name__ == "__main__":
main()
JS
const readline = require('readline');
/**
* SN 地址重排核心算法
* @param {string} sn 原始 SN 字符串(可能包含破折号)
* @param {number} m 每个分组的字符数
* @returns {string} 重排后的 SN 字符串,异常场景返回空字符串
*/
function solve(sn, m) {
// ---- 参数合法性校验 ----
// m 必须为正整数(1 ≤ m ≤ 10),m <= 0 属于异常场景,直接返回空
if (m <= 0) return '';
// ---- 第 1 步:移除所有破折号,得到纯字母数字序列 ----
// 例如 "8F-3T-1G-2n" -> "8F3T1G2n"
let merged = sn.replace(/-/g, '');
// ---- 第 2 步:空字符串处理 ----
// 移除破折号后如果为空(原始字符串为空或只有破折号),返回空字符串
if (!merged) return '';
// ---- 第 3 步:字符合法性校验 ----
// SN 中只允许字母(a-z A-Z)和数字(0-9),出现其他字符视为异常场景
for (const ch of merged) {
if (!/[a-zA-Z0-9]/.test(ch)) return '';
}
// ---- 第 4 步:小写字母转大写 ----
merged = merged.toUpperCase();
const n = merged.length;
// ---- 第 5 步:按规则分组 ----
// 规则 1:如果总长度 n 不是 m 的倍数,余数 r = n % m 的部分作为第一个分组
// (即"余数在前"),后续每组恰好 m 个字符
// 规则 2:每组之间用 '-' 连接
const groups = [];
let pos = 0;
// 先处理余数部分(如果存在)
const r = n % m;
if (r !== 0) {
groups.push(merged.substring(0, r)); // 前 r 个字符为第一个分组
pos = r; // 游标移动到 r 位置
}
// 后续每 m 个字符为一组,直到字符串末尾
while (pos < n) {
groups.push(merged.substring(pos, pos + m));
pos += m;
}
// 用 '-' 将所有分组连接成最终的 SN 字符串
return groups.join('-');
}
// ---- 主程序:读取标准输入,处理并输出结果 ----
// 创建 readline 接口,逐行读取标准输入
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
let firstLine = true; // 是否正在读取第一行(SN 字符串)
let sn; // 存储第一行读取到的 SN 字符串
let processed = false; // 标记是否已正常处理完成,防止 close 事件重复输出
// 监听每一行输入
rl.on('line', (line) => {
try {
if (firstLine) {
// 第一行:读取 SN 字符串
sn = line;
firstLine = false;
} else {
// 第二行:读取分组数 m
// 去除首尾空白后取非空行
const trimmed = line.trim();
if (trimmed !== '') {
const m = parseInt(trimmed, 10); // 解析整数
console.log(solve(sn, m)); // 输出重排结果
processed = true; // 标记处理完成
rl.close(); // 关闭输入流
}
}
} catch (e) {
// 异常场景:任何运行时异常都输出空行
if (!processed) {
console.log('');
processed = true;
}
rl.close();
}
});
// 处理只有一行输入(缺少 m)的边界情况
rl.on('close', () => {
// 如果已经正常处理过(processed = true)则不再输出
if (!processed && !firstLine && sn !== undefined) {
console.log('');
}
});
【华为od机试真题Python+JS+Java+Go合集】【超值优惠】:Py/JS/Java/Go合集
【华为od机试真题Python】:Python真题题库
【华为od机试真题JavaScript】:JavaScript真题题库
【华为od机试真题Java&Go】:Java&Go真题题库
【华为od机试真题C++】:C++真题题库
【华为od机试真题C语言】:C语言真题题库
【华为od面试手撕代码题库】:面试手撕代码题库
【华为od机试面试交流群】【文章底部有二维码链接,可扫码加交流群】
华为OD机试:二本院校有机会吗?
有机会,但不大,大神除外!机考分数越高越好,所以需要提前刷题。机考通过后,如果没有收到面试邀请,也不要着急,非目标院校面试邀请发的时间比较晚。非目标院校今年有点难,机试至少要考到350分,所以需要疯狂刷题,华为OD机考是有题库的,最好在考前完所有题库题目。华为OD机试:跨专业可以参加华为OD可以,但是如果你的本科院校比较差,上岸概率不大。华为OD机试:华为OD简历被锁定机试通过,性格测试也通过,但是没人联系面试,发现简历被锁定。此时需要主动去联系HR。让他帮助你查询原因。
更多推荐




所有评论(0)