我觉得就应该像力扣那样搞关键函数模式,至少前端岗可以这么搞 上 ACM 感觉除了 cpp 和 py 其他处理输入输出要麻烦死,遂在这里记录 js 的处理模板
一、基础模板 我们先来看一个基础模板
1 2 3 4 5 6 7 8 const rl = require ("readline" ).createInterface ({ input : process.stdin });var iter = rl[Symbol .asyncIterator ]();const readline = async ( ) => (await iter.next ()).value ;void (async function ( ) { console .log ("Hello Nowcoder!" ); })();
我们接下来逐行解析下每行代码的作用
1. 引入 readline 模块并创建接口 1 const rl = require ("readline" ).createInterface ({ input : process.stdin });
require("readline"):引入 Node.js 内置的readline模块,这个模块用于从命令行(标准输入)读取一行一行的输入。
createInterface({ input: process.stdin }):创建一个输入接口,指定输入源为process.stdin(标准输入,也就是用户在控制台输入的内容)。
变量rl就是这个输入接口的实例,后续通过它来控制输入的读取。
2. 创建异步迭代器 1 var iter = rl[Symbol .asyncIterator ]();
Symbol.asyncIterator是 Javascript 的一个内置符号,用于定义对象的异步迭代器
这里通过rl[Symbol.asyncIterator]()获取 rl 接口的异步迭代器,赋值给iter。
异步迭代器的作用是:可以通过next()方法异步地获取下一行输入 (因为输入是用户手动输入的,属于异步操作)。
3. 定义读取一行输入的函数 1 const readline = async ( ) => (await iter.next ()).value ;
这是一个异步函数(async标记),作用是读取一行输入。
调用iter.next()会返回一个 Promise,await会等待这个 Promise 完成,获取下一行输入的结果。
结果的value属性就是读取到的一行字符串(如果没有更多输入,value会是undefined)。
简单说:调用readline()就可以得到一行输入的内容(字符串类型)
4. 立即执行的异步函数(核心逻辑区) 1 2 3 4 void (async function ( ) { })();
这是整个代码的执行入口 ,也就是你需要编写核心逻辑的地方,我们拆解一下:
void async function (){...}():这是一个立即执行的异步函数表达式 (IIFE)。
async标记:允许函数内部使用 await 关键字(因为读取输入输出是异步操作)。
void:避免函数执行后返回值可能导致的语法问题,单纯让函数执行。
最后的():表示定义后立即执行这个函数。
核心代码写在哪里? 答案是:写在void async function () { ... }这个函数内部(也就是注释// Write your code here的位置)。根据题目的输入格式不同,你需要修改这个区域的代码。具体常见的输入格式见我第二部分详细讲解。
总结 这个模板的作用是标准化输入读取流程:
准备好读取输入的工具(rl接口,iter迭代器,readline函数)。
在立即执行的异步函数中,通过await readline()获取输入。
在函数内部编写你的核心逻辑(处理输入、计算、输出结果)。
二、常见出题形式 1.单组 A+B 描述 给定两个整数a和b,请你求出a + b的值。
输入描述: 第一行有两个整数a和b
输出描述: 输入一个整数,代表a + b的值。
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 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 ]); console .log (a + b); } })();
核心逻辑解析 函数内部的while循环:
1 while (line = await readline ()) { ... }
作用:持续读取每一行输入 ,直到没有更多输入(readline()返回undefined,循环终止)。
line = await readline():先调用readline()读取每一行输入,赋值给line。
当没有输入时,readline()先返回undefined,循环条件为false,退出循环。
循环内部的代码
1 2 3 let tokens = line.split (" " ); let a = parseInt (tokens[0 ]); let b = parseInt (tokens[1 ]);
2.多组_A+B_EOF 形式 描述 给定若干组测试数据,读取至文件末尾为止,每组数据有两个整数 a 和 b,请你求出 a + b 的值。
输入描述 每行有两个整数 a 和 b,读取至文件末尾为止
输出描述 输出若干行,每行一个整数,代表 a + b 的值。
示例 1 2 3 4 5 6 7 8 输入:1 2 114 514 2024 727 输出:3 628 2751
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 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 ]); console .log (a + b); } })();
3.多组_A+B_T 组形式 描述 给定 t 组测试数据。每组数据有两个整数 a 和 b,请你求出 a + b 的值。
输入描述 第一行有一个整数 t,每行有两个整数 a 和 b
输出描述 输出 t 行,每行一个整数,代表 a + b 的值。
示例 1 2 3 4 5 6 7 8 9 输入:3 1 2 114 514 2024 727 输出:3 628 2751
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 const rl = require ("readline" ).createInterface ({ input : process.stdin });var iter = rl[Symbol .asyncIterator ]();const readline = async ( ) => (await iter.next ()).value ;void (async function ( ) { let T = parseInt (await readline ()); for (let i = 0 ; i < T; i++) { let line = await readline (); let tokens = line.split (" " ); let a = parseInt (tokens[0 ]); let b = parseInt (tokens[1 ]); console .log (a + b); } })();
4.多组A+B 零尾模式 描述 给定若干组测试数据,最后一组数据为 0 0,作为输入的结尾。每组数据有两个整数 a 和 b,请你求出 a + b 的值。
输入描述 每行有两个整数 a 和 b,最后一组数据为 0 0,作为输入的结尾。
输出描述 输出若干行,每行一个整数,代表 a + b 的值。
示例 1 2 3 4 5 6 7 8 9 输入:1 2 114 514 2024 727 0 0 输出:3 628 2751
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 ]); if (a === 0 && b === 0 ) { break ; } console .log (a + b); } })();
5.单组_一维数组 示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 const rl = require ("readline" ).createInterface ({ input : process.stdin });var iter = rl[Symbol .asyncIterator ]();const readline = async ( ) => (await iter.next ()).value ;void (async function ( ) { let n = parseInt (await readline ()); let line = await readline (); let nums = line .split (" " ) .filter ((x ) => x) .map (Number ); let sum = nums.reduce ((acc, curr ) => acc + curr, 0 ); console .log (sum); })();
6.多组_一维数组_T 组形式 示例 1 2 3 4 5 6 7 8 9 10 11 12 输入:3 3 1 4 7 1 1000 2 1 2 输出:12 1000 3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 const rl = require ("readline" ).createInterface ({ input : process.stdin });var iter = rl[Symbol .asyncIterator ]();const readline = async ( ) => (await iter.next ()).value ;void (async function ( ) { const T = parseInt (await readline ()); for (let i = 0 ; i < T; i++) { const n = parseInt (await readline ()); const arrayLine = await readline (); const numbers = arrayLine .split (" " ) .filter ((x ) => x) .map (Number ); const sum = numbers.reduce ((acc, current ) => acc + current, 0 ); console .log (sum); } })();
7.单组_二维数组 示例 1 2 3 4 5 6 7 输入:3 4 1 2 3 4 5 6 7 8 9 10 11 12 输出:78
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 const rl = require ("readline" ).createInterface ({ input : process.stdin });var iter = rl[Symbol .asyncIterator ]();const readline = async ( ) => (await iter.next ()).value ;void (async function ( ) { let firstLine = await readline (); let [m, n] = firstLine.split (" " ).map (Number ); let totalSum = 0 ; for (let i = 0 ; i < m; i++) { let row = await readline (); let nums = row .split (" " ) .filter ((x ) => x) .map (Number ); let rowSum = nums.reduce ((acc, curr ) => acc + curr, 0 ); totalSum += rowSum; } console .log (totalSum); })();
8.多组_二维数组_T 组形式 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 输入:3 3 4 1 2 3 4 5 6 7 8 9 10 11 12 1 1 2024 3 2 1 1 4 5 1 4 输出:78 2024 16
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 const rl = require ("readline" ).createInterface ({ input : process.stdin });var iter = rl[Symbol .asyncIterator ]();const readline = async ( ) => (await iter.next ()).value ;void (async function ( ) { const T = parseInt (await readline ()); for (let t = 0 ; t < T; t++) { const [m, n] = (await readline ()) .split (" " ) .filter ((x ) => x) .map (Number ); let totalSum = 0 ; for (let i = 0 ; i < m; i++) { const row = (await readline ()) .split (" " ) .filter ((x ) => x) .map (Number ); const rowSum = row.reduce ((acc, curr ) => acc + curr, 0 ); totalSum += rowSum; } console .log (totalSum); } })();
9.单组_字符串 描述 给定一个长度为n的字符串s,请你将其倒置,然后输出。
输入描述 第一行有一个整数n,第二行有一个字符串s,仅包含小写英文字符。
输出描述 输出一个字符串,代表倒置后的字符串s。
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 const rl = require ("readline" ).createInterface ({ input : process.stdin });var iter = rl[Symbol .asyncIterator ]();const readline = async ( ) => (await iter.next ()).value ;void (async function ( ) { const n = parseInt (await readline ()); const str = await readline (); const reversedStr = str.split ("" ).reverse ().join ("" ); console .log (reversedStr); })();
10.多组_字符串_T 组形式 描述 给定t组询问,每次只给出一个长度为n的字符串s,请你将其倒置,然后输出。
输入描述 第一行有一个整数t,随后t组数据。每组的第一行有一个整数n,每组的第二行有一个字符串s,仅包含小写英文字符。
输出描述 输出t行,每行一个字符串,代表倒置后的字符串s。
示例 1 2 3 4 5 6 7 8 9 10 11 12 输入:3 5 abcde8 redocwon9 tfarcenim 输出: edcba nowcoder minecraft
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 const rl = require ("readline" ).createInterface ({ input : process.stdin });var iter = rl[Symbol .asyncIterator ]();const readline = async ( ) => (await iter.next ()).value ;void (async function ( ) { const T = parseInt (await readline ()); for (let t = 0 ; t < T; t++) { const n = parseInt (await readline ()); const str = await readline (); const reversedStr = str.split ("" ).reverse ().join ("" ); console .log (reversedStr); } })();
11.单组_二维字符数组 输入描述 第一行有两个整数n和m,随后n行,每行有m个字符,仅包含小写英文字符。
输出描述 输出一个二维字符数组。
示例 1 2 3 4 5 6 7 8 9 输入:3 4 abcd efgh ijkl 输出: lkji hgfe dcba
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 const rl = require ("readline" ).createInterface ({ input : process.stdin });var iter = rl[Symbol .asyncIterator ]();const readline = async ( ) => (await iter.next ()).value ;void (async function ( ) { const [m, n] = (await readline ()) .split (" " ) .filter ((x ) => x) .map (Number ); const rows = []; for (let i = 0 ; i < m; i++) { rows.push (await readline ()); } const reversedRows = rows .map ((row ) => row.split ("" ).reverse ().join ("" )) .reverse (); reversedRows.forEach ((row ) => console .log (row)); })();
12.多组_带空格的字符串_T 组形式 描述 给定t组询问,每次给出一个长度为n的带空格的字符串s,请你去掉空格之后,将其倒置,然后输出。
输入描述 第一行有一个整数t,随后有t组数据。每组的第一行有一个整数n,每组的第二行有一个字符串s,仅包含小写英文字符和空格,保证字符串首尾都不是空格。
输出描述 输出 t 行,每行一个字符串,代表倒置后的字符串s。
示例 1 2 3 4 5 6 7 8 9 10 11 12 输入:3 9 one space11 two spaces14 three spaces 输出: ecapseno secapsowt secapseerht
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 const rl = require ("readline" ).createInterface ({ input : process.stdin });var iter = rl[Symbol .asyncIterator ]();const readline = async ( ) => (await iter.next ()).value ;void (async function ( ) { const T = parseInt (await readline ()); for (let t = 0 ; t < T; t++) { const n = parseInt (await readline ()); const str = await readline (); const processed = str .split ("" ) .reverse () .join ("" ) .replace (/\s+/g , "" ); console .log (processed); } })();
13.单组_保留小数位数 描述 给定一个小数 n ,请你保留 3 位小数后输出。
如果原来的小数位数少于 3 ,需要补充 0 。
如果原来的小数位数多于 3 ,需要四舍五入到 3 位。
输出描述 输出一个小数,保留 3 位。
示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 输入:1.23 输出:1.230 输入:114.514 输出:114.514 输入:123 输出:123.000
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 const rl = require ("readline" ).createInterface ({ input : process.stdin });var iter = rl[Symbol .asyncIterator ]();const readline = async ( ) => (await iter.next ()).value ;void (async function ( ) { const numStr = await readline (); const num = parseFloat (numStr); const result = num.toFixed (3 ); console .log (result); })();
14.单组_补充前导零 描述 给定一个正整数 n ,请你保留 9 个数位,然后输出。
如果数位少于 9 个,那么需要补充前导零。
输出描述 输出一个小数,保留 3 位。
示例 1 2 3 4 5 6 7 8 9 输入:123 输出:000000123 输入:123456789 输出:123456789
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 const rl = require ("readline" ).createInterface ({ input : process.stdin });var iter = rl[Symbol .asyncIterator ]();const readline = async ( ) => (await iter.next ()).value ;void (async function ( ) { const numStr = await readline (); const result = numStr.padStart (9 , "0" ); console .log (result); })();
常用方法
再配合while和for语句差不多可以应对各种题型了