工作和面试中绝对会碰到的问题-字符串的操作,看了就懂了

160 阅读3分钟

前言

最近在面试的时候有做过类似的一道题,也是面试非常常见的对字符串操作,在这里分享下我自己的实现思路。

先看题目:

1.  请用JS代码生成由数字和大小写字母组成的,长度为100的随机字符串 

<!---->

2.  找出题目1的随机串中连续最长的字母串 

<!---->

3.  统计题目1的随机串中每个字符出现的次数,并按数量进行降序排序 

<!---->

4.  删除题目1的随机串中符合以下所有条件的字符: 

(1)出现次数最少 

(2)复数出现的字符:如ds33abc、ab333ab,处理之后为dsabc,abab

解答

1.请用JS代码生成由数字和大小写字母组成的,长度为100的随机字符串

//先定义好大小写字母和数字的字符串,然后用Math.random生成字符串长度的随机数,获取到随机下标,然后从字符串里拿到对应的字符进行拼接。
getRandomString(length, charSet) {
  charSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  let randomString = "";
  for (let i = 0; i < length; i++) {
    let randomPoz = Math.floor(Math.random() * charSet.length);
    randomString += charSet.substring(randomPoz, randomPoz + 1);
  }
  this.randomString = randomString;
  return randomString;
}

2.找出题目1的随机串中连续最长的字母串

这里是要拿连续最长的字母串,由于生成的随机字符串是包含数字的,所以我们可以用数字去做分割,然后再判断分割后的字符串数组,判断哪个是最长的,则可以拿到最长的字母串。

getMaxLengthStr() {
  //先获取随机字符串
  let newStr = this.randomString;
  // 解题思路:  替换所有的数字变成“,” 然后用split(',')去分割字符串,再循环得到的字符串数组拿到最长的。
  newStr = newStr.replace(/\d/g, ",").split(",");
  //针对得到的数组进行长度排序,最长的字符串在最前面;
  newStr = newStr.sort((a, b) => {
    return b.length - a.length;
  });
  return [newStr.length ? newStr[0].length : 0]; //做个兼容,
}
  1. 统计题目1的随机串中每个字符出现的次数,并按数量进行降序排序

思路: 1. 先获取每个字符出现的次数 2. 根据次数进行降序

//获取每个字符出现的次数
 getStrMapLength(){
      let newStr = this.randomString;
      //解题思路: 创建一个空对象,循环字符串统计每个字符的长度,没有则设置为1,有则自增。
      let map = {};
      for (let i of newStr) {
        map[i] = !map[i] ? 1 : map[i] + 1;
      }
      return map;
}

 //获取字符的数量和降序的数组
getSortArr() {
  //通过Object.entires获取对象里的键值对的数组,通过对数组的排序实现降序操作
  let newArr = Object.entries(this.getStrMapLength());
  newArr = newArr.sort((a, b) => {
    return b[1] - a[1];
  });
  // console.log("根据数量降序后的数组", newArr);
  return newArr;
}
  1. 删除题目1的随机串中符合以下所有条件的字符: (1)出现次数最少 解题思路,出现次数最少的只能是1了,有可能出现多个只出现1次的字符,所以要先把次数为1的字符串筛选出来放到数组里,然后循环数组删除对应的字符串
//获取出现次数最少为1的数字或者字母集合
getMinArr(){
      //循环获取最少次数为1的数字或者字母,放进数组里
      let map = this.getStrMapLength(),arr = [];
      for(let i in map){
        if(map[i] === 1){
          arr.push(i)
        }
      }
      return arr || []
      console.log('次数最少的数组集合',arr)
}

//删除出现次数最少的字符串
deletMinNumStr() {
      //解题思路: 获取到最少次数为1的字母或者数字的集合,通过循环替换的方式,删掉对应的字符串
      let arr = this.getMinArr();
      let copyRandomStr = this.randomString;
      for(let i of arr){
        copyRandomStr = copyRandomStr.replace(i,'');
      }
      return copyRandomStr
}

(2)复数出现的字符:如ds33abc、ab333ab,处理之后为dsabc,abab

解题思路:主要是利用正则去匹配重复出现的字符,把所有能匹配上的都放进数组里,然后把匹配到的字符串数组replace成一个空字符串。

//删除复数出现的字符串
getDeleteDoubleStr(str =''){
      //str为输入的测试用例,如果不传,则为上面生成的100个随机数列
      let copyRandomStr =  str||this.randomString;
      //使用正则去匹配重复字符
      let doubleArr = copyRandomStr.match(/(.)\1+/g);

      if(doubleArr == null){
        console.log('生成的字符中没有重复的,直接返回原随机数组');
        return copyRandomStr;
      }else{
        console.log('获取到的复数数组为',doubleArr)
        for(let i=0;i<doubleArr.length;i++){
          copyRandomStr = copyRandomStr.replace(doubleArr[i],'')
        }
        return copyRandomStr
      }
}

整体的代码

<!--
 * @Description: 
 * @Author: huangkaicheng
 * @Date: 2022-04-12 16:07:25
 * @LastEditTime: 2022-04-12 18:09:15
 * @LastEditors: huangkaicheng@foxmail.com
-->

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      class SortClass {
        constructor() {
          this.randomString = "";
          this.init();
        }

        init() {
          this.randomString = this.getRandomString(100);
          console.log("第一题:-----------------------------------------------");
          console.log("获取100位随机的字母数字组成的字符串", this.randomString);
          let getMaxLengthStr = this.getMaxLengthStr();
          console.log("第二题:-----------------------------------------------");
          console.log(
            "随机串中连续最长的字母串",
            getMaxLengthStr[0],
            "字符串为",
            getMaxLengthStr[1]
          );

          console.log("第三题:-----------------------------------------------");
          let mapArr = this.getStrMapLength();
          console.log("每个字符出现的次数对象为:", mapArr);
          console.log("按照数量进行降序后获得数组为:");
          this.getSortArr();

          console.log("第四题:-----------------------------------------------");
          console.log("获取100位随机的字母数字组成的字符串", this.randomString);
          console.log('删除出现最少次数后的随机字符串',this.deletMinNumStr());

          console.log('删除复数后的随机字符串为',this.getDeleteDoubleStr());


          console.log('输入的复数测试用例1-------------ds33abc');
          console.log(this.getDeleteDoubleStr('ds33abc'))

          console.log('输入的复数测试用例2-------------ab333ab');
          console.log(this.getDeleteDoubleStr('ab333ab'))
        }
        /**
         * length : 随机生成的字符长度 数字类型
         * charSet : 可选择的字符集,如果不传则选择默认值
         * description : 获取随机字符串
         */
        getRandomString(length, charSet) {
          charSet =
            charSet ||
            "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
          let randomString = "";
          for (let i = 0; i < length; i++) {
            let randomPoz = Math.floor(Math.random() * charSet.length);
            randomString += charSet.substring(randomPoz, randomPoz + 1);
          }
          this.randomString = randomString;
          return randomString;
        }

        getMaxLengthStr() {
          //先获取随机字符串
          let newStr = this.randomString;
          // 解题思路:  替换所有的数字变成“,” 然后用split(',')去分割字符串,再循环得到的字符串数组拿到最长的。
          newStr = newStr.replace(/\d/g, ",").split(",");
          //针对得到的数组进行长度排序,最长的字符串在最前面;
          newStr = newStr.sort((a, b) => {
            return b.length - a.length;
          });
          return [newStr.length ? newStr[0].length : 0, newStr[0]]; //做个兼容,
        }
        //获取每个字符出现的次数
        getStrMapLength(){
          let newStr = this.randomString;
          //解题思路: 创建一个空对象,循环字符串统计每个字符的长度,没有则设置为1,有则自增。
          let map = {};
          for (let i of newStr) {
            map[i] = !map[i] ? 1 : map[i] + 1;
          }
          return map;
        }


        //获取字符的数量和降序的数组
        getSortArr() {
          //通过Object.entires获取对象里的键值对的数组,通过对数组的排序实现降序操作
          let newArr = Object.entries(this.getStrMapLength());
          newArr = newArr.sort((a, b) => {
            return b[1] - a[1];
          });
          // console.log("根据数量降序后的数组", newArr);
          return newArr;
        }


        //获取出现次数最少为1的数字或者字母集合
        getMinArr(){
          //循环获取最少次数为1的数字或者字母,放进数组里
          let map = this.getStrMapLength(),arr = [];
          for(let i in map){
            if(map[i] === 1){
              arr.push(i)
            }
          }
          return arr || []
          console.log('次数最少的数组集合',arr)
        }

        //删除出现次数最少的字符串
        deletMinNumStr() {
          //解题思路: 获取到最少次数为1的字母或者数字的集合,通过循环替换的方式,删掉对应的字符串
          let arr = this.getMinArr();
          let copyRandomStr = this.randomString;
          for(let i of arr){
            copyRandomStr = copyRandomStr.replace(i,'');
          }
          return copyRandomStr
        }

        //删除复数出现的字符串
        getDeleteDoubleStr(str =''){
          //str为输入的测试用例,如果不传,则为上面生成的100个随机数列
          let copyRandomStr =  str||this.randomString;
          //使用正则去匹配重复字符
          let doubleArr = copyRandomStr.match(/(.)\1+/g);
          
          if(doubleArr == null){
            console.log('生成的字符中没有重复的,直接返回原随机数组');
            return copyRandomStr;
          }else{
            console.log('获取到的复数数组为',doubleArr)
            for(let i=0;i<doubleArr.length;i++){
              copyRandomStr = copyRandomStr.replace(doubleArr[i],'')
            }
            return copyRandomStr
          }
          
        }
      }

      let sortFuc = new SortClass();
    </script>
  </body>
</html>

输出结果

image.png