這兩天微博上看到左耳朵耗子吐槽了一下node社區的left-pad的代碼,原po鏈接
我也思考了一下 怎么用實現一個left-pad比較合適,上圖代碼確實比較搓
leftpad功能,就是字符串前面拼指定字符到固定長度,比如
leftpad('hello',20,'1'),就要返回'111111111111111hello'
版本1 用數組+join
function leftpad(str, len, ch) {
if (!ch && ch !== 0) ch = ' ';
var len = len - str.length;
return Array(len).join(ch) + str;
}
版本2 用一個帶length屬性的對象去實現join,免去了創建arr的步驟,性能應該回好點
function leftpad(str, len, ch) {
if (!ch && ch !== 0) ch = ' ';
var len = len - str.length;
return Array.prototype.join.call({
length:len
},ch)+str;
}
如果把Array.prototype.join緩存到外部變量里,多次使用速度更快
var _join = Array.prototype.join
function leftpad(str, len, ch) {
if (!ch && ch !== 0) ch = ' ';
var len = len - str.length;
return _join.call({
length:len
},ch)+str;
}
版本3 二分法
上面復雜度都是O(N)的,既然核心思路是把字符串重復n次,可以用二分法,比如把s,重復20次,拼在str前面,大概過程如下
total = ''
ch = 's'
20是偶數
ch變成ss
長度變成10
10是偶數
ch變成ssss
長度變成5
5是奇數
total += ch(total變成ssss)
ch變成ssssssss(8個)
長度變成2
2是偶數
ch繼續變成(ssssssssssssssss)(16個s)
長度變成1
total= total+ch(4個加16個)
結束代碼 拼接str 返回
代碼如下
function leftpad(str, len, ch) {
if (!ch && ch !== 0) ch = ' ';
var len = len - str.length,
total = ''
while (true) {
// 如果len是基數,total上就加一個ch
if (len % 2 == 1) total += ch;
if (len == 1) return total + str;;
// 每次ch都變成chch
ch += ch;
//長度減半
len = parseInt(len / 2);
}
}
最后寫完這些,看了耗子大神微博貼的代碼,突然想起求余和除以二取整,可以用 按位與len&1 和右移len>>1代替,囧,還是代碼寫的太少,沒想到
最后代碼
function leftpad(str, len, ch) {
if (!ch && ch !== 0) ch = ' ';
var len = len - str.length,
total = ''
while (true) {
// 如果len是基數,total上就加一個ch
if (len & 1 == 1) total += ch;
if (len == 1) return total + str;;
// 每次ch都變成chch
ch += ch;
//長度減半
len = len>>1;
}
}
大家可以嘗試用python實現一下(不要用自帶的rjust),本文僅提供一個思路,很小的一個功能函數,可能還會有很多更好的優化和實現,歡迎大家多指教寫代碼過程中還是要多思考,共勉