实现字符串 repeat 方法
多种方式实现字符串的重复拼接功能
问题
实现一个 repeat 方法,将目标字符串重复 n 次并拼接返回。
解答
方法一:Array.join
利用数组的 join 方法,创建指定长度的数组并用目标字符串连接。
function repeat(target, n) {
return (new Array(n + 1)).join(target);
}
方法二:类数组对象
省去创建数组的开销,直接使用类数组对象调用 join 方法。
function repeat(target, n) {
return Array.prototype.join.call({
length: n + 1
}, target);
}
方法三:闭包缓存
通过闭包缓存 join 方法和对象引用,避免重复查找和创建。
var repeat = (function () {
var join = Array.prototype.join, obj = {};
return function(target, n) {
obj.length = n + 1;
return join.call(obj, target);
};
})();
方法四:二分法
使用位运算和二分思想,减少字符串拼接次数,时间复杂度 O(log n)。
function repeat(target, n) {
var s = target, total = [];
while (n > 0) {
if (n % 2 === 1) {
total[total.length] = s;
}
if (n === 1) {
break;
}
s += s;
n = n >> 1;
}
return total.join('');
}
方法五:二分法优化(字符串直接拼接)
去掉数组和 join,直接拼接字符串,但会产生额外长度需要截取。
function repeat(target, n) {
var s = target, c = s.length * n;
do {
s += s;
} while (n = n >> 1);
s = s.substring(0, c);
return s;
}
方法六:二分法改良
结合方法四的思路,用字符串直接拼接替代数组。
function repeat(target, n) {
var s = target, total = "";
while (n > 0) {
if (n % 2 === 1) {
total += s;
}
if (n === 1) {
break;
}
s += s;
n = n >> 1;
}
return total;
}
关键点
- 方法一、二、三基于数组
join,简单但性能一般,适合小规模重复 - 方法三通过闭包缓存提升性能,避免重复创建对象和查找方法
- 方法四、五、六使用二分法,时间复杂度从 O(n) 降至 O(log n),适合大量重复
- 位运算
n >> 1等价于Math.floor(n / 2),性能更优 - 二分法的核心思想:每次将字符串翻倍,根据 n 的奇偶性决定是否累加当前结果
目录