写在开头:
字符串是前端基本类型之一,很多场合都涉及到对字符串进行处理。但是处理字符串的时候,往往要借助数组、正则等方法,不仅可以让工作变得简单,也能加快处理效率。
字符串的原型上的属性和方法:
length:字符串的长度属性
charAt:获取某个角标的字符,等同于string[index],入参:角标位置
substring:截取字符串字符的方法,入参:开始位置角标、位数
substr:和substring用法相同,区别是可以入参负数作为开始角标的位置(负数为从结尾开始计算)
slice:截取字符串字符的方法,入参:开始位置角标、结束位置角标,如果有两个参数,会自动将较小的作为开始,较大的作为结束,如果参数为负数则是从结束位置开始计算位置。
indexOf:获取字符串中某个字符的位置(从开始位置),入参:字符,角标(有:返回该角标之后的结果),返回结果:角标(获取到位置)、-1(未获取到位置)
lastIndexOf:获取字符串中某个字符的位置(从结束位置),入参和出参同上。
search:几乎等同于indexOf,但是它无法设置第二个参数。
split:将字符串以特定的字符切割成数组,入参:切割字符,出参:数组
replace:将字符串中的某个字符替换成另一个字符,入参:被替换字符、替换后的字符
toUppercase:将字符串中的字母转化成大写
toLowerCase:将字符串中的字母转化成小写
concat:连接两个或多个字符串,等同于+运算符
trim:删除空格
更多字符串处理方法见W3school
1.输入一个字符串,输出出现最多的字符极其个数
function fn(str){
const result = {}
let maxKey = '',maxNum = 0
str.split('').forEach((item)=>{
if(result[item]){
result[item]+=1
}else{
result[item]=1
}
if(result[item]>maxNum){
maxKey = item
maxNum= result[item]
}
})
return '出现最多的字符是'+maxKey+',出现了'+maxNum+'次'
}
2.以数组中每项的第二个字符排序
function mySort(inputs){
// 没法直接对字母进行加减运算,但是可以对比大小
return inputs.sort((a,b)=>{
if(a[1]>b[1]) return 1
if(a[1]<b[1]) return -1
return false
})
}
3.给定一个数字,返回结果为每三个数加一个逗号,比如100000,返回结果为100,000
function formatNum(num){
const arr = num.toString().split('')
let len = arr.length
if(len<3) return num
while(len>3){
arr.splice(len-3,0,',')
len -= 3
}
return arr.join('')
}
4.反转字符串中的元音字母(最简写法)
输入:'ifdfodiuodfdaa' 输出:' afdfadouidfdoi'
function myReverse(str) {
const regex = /a|o|e|i|u|v/g
// 加g代表全文匹配,会记录匹配到的字段在位置,再次匹配到的时会跳过那个记录的位置进行匹配
if (!regex.test(str)) return str
const result = str.split('')
const arr = str.match(regex).reverse()
const res = result.map((string) => {
if (!/a|o|e|i|u|v/.test(string)) { // 不加g,每次都会重新匹配
return string
}
return arr.shift()
}).join('')
return res
}
5.从字符串中查找合法的 IP 段
ip地址,全名为Internet Protocol Address,是指互联网协议地址,IP地址为统一的地址格式,是互联网里面的不同网络和不同主机分配一个逻辑地址,以此来区别物理地址。
ip地址是32位的二进制字符,由分为4段,每段8位,但是每组都分别以十进制展示,最大不超过255(即二进制最大八位数:11111111)
P地址由两部分组成,即网络地址和主机地址。网络地址表示其属于互联网的哪一个网络,主机地址表示其属于该网络中的哪一台主机。二者是主从关系
IP地址分为A、B、C、D、E四类。
A类地址:第一段为网络地址,它的范围是0-127,后三段为主机地址,范围:0-255,全地址范围:0.0.0.0-127.255.255.255,对应的子网掩码为:255.0.0.0,一般适用于大型网络
B类地址:前两段为网络地址,第一段的范围是128-191,后三段范围:0-255,全地址范围:128.0.0.0-191.255.255.255,对应的子网掩码:255.255.0.0,一般适用于中型网络
C类地址:前三段为网络地址,第一段的范围:192-223,后三段的范围:0-255,全地址范围:192.0.0.0-223.255.255.255,对应的子网掩码:255.255.255.0,一般适用于小型网络
D类:该类IP地址的最前面为“1110”,范围在224.0.0.0~239.255.255.255,不区分网络,一般用于多路广播用户。
E类I:以“11110”开始,范围在240.0.0.0~254.255.255.255不区分网络,保留用于将来和实验使用。
综上所述,合法的ip字段,四个字段的取值范围都在0-255,且不能有前置零的情况。
// 递归法
function getIpList(str) {
const len = str.length
const result = []
if (4 > len || 12 < len) return []
splite(str, 1, '', result)
return result
}
function splite(str, num, out, result) {
if (num === 5 && str.length === 0) {
result.push(out)
return
}
for (let i = 1; i < 4; i++) {
// i代表要截取的字符位数
if (str.length < i) break
const outStr = str.substring(0, i)
if (!valid(outStr)) break
const newOut = out + outStr + (num === 4 ? '' : '.')
splite(str.substring(i), num + 1, newOut, result)
}
}
function valid(str) {
let passd = true
if (str.length > 1) {
if (str[0] === '0') {
passd = false
}
}
if (+str > 255) {
passd = false
}
return passd
}
console.log(getIpList('1231423125'))
这个算法题目,我花了好长时间。我总觉得有优化的地方,比如每一段的字符长度有一个合法性区间(不能为0,也不能超过三),如果能根据剩余字符长度将这个区间计算出来,或许可以减少递归和遍历的次数,提升性能。后来找到了那种区间规律,但是将那一部分加进去的话,逻辑就变得复杂了,于是就又摘离了出去。如果有大佬有更加简单高效的算法,欢迎留言交流。
未完待续,持续更新...