[算法小题] 字符串类走一波~ 与 split的实现~

520 阅读5分钟

目录

  1. 判断一个单词是否是回文?
  2. split的简易初版实现
  3. 再看字符串截取的三个方法

一 判断一个单词是否是回文?

字符串转换成数组,这个思路很重要,我们可以拥有更多的自由度去进行字符串的一些操作。

function checkPlalindromeStr(str){
    if(typeof str !== 'string'){return}
    return str === str.split('').reverse().join('');
};
var str = 'abcba';
var str1 = 'abc1ba';

checkPlalindromeStr(str); // true
checkPlalindromeStr(str1); // false
checkPlalindromeStr(11); // undefined

二 split的简易初版实现

注意: 如果把空字符串 ('') 用作 separator,那么 stringObject 中的每个字符之间都会被分割。

0) 分割符正则

var s='a|b/c-d'
s.split(/[\|\/\-]/);
// ['a', 'b', 'c', 'd']

1) split 的使用

stringObject.split(separator,howmany)
参数描述
separator必需。字符串或正则表达式,从该参数指定的地方分割 stringObject。
howmany可选。该参数可指定返回的数组的最大长度。如果设置了该参数,返回的子串不会多于这个参数指定的数组。如果没有设置该参数,整个字符串都会被分割,不考虑它的长度。
1.1) split 五种情况
  • split() 无参数时, 直接将整个字符串转换为数组 例: 'abc' -> ['abc']
  • split('') 有参数时,参数为 '' 例: 'abc' -> ['a', 'b', 'c']
  • split('-') 有参数时,参数为 '-'等等 字符串中的符号
  • split(/[\|\/\-]/) 有参数时,参数为 正则 字符串中的多个符号 /[|/-]/
  • split('',2) 有参数时, 先转为单个字符 并截取指定长度
'abc'.split()
// ['abc']
'abc'.split('')
// ['a', 'b', 'c']

**注意: ** 传入不存在的分割符时,直接被忽略,返回整个字符串做为数组中的唯一一项

以下三种都视为无参情况,没有split的意义

var a = 'abc'
a.split(); // ['abc']
a.split(' '); // ['abc']
a.split('---'); // ['abc']

split正确打开方式

var a = 'abc';
a.split(''); // ['a', 'b', 'c']
var a = 'a-b-c';
a.split('-'); // ['a', 'b', 'c']

**split 不会处理最开始和最结尾的分割符 **

var a = '-a-b-c-';
a.split('-'); // ['', 'a', 'b', 'c', '']
1.2) str转数组后,并通过第二个参数截取数组
var str="ab c!";
str.split("",2)
// ['a', 'b']

2) split的简易实现

String.prototype.split1=function(separator){
    // constructor 可能被改写,建议判断类型使用Object.ptototype.toString.call
    if(this.constructor !== String){throw new Error('请注意:只能操作字符串~')}
    let str = this; // 目标字符串
    // 入参: 分割符 separator
    // 返回值
    let res = [];
    // 此处只判断有分割符,(判断不准确),应该是判断每个字符后都有某个分割符.比如 'a-b-c'除了最后一个每个后都有 '-'
    if(separator){
        let reg = new RegExp(separator,'g'); // 在此处替换 分割符 比在循环中处理更好一些.
        str = str.replace(reg,'');
        traverse();
    }else{
        traverseNoSeparator();
    }
    function traverseNoSeparator(){
        // 没有传入 分割符, 把整个字符串转为数组可以用push('aaa')
        // 字符串转数组三个方法,1. [...str]  2. str.split  3. [].push(str)
        res.push(str.toString())
    };
    function traverse(){
            for(let i=0; i<str.length; i++){
            // 剔除'a-b-c'遍历后得到数组中 ['a', '-', 'b', '-', 'c'] 的'-'分割符
            // let temp = str[i] === separator ? '' : str[i]; // ['a', '', 'b', '', 'c'] 这样剔除明显不行
            let temp = str[i];
            res.push(temp);
        }
    }
    return res;
}

var str11 = 'a-8-b-&-c';
console.log(str11.split1())
// ['a-8-b-&-c']
console.log(str11.split1('-'))
// ['a', '8', 'b', '&', 'c']
2.1) split1测试用例 入参为正则

split 入参为正则

var s='a|b/c-d'
s.split(/[\|\/\-]/);
// ['a', 'b', 'c', 'd']

split1 入参为正则

var s='a|b/c-d'
s.split1(/[\|\/\-]/);
// ['a', 'b', 'c', 'd']
2.2) split1测试用例 无参时

split 无参时

var s='abc'
s.split();
// ['abc'] 

split1 无参时

var s='abc'
s.split1();
// ['abc'] 
2.2) split1测试用例 有参时

split 无参时

var s='a-b-c'
s.split('-');
// ['a', 'b', 'c']

split1 无参时

var s='a-b-c'
s.split1('-');
// ['a', 'b', 'c']

注意: 目前split简易版本还有很多场景不兼容,大家补充起来

3) new String('abc') 与 toString() 与 valueOf()

image.png

三 再看字符串截取的三个方法

0) 共三个方法

  • slice
  • substring
  • substr
0.1) 相同点不改变原始数据
0.2) 不同点参数不同
  • substring 不支持负参数.

js中有三个截取字符的方法,分别是substring()substr()slice(), 这三个方法都可以对字符串进行截取,并且返回一个新的字符串,也就是不会对原字符串进行修改

1) 只有 slice 可以接收负数做为参数

slice() 方法可提取字符串的某个部分,并以新的字符串返回被提取的部分

string.slice(start,end);

var a = '0123456789'
a.slice(1,5)
//'1234'
var a = '0123456789'
a.slice(-2);// '89'
1) slice 的方向性左=>右

start=>end对应左=>右,如果传入的两参数顺序是从右到左,那么返回空.

var str = '0123456789'
str.slice(2,1)// 2所在的位置是'2',1所在的位置是'1',从2=>1,方向相反,返回为空
a.slice(-2,1)// -2所在的位置是'8',1所在的位置是'1',从8=>1,方向相反,返回为空
a.slice(-2,-1)// -2所在的位置是'8',-1所在的位置是'9',从8=>9,方向正常,返回为'8'

2) substring

substring() 方法返回的子串包括 start 处的字符,但不包括 stop 处的字符。

string.substring(start,end);

var a = '0123456789';
a.substring(1,5);
//'1234'
  • end 可省略,直接截取到末尾

3) substr

substr() 方法可在字符串中抽取从 start 下标开始的指定数目的字符。

重要事项:ECMAscript 没有对该方法进行标准化,因此反对使用它。

string.substr(start,length);

var a = '0123456789';
a.substr(1,5);
//'12345'

参考

总结

  • split() 无参数时, 直接将整个字符串转换为数组 例: 'abc' -> ['abc']
  • split('') 有参数时,参数为 '' 例: 'abc' -> ['a', 'b', 'c']
  • js中有三个截取字符的方法,分别是substring()substr()slice(), 这三个方法都可以对字符串进行截取,并且返回一个新的字符串,也就是不会对原字符串进行修改
  • substr的第二个参数是长度,这是和其他两种方式最大的不同之处,slice的方向性比较强,永远是从start=>end对应左=>右,如果传入的两参数顺序是从右到左,那么返回空.
  • 截取原始字符串方法共三个,都不改变原始数据, 想要改变原始数据的截取字符串的方法没有,这个有点郁闷...
  • 字符串转数组三个方法: 1. [...str] 2. str.split 3. [].push(str)
split 五种情况
  1. split() 无参数时, 直接将整个字符串转换为数组 例: 'abc' -> ['abc']
  2. split('') 有参数时,参数为 '' 例: 'abc' -> ['a', 'b', 'c']
  3. split('-') 有参数时,参数为 '-'等等 字符串中的符号
  4. split(/[|/-]/) 有参数时,参数为 正则 字符串中的多个符号 /[|/-]/
  5. split('',2) 有参数时, 先转为单个字符 并截取指定长度
  • 注意: 目前split简易版本还有很多场景不兼容,大家补充起来