查找字符串中出现次数最多的字符

3,459 阅读2分钟

提示:以下代码都可以在node环境直接运行。

方法一:

大致思路:

1.先将无序的字符串排序。例如:‘bdacAbbDB’ => 'ABDabbbcd'。

2.再使用match方法按字符种类分割字符串。'ABDabbbcd' => ['A', 'B', 'D', 'a', 'bbb', 'c', 'd']

3.长度最长的字符串的字符即为出现次数最多的字符。['A', 'B', 'D', 'a', 'bbb', 'c', 'd'] => b,3次。

/**
 * @description 查找字符串中出现次数最多的字符
 * @param {string} text 要查询的字符串
 * @returns 成功返回 {text: '字符', count: '次数'},失败返回false
 */
function queryRepeatCount(text = 'aAbcedAbbcc') {
    if (typeof text !== 'string') {
        return false;
    }

    if (text.trim().length === 0) {
        return false;
    }

    // 将无序的字符串排序 aAbcedAbbcc => AAabbbcccde
    text = text.split('').sort().join('');

    // 正则:/([^])\1+/ => 将任意出现一次以上的字符作为一组
    // 记录出现次数超过一次的字符 AAabbbcccde => ['AA', 'bbb', 'ccc']
    const group = text.match(/([^])\1+/g) || [];
    const repeatObj = {text: '', count: 0};

    if (group.length === 0) {
        repeatObj.text = '每一个字符出现的次数都一样';
        repeatObj.count = 1;
    }

    // 筛选出出现次数最多的字符
    group.forEach((item) => {
        if (item.length > repeatObj.count) {
            repeatObj.text = item.substr(0, 1);
            repeatObj.count = item.length;
        } else if (item.length === repeatObj.count) {
            repeatObj.text += '、' + item.substr(0, 1);
        }
    });

    return repeatObj;
}

const repeatLetter = queryRepeatCount('f2werf3da2fd2f23422');

if (repeatLetter !== false) {
    console.log(`出现次数最多的字符为:${repeatLetter.text},出现了${repeatLetter.count}次。`);
}

方法二:

记录每个字符出现的次数,最后筛选出出现次数最多的字符。

/**
 * @description 查找字符串中出现次数最多的字符
 * @param {string} str 要查询的字符串
 * @returns 成功返回 {text: '字符', count: '次数'},失败返回false
 */
function queryLetterCountOne(str) {
    if (typeof str !== 'string') {
        console.error('arguments type error.');
        return false;
    }

    // 该字符串只有空格
    if (/^ +$/.test(str)) {
        console.error('arguments error.');
        return false;
    }

    // 移除字符串中的所有空格
    const noSpaceStr = str.replace(/ /g, '');

    // 记录所有字符出现的次数
    let record = null;
    for (let i = 0; i < noSpaceStr.length; i++) {
        if (record === null) {
            record = [{
                text: noSpaceStr[i],
                count: 1
            }];
        } else {
            // 查找该字符是否已经出现过了,有则次数加一,没有则记录。
            const index = record.findIndex((item) => item.text === noSpaceStr[i]);


            if (index === -1) {
                record.push({
                    text: noSpaceStr[i],
                    count: 1
                });
            } else {
                record[index].count += 1;
            }
        }
    }

    // 筛选出出现次数最多的字符
    let moreStr = null;
    for (let i = 0; i < record.length; i++) {
        if (moreStr === null) {
            moreStr = record[i];
        } else {
            if (record[i].count > moreStr.count) {
                // 记录出现次数最多的字符
                moreStr = record[i];
            } else if (record[i].count === moreStr.count) {
                // 记录出现次数相同的字符
                moreStr.text = moreStr.text + ',' + record[i].text;
            }
        }

        // record.length => 一共出现了多少种字符   noSpaceStr.length => 一共有多少个字符
        // 只要该字符出现的次数大于(noSpaceStr.length - record.length) / 2 + 1,则该字符出现次数最多
        if (moreStr.count >= (noSpaceStr.length - record.length) / 2 + 1) {
            break;
        }
    }

    return moreStr;
}

const moreLetter = queryLetterCountOne("to be or not to be,that's a questionobbbb.");

if (moreLetter !== false) {
    console.log(`${moreLetter.text} 出现的次数最多,出现了${moreLetter.count}次`);
}

方法三:

使用for...of遍历字符串,将每个字符出现的次数存入对象 中,键名为字符自身。

/**
 * @description 查找字符串中出现次数最多的字符
 * @param {string} str 要查询的字符串
 * @returns 成功返回 {text: '字符', count: '次数'},失败返回false
 */
function queryLetterCountTwo(str) {
    if (typeof str !== 'string') {
        console.error('arguments type error.');
        return false;
    }

    // 该字符串只有空格
    if (/^ +$/.test(str)) {
        console.error('arguments error.');
        return false;
    }

    // 移除字符串中的所有空格
    const noSpaceStr = str.replace(/ /g, '');

    const record = {};
    for (const key of noSpaceStr) {
        // 判断该键是否存在,存在则次数加一,不存在则添加该键并赋值一
        if (record.hasOwnProperty(key)) {
            record[key]++;
        } else {
            record[key] = 1;
        }
    }

    // 保存一共出现了多少种字符
    const kind = Object.keys(record).length;

    // 筛选出出现次数最多的字符
    const maxLetter = {
        text: '',
        count: 0
    };

    for (const key in record) {
        // 如果该字符出现的次数大于maxLetter中保存的字符出现的次数,则替换
        if (record[key] > maxLetter.count) {
            maxLetter.text = key;
            maxLetter.count = record[key];
        } else if (record[key] === maxLetter.count) {
            // 记录出现次数相同的字符
            maxLetter.text += ',' + key;
        }

        // 只要该字符出现的次数大于等于 (字符串长度-字符种类)/ 2 + 1,则该字符的出现次数一定最多
        if (maxLetter.count >= (noSpaceStr.length - kind) / 2 + 1) {
            break;
        }
    }

    return maxLetter;
}

const moreLetter = queryLetterCountTwo("to be or not to be,that's a questionobbbb.");

if (moreLetter !== false) {
    console.log(`${moreLetter.text} 出现的次数最多,出现了${moreLetter.count}次`);
}

方法四:

使用字符串的replace方法,获取字符出现的次数。

/**
 * @description 查找字符串中出现次数最多的字符
 * @param {string} str 要查询的字符串
 * @returns 成功返回 {text: '字符', count: '次数'},失败返回false
 */
function queryLetterCountThree(str) {
    if (typeof str !== 'string') {
        console.error('arguments type error.');
        return false;
    }

    // 该字符串只有空格
    if (/^ +$/.test(str)) {
        console.error('arguments error.');
        return false;
    }

    // 移除字符串中的所有空格
    let noSpaceStr = str.replace(/ /g, '');

    // 保存原字符串长度
    const permanentCou = noSpaceStr.length;

    // 获取一共有多少种字符
    const kindCount = new Set(noSpaceStr.split('')).size;

    // 保存出现次数最多的字符
    const maxLetter = {
        text: '',
        count: 0
    };

    while (noSpaceStr !== '') {
        // 保存一个副本
        const tempStr = noSpaceStr;

        // 将字符串中和第一个字符相同的字符都替换为空字符
        const regExp = new RegExp(noSpaceStr[0], 'g');
        noSpaceStr = noSpaceStr.replace(regExp, '');

        // 保存该字符出现的次数
        const count = tempStr.length - noSpaceStr.length;

        // 如果该字符的出现次数大于maxLetter中保存的字符的出现次数,则替换
        if (maxLetter.count < count) {
            maxLetter.text = tempStr[0];
            maxLetter.count = count;
        } else if (maxLetter.count === count) {
            // 记录出现次数相同的字符
            maxLetter.text += ',' + tempStr[0];
        }

        // 只要该字符出现的次数大于等于 (字符串长度-字符种类)/ 2 + 1,则该字符的出现次数一定最多
        if (maxLetter.count >= (permanentCou.length - kindCount) / 2 + 1) {
            break;
        }
    }

    return maxLetter;
}

const moreLetter = queryLetterCountThree("to be or not to be,that's a questionobbbb.");

if (moreLetter !== false) {
    console.log(`${moreLetter.text} 出现的次数最多,出现了${moreLetter.count}次`);
}

原文链接:www.wansongtao.com/blog/detail…