获取字符串中出现最多的字符和次数

这里提供三个方案,第一个方案是之前的。

// 第一个方案
var getFunc1 = function (str) {

    // 通过sort简单排序  得到排列好的字符串
    var temp = str.split('').sort().join(''),
        times = 0,
        index = 0,
        found = false,
        getIndex = function (times) {
            times -= 1;
            // 用正则去匹配尽量多的相同字符
            // 正则不太熟还真是要闹笑话 - -!
            return temp.search( new RegExp('(\\w)\\1{' + times + '}') );
        };

    if (temp.length) {
        // 有长度 即有一次
        times = 1;

        while(!found) {
            // 获取出现相应次数的字符的位置
            index = getIndex(times);
            // 已过了最大次数
            if (index === -1) {
                // 标记找到  退出循环
                found = true;
            } else {
                // 否则增加次数
                times += 1;
            }
        }

        // 返回最大次数
        times -= 1;
        // 调用函数获得最大次数的位置
        index = getIndex(times);
    }

    return {
        code : temp.charAt(index),
        times : times
    };
};

// 现在给出第二个方案
var getFunc2 = function (str) {
    // 同方案一,但只是获得数组
    var arr = str.split('').sort(),
        index = 0,
        i = arr.length - 1,
        max = 0,
        times = 1;

    while (i !== -1) {
        // 当后一个字符和前一个字符一致
        while(arr[i] === arr[ i - 1 ]) {
            // 增加次数 并减小i
            times += 1;
            i--;
        }
        // 如果次数大于最大次数  赋值max  并标记index为当前i
        if (times > max) {
            max = times;
            index = i;
        }
        // times 置为初始
        times = 1;
        i--;
    }
    return {
        code : arr[index],
        times : max
    };
};

// 第三个方案, 网上的 做了一点优化
var getFunc3 = function (str) {
    var maxlength = 0,
        old = '',
        first = '',
        code = '',
        len = 0;
    while(str !== ''){
        old = str;
          first = str.substr(0, 1);
          str = str.replace(new RegExp(first, 'g'), '');
          len = old.length - str.length;

          if (len > maxlength) {
              maxlength = len;
              code = first;
          }
    }
    return {
        code : code,
        times : maxlength
    };
};

性能测试方面,都使用以下相同的方式:

var a = '34adasdaaa',
    start = new Date().getTime(),
    i = 8;
for ( ; i--; ) {
    a += a;
}
console.log( getFunc1(a) );  // 2、3类似
var end =  new Date().getTime();
console.log(end - start);

测试结果(6次):
getFunc1: 1186ms 1173ms 1170ms 1161ms 1173ms 1170ms
getFunc2: 1ms 2ms 1ms 1ms 1ms 1ms
getFunc3: 3ms 1ms 1ms 1ms 1ms 1ms

Update:添加方案一空白符情况及优化代码语义。—— 2014.06.09 21:45

var processSpace = function (str) {
    var len = str.length;
    if (!len) {
        return {
            code : '',
            times : 0
        };
    }

    var remainLen = str.replace(/\s/g, '').length;
    if (!remainLen) {
        return {
            code : ' ',
            times : len
        };
    } else if (remainLen <= len / 2) {
        return {
            code : ' ',
            times : len - remainLen
        };
    }
};

var getIndex = function (temp, times) {
    times -= 1;
    return temp.search( new RegExp('(.)\\1{' + times + '}') );
};

var getFunc1 = function (str) {

    var spaceSituation = processSpace(str);
    if (spaceSituation) {
        return spaceSituation;
    }

    // 通过sort简单排序  得到排列好的字符串
    var temp = str.split('').sort().join(''),
        times = 1,
        index = 0,
        found = false;

    while(!found) {
        // 获取出现相应次数的字符的位置
        index = getIndex(temp, times);
        // 已过了最大次数
        if (index === -1) {
            // 标记找到  退出循环
            found = true;
        } else {
            // 否则增加次数
            times += 1;
        }
    }

    // 返回最大次数
    times -= 1;
    // 调用函数获得最大次数的位置
    index = getIndex(temp, times);

    return {
        code : temp.charAt(index),
        times : times
    };
};