字符串基础API使用
因为字符串不可以修改
增
这里增的意思并不是说直接增添内容,而是创建字符串的一个副本,再进行操作
除了常用+
以及${}
进行字符串拼接之外,还可通过concat
concat
用于将一个或多个字符串拼接成一个新字符串
let stringValue = "hello ";
let result = stringValue.concat("world");
console.log(result); // "hello world"
console.log(stringValue); // "hello"
删
这里的删的意思并不是说删除原字符串的内容,而是创建字符串的一个副本,再进行操作
常见的有:
- slice()
- substr()
- substring()
这三个方法都返回调用它们的字符串的一个子字符串,而且都接收一或两个参数。
let stringValue = "hello world";
console.log(stringValue.slice(3)); // "lo world"
console.log(stringValue.substring(3)); // "lo world"
console.log(stringValue.substr(3)); // "lo world"
console.log(stringValue.slice(3, 7)); // "lo w"
console.log(stringValue.substring(3,7)); // "lo w"
console.log(stringValue.substr(3, 7)); // "lo worl"
日常主要使用 slice
改
这里改的意思也不是改变原字符串,而是创建字符串的一个副本,再进行操作
常见的有:
- trim()
- repeat()
- padStart()、padEnd()
- toLowerCase()、 toUpperCase()
trim()
删除前、后或前后所有空格符,再返回新的字符串
let stringValue = " hello world ";
let trimmedStringValue = stringValue.trim();
console.log(stringValue); // " hello world "
console.log(trimmedStringValue); // "hello world"
repeat()
接收一个整数参数,表示要将字符串复制多少次,然后返回拼接所有副本后的结果
let stringValue = "na ";
let copyResult = stringValue.repeat(2) // na na
padEnd()
复制字符串,如果小于指定长度,则在相应一边填充字符,直至满足长度条件
let stringValue = "foo";
console.log(stringValue.padStart(6)); // " foo"
console.log(stringValue.padStart(9, ".")); // "......foo"
toLowerCase()、 toUpperCase()
大小写转化
let stringValue = "hello world";
console.log(stringValue.toUpperCase()); // "HELLO WORLD"
console.log(stringValue.toLowerCase()); // "hello world"
查
除了通过索引的方式获取字符串的值,还可通过:
- chatAt()
- indexOf()
- startWith()
- includes()
charAt()
返回给定索引位置的字符,由传给方法的整数参数指定
let message = "abcde";
console.log(message.charAt(2)); // "c"
indexOf()
从字符串开头去搜索传入的字符串,并返回位置(如果没找到,则返回 -1 )
let stringValue = "hello world";
console.log(stringValue.indexOf("o")); // 4
startWith()、includes()
从字符串中搜索传入的字符串,并返回一个表示是否包含的布尔值
let message = "foobarbaz";
console.log(message.startsWith("foo")); // true
console.log(message.startsWith("bar")); // false
console.log(message.includes("bar")); // true
console.log(message.includes("qux")); // false
转换方法
split
let str = "12+23+34"
let arr = str.split("+") // [12,23,34]
模板匹配方法
针对正则表达式,字符串设计了几个方法:
- match()
- search()
- replace()
match()
接收一个参数,可以是一个正则表达式字符串,也可以是一个RegExp
对象,返回数组
let text = "cat, bat, sat, fat";
// 以 at 结尾
let pattern = /.at/;
let matches = text.match(pattern);
console.log(matches[0]); // "cat"
search()
接收一个参数,可以是一个正则表达式字符串,也可以是一个RegExp
对象,找到则返回匹配索引,否则返回 -1
let text = "cat, bat, sat, fat";
let pos = text.search(/at/);
console.log(pos); // 1
replace()
接收两个参数,第一个参数为匹配的内容,第二个参数为替换的元素(可用函数)
let text = "cat, bat, sat, fat";
let result = text.replace("at", "ond");
console.log(result); // "cond, bat, sat, fat"
let result2 = text.replace(/.at/g, 'ond');
console.log(result); // 'cond, bond, sond, fond'
leetcode-字符串
反转字符串
地址:https://leetcode.cn/problems/reverse-string/
简单。。
/**
* @param {character[]} s
* @return {void} Do not return anything, modify s in-place instead.
*/
var reverseString = function(s) {
for(let i = 0; i < Math.floor(s.length / 2); i++) {
let temp = s[i];
s[i] = s[s.length - i - 1];
s[s.length - i -1] = temp
}
return s
};
反转字符串 ||
地址:https://leetcode.cn/problems/reverse-string-ii/
字符串不好处理,转成数组来解决,这题不难,就是要仔细考虑考虑边界的问题
/**
* @param {string} s
* @param {number} k
* @return {string}
*/
var reverseString = function(arr, left, right) {
while(left < right) {
let temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
left++;
right--;
}
};
var reverseStr = function(s, k) {
let arr = Array.from(s);
for(let i = 0; i < arr.length; i += 2 * k ) {
reverseString(arr, i, Math.min(k - 1, s.length - i - 1) + i)
}
return arr.join('')
};
替换空格
地址:https://leetcode.cn/problems/ti-huan-kong-ge-lcof/
参考:代码随想录。
简单解法
正则就可以解决
/**
* @param {string} s
* @return {string}
*/
var replaceSpace = function(s) {
return s.replace(/\s/g, '%20')
};
双指针法
首先扩充数组到每个空格替换成"%20"之后的大小。
然后从后向前替换空格,也就是双指针法,过程如下:
i指向新长度的末尾,j指向旧长度的末尾。
但 js 的字符串是不可改变的,不可避免要额外的辅助空间,那就更简单了,不需要如下图这么复杂。
翻转字符串里的单词
这题的要求
**进阶:**如果字符串在你使用的编程语言中是一种可变数据类型,请尝试使用
O(1)
额外空间复杂度的 原地 解法。
显然, js的 字符串是不可变的。
这题就用数组和字符串API解决(先将字符串转换成数组)
/**
* @param {string} s
* @return {string}
*/
var reverseWords = function(s) {
return s.split(' ').filter(item => item != '').reverse().join(' ').trim();
};
实现 strStr()
地址:https://leetcode.cn/problems/implement-strstr/
这题简答解决就是直接调用API解决,但这题往深了说是想考KMP算法,KMP思想其实不难,但在实现过程中有很多巧合(这一定有内在的数学联系,不过我理解不了,这能把他当成一种巧合),所以不要去理解它,去感受它。
在寻找这个规律的过程可以看看代码随想录的讲解:https://www.bilibili.com/video/BV1PD4y1o7nd/
JS实现KMP
/**
* @param {string} haystack
* @param {string} needle
* @return {number}
*/
var strStr = function(haystack, needle) {
if (needle.length === 0)
return 0;
const getNext = (needle) => {
let next = [];
let j = 0;
next.push(j);
for (let i = 1; i < needle.length; i++) {
while (j > 0 && needle[i] !== needle[j])
j = next[j - 1];
if (needle[i] === needle[j])
j++;
next.push(j);
}
return next;
}
let next = getNext(needle);
let j = 0;
for (let i = 0; i < haystack.length; i++) {
while (j > 0 && haystack[i] !== needle[j])
j = next[j - 1];
if (haystack[i] === needle[j])
j++;
if (j === needle.length)
return (i - needle.length + 1);
}
return -1;
};
重复的子字符串
地址:https://leetcode.cn/problems/repeated-substring-pattern/
简单解法:调用API,哈哈
/**
* @param {string} s
* @return {boolean}
*/
var repeatedSubstringPattern = function(s) {
for(let i = 0; i < s.length; i++) {
let str = s;
let cstr = s.slice(0, i);
let nstr = s.replaceAll(cstr, '');
if(nstr == '') {
return true
}
}
return false
};
深入解法:
凡是遇到字串的问题,都看看是否可以用KMP算法解决,这题也可以用KMP解决。
参考代码随想录:
很多时候,题目更高效率的解决都是规律的发现,但规律的背后都是数学原理(咱理解不了),所以感受它,不要理解。。。
/**
* @param {string} s
* @return {boolean}
*/
var repeatedSubstringPattern = function (s) {
if (s.length === 0)
return false;
const getNext = (s) => {
let next = [];
let j = -1;
next.push(j);
for (let i = 1; i < s.length; i++) {
while (j >= 0 && s[i] !== s[j + 1])
j = next[j];
if (s[i] === s[j + 1])
j++;
next.push(j);
}
return next;
}
let next = getNext(s);
if (next[next.length - 1] !== -1 && s.length % (s.length - (next[next.length - 1] + 1)) === 0)
return true;
return false;
};