Skip to content

01华为机试_元宝版

准备华为前端机试时,熟练掌握一些核心代码模板能帮你节省大量时间。下面这个表格汇总了最关键的几类模板,之后我会详细解释它们的用法和要点。

模板类别核心要点/常见写法典型应用场景
输入输出处理1. 基于事件的readline接口 2. 使用异步迭代器的现代写法所有题目的基础,用于读取输入数据
字符串处理正则表达式、splitreversejoinHJ31(单词倒排)、HJ12(字符串反转)等
数组与数据结构Map/Setsort排序、栈与队列去重、统计、排序、模拟操作等
数学与算法进制转换、质数判断、斐波那契数列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分钟内完成。

这些题目覆盖了华为机试最常见的前端考点。建议你每道题都自己先尝试,再看答案。重点理解解题思路而非单纯记忆代码。

最近更新