编辑代码

const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;

// 问题描述:统计两个数组的交集元素及其在第一个数组中出现的次数
// 输入格式:两行,每行为逗号分隔的数字序列
// 输出格式:按出现次数分组,每组格式为 "次数:数字1,数字2,..."(数字按升序排列)

void (async function () {
    // 读取两个输入数组并转换为数字数组
    const arr1 = (await readline()).split(",").map(Number);
    const arr2 = (await readline()).split(",").map(Number);

    // 创建Map记录第一个数组中每个数字出现的次数
    const map = new Map();
    for (let i = 0; i < arr1.length; i++) {
        map.set(arr1[i], (map.get(arr1[i]) || 0) + 1);
    }

    // 找出在两个数组中都出现的数字(去重)
    const res = [];
    for (let i = 0; i < arr2.length; i++) {
        if (!map.has(arr2[i])) continue;  // 如果数字不在第一个数组中,跳过
        else {
            if (!res.includes(arr2[i])) {  // 避免重复添加相同的数字
                res.push(arr2[i]);
            }
        }
    }

    // 创建新的Map,按出现次数分组存储数字
    const ansMap = new Map();
    res.forEach((val) => {
        // 获取当前数字及其在第一个数组中的出现次数
        const [num, count] = [val, map.get(val)];
        // 将数字添加到对应次数的组中,并保持组内数字有序
        ansMap.set(
            count,
            ansMap.get(count)
                ? [...ansMap.get(count), num].sort((a, b) => a - b)  // 如果该次数已有数字,则添加并排序
                : [num]  // 如果该次数还没有数字,则创建新数组
        );
    });

    // 获取所有出现次数并按升序排序
    const ansMapKeys = [...ansMap.keys()].sort((a, b) => a - b);
    // 按格式输出结果
    for (let i = 0; i < ansMapKeys.length; i++) {
        const key = ansMapKeys[i];
        console.log(`${key}:${[...ansMap.get(key)].join(",")}`);
    }
})();

// 示例说明:
// 输入:
// 1,2,2,3,3,3
// 2,3,4
// 输出:
// 1:2
// 3:3
// 解释:
// - 2在第一个数组中出现1次
// - 3在第一个数组中出现3次
// - 4不在第一个数组中,所以不输出