Skip to content

JS 字符串常见操作

统计信息:字数 7469 阅读15分钟

String 对象 API

使用 String 原生 API 操作:字符串增加(拼接 + )、更改(slice, substring)、查询(indexOf, lastIndexOf, includes)等常见操作。

和其他数据类型的转换等(number,array,dict);

str.length // 属性: 获取字符串的长度

charAt(0) 返回0位置的字符不改变原始字符串
charCodeAt(0) 返回0位置的字符的 Unicode使用按照字符顺序排序
fromCodeAt(65) 返回65Unicode对应的字符

toLowerCase()
toUpperCase() 转换成大写或者小写

// 搜索
indexOf
lastIndexOf 如果一个字符的开始搜索等于结束搜索index那么只有这一个字符
includes 判断是否存在

// 拼接
concat(str1, str2, str3) 连接多个字符串并返回
slice(start, end)
substring(start, end) 截取开始到结尾的字符串 [start, end)
substr(start, numbers) 从start开始截取截取长度是 numbers如果长度超过结尾或者不传参那么就到结尾

// 数据类型转换
split('') 字符串转换成数组

// 首尾操作
trim()
trimStart()
trimEnd()
padStart(2, '0') 用于时间或者进制转换
padEnd(10, '.00') 用于小数点转换
repeat(20) 重复字符串并返回
startsWith('hello') 判断字符串是否以某个子字符串开头str.indexOf(subStr) === 0
endsWith('00')

// 正则操作
replace(/test/.ig, 'Hello');

search('Mike') 可以查找字符串,或者查找正则表达式,输出对应的索引

let s = 'Mike Toni Tom';
let index = s.search(/Tom/ig);
// 10

match(/test/ig) 全局查找test(不区分大小写)并将查找结果数组返回

let s = 'asdfghjklasdfghjklasdfghjkASDFGH';
let arr = s.match(/asd/ig);
// ["asd", "asd", "asd", "ASD"]

* 特殊:位运算处理进制转换(不常用)

function bin2dec(bin) {
  // 传入二进制,先转换成十进制数字,然后转换成字符串输出
  return parseInt(bin, 2).toString(10);
}
function dec2bin(dec) {
  // 传入十进制,先使用位运算转换,然后转换成二进制字符串输出
  // >>> 表示把dec转换成二进制,然后前边加0,然后向右移动0位
  return (dec >>> 0).toString(2);
}

下面是实际题目(获取字符串子序列,统计出现的次数;反转字符串)

随机字符串

可以获取指定长度的随机字符串(生成默认密码)

/**
* Get random string
**/
function randomString(n) {
  let str = 'abcdefghijklmnopqrstuvwxyz9876543210'; // 这里可以增加密码强度
  let tmp = '';
  let l = str.length;
  for (let i = 0; i < n; i++) {
    tmp += str.charAt(Math.floor(Math.random() * l));
  }
  return tmp;
}

最长公共前缀

获取一个字符串数组中,最长的公共前缀

https://leetcode.com/problems/longest-common-prefix/description/

第一种解法

var longestCommonPrefix = function(strs) {
  if (strs.length === 0) return '';
  if (strs.length === 1) {
    return strs[0];
  }
  let commonPrefix = '';
  for (let i = 0, len = strs[0].length; i < len; i++) {
    let str = strs[0].charAt(i);
    for (let j = 0; j < strs.length; j++) {
      if (str !== strs[j].charAt(i)) {
        return commonPrefix;
      }
    }
    commonPrefix += str;
  }
  return commonPrefix;
};

第二种解法

/**
 * Write a function to find the longest common prefix string amongst an array of strings.
 * input [] => '' ['abc', 'abe', 'abe'] => 'ab'
*/
const findLongestCommonPrefix = function (strs) {
  // 数组长度是0,那么直接返回空字符串
  if (strs.length === 0) {
    return ''
  }
  // todo:数组长度是1,直接返回第一项

  // 辅助函数:判断数组的公共前缀是否是str
  var fn = function (str) {
    for (let i = 0; i < strs.length; i++) {
      // 或者使用 strs[i].startsWith(str)
      if(strs[i].indexOf(str) !== 0) {
        return false
      }
    }
    return true
  }

  const prefixMap = {}
  let key = ''
  let j = 0
  // 没有必要根据字符串的长度排序
  while(key !== strs[0]) {
    // 依次把当前的第一个字符的子序列获取到,循环判断是否是公共前缀
    const q = (key + strs[0][j++])
    if (!fn(q)) {
      break  
    }
    key = q
  }
  // 返回公共前缀
  return key;
}
console.log(findLongestCommonPrefix(["a","b"]))

无重复字符的最长子串

https://leetcode.com/problems/longest-substring-without-repeating-characters/description/

第一种解答(性能不好)

/**
 * @param {string} s
 * @return {number}
 */
// 初步思路:双指针(快慢指针实现)
// 两个指针移动,然后不断判断子序列内部是否重复,然后累计计算当前最长的距离。

var lengthOfLongestSubstring = function(s) {
  // true 没有重复字符串
  var checkStr = (str) => {
    const len = str.length;
    for (let i = 0; i < len; i++) {
      let current = str[i];
      if (str.lastIndexOf(current) !== str.indexOf(current)) {
        return false;
      }
    }
    return true;
  }

  const len = s.length;
  // 处理特殊情况(如果长度是0或者是1,那么直接返回长度)
  if (len <= 1) {
    return len;
  }
  // 设置初始值
  let start = 0;
  let end = 1;
  let num = 1;

  // 循环
  while (end <= len - 1) {
    let sub = s.slice(start, end + 1);
    let result = checkStr(sub);
    // 如果不重复
    if (result) {
      end++;
      num = num > sub.length ? num : sub.length;
    }
    // 如果重复,重新开始
    else {
      if (end === len - 1) {
        return num;
      } else {
        start = start + 1;
        end = end + 1;
      }
    }
    console.log(sub, result, start, end, num);
  }
  return num;
};
// 1、循环获取子串 ——双指针
// 2、如何判断一个子串是否有重复字符?——这个直接IndexOf行不行
// 如果这个方法不好,那么使用对象判断是否重复

第二种解答

todo:分析这两种方法的复杂度,然后leetcode重新提交

const lengthOfLongestSubstring = function(str) {
  let i = 0;
  let maxSubstring = str[i];
  let currentMaxString = str[i];
  let position = 0;

  // 循环当前字符串,设置指针记录无重复子串的位置
  // 如果新的子串长度大于已有子串,那么就使用新的子串
  for (let j = 1; j < str.length; j++){
    if (currentMaxString.indexOf(str[j]) >= 0) {
      i = currentMaxString.indexOf(str[j]) + 1 + position;
      if (currentMaxString.length > maxSubstring.length) {
        maxSubstring = currentMaxString;
      }
      if (i === j) {
        currentMaxString = str[j];
      } else {
        currentMaxString = str.substring(i, j);
        str = str.substr(i);
      }
      continue;
    }
    currentMaxString += str[j];
    maxSubstring = currentMaxString;
  }
  return maxSubstring;
};

lengthOfLongestSubstring("dvdf")

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

/**
* find the maximum duplicate char in an string
**/
function findMaxDuplicateChar(str) {
  if (str.length == 1) {
    return str;
  }
  let charObj = {};
  for (let i=0; i < str.length; i++) {
    if(!charObj[str.charAt(i)]) {
      charObj[str.charAt(i)] = 1;
    } else{
      charObj[str.charAt(i)] += 1;
    }
  }
  let maxChar = '',
      maxValue = 1;
  for (var k in charObj) {
    if (charObj[k] >= maxValue) {
      maxChar = k;
      maxValue = charObj[k];
    }
  }
  return maxChar;
}

Last update: November 9, 2024