01华为机试_元宝版
准备华为前端机试时,熟练掌握一些核心代码模板能帮你节省大量时间。下面这个表格汇总了最关键的几类模板,之后我会详细解释它们的用法和要点。
| 模板类别 | 核心要点/常见写法 | 典型应用场景 |
|---|---|---|
| 输入输出处理 | 1. 基于事件的readline接口 2. 使用异步迭代器的现代写法 | 所有题目的基础,用于读取输入数据 |
| 字符串处理 | 正则表达式、split、reverse、join等 | HJ31(单词倒排)、HJ12(字符串反转)等 |
| 数组与数据结构 | Map/Set、sort排序、栈与队列 | 去重、统计、排序、模拟操作等 |
| 数学与算法 | 进制转换、质数判断、斐波那契数列 | HJ5(进制转换)、HJ6(质数因子)等 |
💻 输入输出处理模板
这是考试的基础,必须熟练掌握。华为机试采用ACM模式,需要自己处理输入输出。以下是两种常用写法,第二种(异步迭代器)更为现代和清晰,推荐重点掌握。
// 方法1:基于事件的readline接口 (适合连续输入)
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
let lines = [];
rl.on('line', function(line) {
lines.push(line.trim()); // 收集每一行输入
}).on('close', function() {
// 所有输入读取完毕后,在此处处理逻辑
main(lines);
});
// 方法2:使用异步迭代器的现代写法 (适合逐行处理)
const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
void (async function () {
while((line = await readline())) { // 逐行读取
let tokens = line.split(' ');
let a = parseInt(tokens[0]);
let b = parseInt(tokens[1]);
// 处理当前行数据
}
})()关键:根据题目描述判断输入格式(如多组数据通常用while((line = await readline()))循环),并在牛客网华为机试平台练习。
🔤 字符串处理技巧
字符串题常涉及查找、分割、翻转等操作。
// 常用字符串操作
// 1. 分割与翻转
let reversedStr = str.split('').reverse().join(''); // 字符串反转
let reversedSentence = str.split(' ').reverse().join(' '); // 句子逆序(单词为单位)
// 2. 正则表达式提取(HJ31 单词倒排的核心)
let words = line.match(/[A-Za-z]+/g); // 提取所有连续字母作为单词
// 或使用split分割非字母字符
let words = line.split(/[^a-zA-Z]+/).filter(word => word !== ''); // 分割并过滤空串
// 3. 字符统计
let charMap = new Map();
for(let char of str) {
charMap.set(char, (charMap.get(char) || 0) + 1);
}🔢 数组与数据结构操作
数组操作常用于排序、去重、统计等。
// 1. 数组排序
// 简单排序
arr.sort((a, b) => a - b); // 数字升序
// 多条件排序:先按长度,再按字典序
arr.sort((a, b) => a.length - b.length || a.localeCompare(b));
// 2. 去重
let uniqueArr = [...new Set(arr)]; // 利用Set去重
// 或使用对象属性去重(适用于复杂情况)
let obj = {};
arr.forEach(item => obj[item] = true);
let uniqueArr = Object.keys(obj);
// 3. 使用Map进行键值对统计(HJ8 合并表记录)
let map = new Map();
// ... 假设有输入数据
map.set(key, (map.get(key) || 0) + value); // 合并相同key的值🧮 数学与简单算法
// 1. 进制转换(HJ5)
console.log(parseInt(str, 16)); // 十六进制转十进制
// 十进制转其他进制
let binary = num.toString(2); // 转二进制
// 2. 质数因子(HJ6)
function primeFactors(n) {
let factors = [];
for(let i = 2; i * i <= n; i++) {
while(n % i === 0) {
factors.push(i);
n /= i;
}
}
if(n > 1) factors.push(n);
return factors.join(' ');
}💡 实战建议
理解而非死记:理解每个模板的应用场景和原理,考试时才能灵活调整。
牛客网练习:在牛客网华为机试平台用ACM模式反复练习,熟悉输入输出处理和调试。
注意边界和效率:注意输入数据的边界条件(如空串、极大/小值),在循环中避免不必要的操作。
这些模板覆盖了华为机试的大部分基础题型。熟练之后,你就能更专注于题目本身的逻辑。
希望这些模板能帮到你。如果你在具体某类题目上遇到困难,我可以提供更针对性的解答。
高频知识点题目与JS解答
📊 高频考点统计
根据华为历年机试分析,高频考点主要集中在以下领域:
| 考点类别 | 出现频率 | 典型题目 |
|---|---|---|
| 字符串处理 | 35% | HJ31、HJ12、HJ13、HJ20 |
| 数组/排序 | 25% | HJ8、HJ3、HJ101 |
| 哈希/计数 | 20% | HJ2、HJ23、HJ9 |
| 动态规划/递归 | 15% | HJ91、HJ24 |
| 数学计算 | 5% | HJ6、HJ7 |
🎯 高频题目精选与JS解答
1. 字符串处理类
HJ31 单词倒排
题目描述:对字符串中的所有单词进行倒排,构成单词的字符只有字母,非字母字符视为单词间的分隔符。
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.on('line', function(line) {
// 使用正则匹配所有单词
const words = line.match(/[a-zA-Z]+/g);
if (!words) {
console.log('');
return;
}
// 反转并输出
console.log(words.reverse().join(' '));
});HJ12 字符串反转
题目描述:接受一个只包含小写字母的字符串,然后输出该字符串反转后的字符串。
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.on('line', function(line) {
console.log(line.split('').reverse().join(''));
});HJ13 句子逆序
题目描述:将一个英文语句以单词为单位逆序排放。
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.on('line', function(line) {
const words = line.trim().split(' ');
console.log(words.reverse().join(' '));
});HJ20 密码验证合格程序
题目描述:密码要求包括长度、包含字符种类、不能有重复长度大于2的子串重复。
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.on('line', function(line) {
const password = line.trim();
// 1. 长度检查
if (password.length <= 8) {
console.log('NG');
return;
}
// 2. 包含字符种类检查
const hasUpper = /[A-Z]/.test(password);
const hasLower = /[a-z]/.test(password);
const hasDigit = /\d/.test(password);
const hasOther = /[^A-Za-z0-9]/.test(password);
const types = [hasUpper, hasLower, hasDigit, hasOther].filter(Boolean).length;
if (types < 3) {
console.log('NG');
return;
}
// 3. 子串重复检查
for (let i = 0; i < password.length - 3; i++) {
const subStr = password.substring(i, i + 3);
if (password.indexOf(subStr, i + 1) !== -1) {
console.log('NG');
return;
}
}
console.log('OK');
});2. 数组/排序类
HJ3 明明的随机数
题目描述:明明生成了N个1到500之间的随机整数。请你删去其中重复的数字,然后再把这些数字从小到大排序,按照排好的顺序输出。
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
let n = 0;
let nums = [];
let count = 0;
rl.on('line', function(line) {
if (n === 0) {
n = parseInt(line);
} else {
nums.push(parseInt(line));
count++;
if (count === n) {
// 去重并排序
const uniqueSorted = [...new Set(nums)].sort((a, b) => a - b);
uniqueSorted.forEach(num => console.log(num));
// 重置变量
n = 0;
nums = [];
count = 0;
}
}
});HJ8 合并表记录
题目描述:数据表记录包含表索引和数值,请合并相同索引的值,并按照索引值升序输出。
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
let n = 0;
let map = new Map();
let count = 0;
rl.on('line', function(line) {
if (n === 0) {
n = parseInt(line);
} else {
const [key, value] = line.split(' ').map(Number);
map.set(key, (map.get(key) || 0) + value);
count++;
if (count === n) {
// 按key升序排序
const sortedKeys = [...map.keys()].sort((a, b) => a - b);
sortedKeys.forEach(key => {
console.log(key, map.get(key));
});
}
}
});HJ101 输入整型数组和排序标识
题目描述:按照升序或降序对数组进行排序。
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
let lines = [];
let n = 0;
let arr = [];
let flag = 0;
rl.on('line', function(line) {
lines.push(line.trim());
if (lines.length === 3) {
n = parseInt(lines[0]);
arr = lines[1].split(' ').map(Number);
flag = parseInt(lines[2]);
if (flag === 0) {
// 升序
arr.sort((a, b) => a - b);
} else {
// 降序
arr.sort((a, b) => b - a);
}
console.log(arr.join(' '));
}
});3. 哈希/计数类
HJ2 计算某字符出现次数
题目描述:写出一个程序,接受一个由字母、数字和空格组成的字符串,和一个字符,然后输出输入字符串中该字符的出现次数(不区分大小写)。
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
let lines = [];
let str = '';
let targetChar = '';
rl.on('line', function(line) {
lines.push(line.trim());
if (lines.length === 2) {
str = lines[0].toLowerCase();
targetChar = lines[1].toLowerCase();
let count = 0;
for (let char of str) {
if (char === targetChar) {
count++;
}
}
console.log(count);
}
});HJ23 删除字符串中出现次数最少的字符
题目描述:删除字符串中出现次数最少的字符,如果有多个字符出现次数一样,则都删除。
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.on('line', function(line) {
const str = line.trim();
if (str.length === 0) {
console.log('');
return;
}
// 统计每个字符出现的次数
const freqMap = new Map();
for (let char of str) {
freqMap.set(char, (freqMap.get(char) || 0) + 1);
}
// 找到最小出现次数
const minFreq = Math.min(...freqMap.values());
// 构建结果字符串,跳过出现次数最小的字符
let result = '';
for (let char of str) {
if (freqMap.get(char) !== minFreq) {
result += char;
}
}
console.log(result);
});HJ9 提取不重复的整数
题目描述:输入一个int型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.on('line', function(line) {
const numStr = line.trim();
const seen = new Set();
let result = '';
// 从右向左遍历
for (let i = numStr.length - 1; i >= 0; i--) {
const digit = numStr[i];
if (!seen.has(digit)) {
result += digit;
seen.add(digit);
}
}
// 去掉前导零
result = result.replace(/^0+/, '') || '0';
console.log(result);
});4. 动态规划/递归类
HJ91 走方格的方案数
题目描述:请计算n*m的棋盘格子,从左上角走到右下角,每次只能向右或向下走,共有多少种走法。
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.on('line', function(line) {
const [n, m] = line.split(' ').map(Number);
// 使用动态规划
const dp = new Array(m + 1).fill(0).map(() => new Array(n + 1).fill(0));
// 初始化第一行和第一列
for (let i = 0; i <= n; i++) dp[0][i] = 1;
for (let j = 0; j <= m; j++) dp[j][0] = 1;
// 填充DP表
for (let i = 1; i <= m; i++) {
for (let j = 1; j <= n; j++) {
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
console.log(dp[m][n]);
});
// 更简洁的数学解法(组合数)
// 从左上到右下需要走n+m步,其中n步向右,m步向下
// 方案数为C(n+m, n) = C(n+m, m)
function solution2() {
rl.on('line', function(line) {
const [n, m] = line.split(' ').map(Number);
// 计算组合数C(n+m, n)
const total = n + m;
const k = Math.min(n, m);
let result = 1;
for (let i = 1; i <= k; i++) {
result = result * (total - k + i) / i;
}
console.log(result);
});
}5. 数学计算类
HJ6 质数因子
题目描述:输入一个正整数,按照从小到大的顺序输出它的所有质因子。
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.on('line', function(line) {
let num = parseInt(line);
const result = [];
// 从2开始试除
for (let i = 2; i * i <= num; i++) {
while (num % i === 0) {
result.push(i);
num /= i;
}
}
// 如果最后剩下一个大于1的数,它也是质因子
if (num > 1) {
result.push(num);
}
console.log(result.join(' '));
});HJ7 取近似值
题目描述:写出一个程序,接受一个正浮点数值,输出该数值的近似整数值。如果小数点后数值大于等于5,向上取整;小于5,则向下取整。
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.on('line', function(line) {
const num = parseFloat(line);
console.log(Math.round(num));
});🎯 备考建议
先易后难:从字符串处理(HJ12, HJ13, HJ31)开始,然后是数组处理(HJ3, HJ8),最后挑战动态规划(HJ91)。
重点掌握:
字符串的`split`, `join`, `reverse`, `match`, `replace`方法
数组的`sort`, `map`, `filter`, `reduce`方法
Set/Map数据结构
基本的数学运算和质数判断
练习顺序:
基础 → HJ2, HJ5, HJ6, HJ7, HJ9, HJ12, HJ13
进阶 → HJ3, HJ8, HJ20, HJ23, HJ31, HJ101
挑战 → HJ24, HJ91时间分配:建议在牛客网按顺序刷题,每题控制在20-30分钟内完成。
这些题目覆盖了华为机试最常见的前端考点。建议你每道题都自己先尝试,再看答案。重点理解解题思路而非单纯记忆代码。