前端面试常考:字符串反转多种实现方案(reverse,reduce,递归,for of)

117 阅读6分钟

前言

通过背八股文和分析已入职和求职中的学长在面经交流群发的的大量面经发现,中大厂面试题并不是一定要很难,难度当然大,但更多的是考察基础是否扎实,还有就是面试过程当中的表达能力。那么好,这里就讲解两道大家容易忽视的基础题,以及该如何在面试当中进行表达。春招在即,所谓“金三银四”,各位大佬冲压。

字符串反转

面试官问你:用JS怎么实现字符串反转,有几种方案?

这时候,你脑海立马浮现的是reverse方法?但是你该怎么说给面试官听呢?肯定不能直接说用reverse方法,这样太模糊了,这也不是面试官想要的回答。而且你要知道JS当中reverse方法是数组的内置方法,字符串没有,所以你应该回答:我首先想到数组的reverse方法——将字符串转数组,然后调用reverse。这样回答就差不多了,虽然各位大佬都很熟悉这些知识点,但一定要表达到位。

function reverseStr(str) {
    // 类型检测
    if(typeof str !== 'string') {
        return 
    }
    // 数组有reverse 方法
    // 字符数组
    // 反转的字符数组
    // 变成字符串
    return str.split('').reverse().join('')
}

上面就是解决方案之一,相信大家都清楚,不过在面试的时候表达要到位,并且在敲代码的时候或快敲完的时候边说明:我先类型检测,不是字符串就直接返回,然后调用字符串的 split 方法,以空字符串作为分隔符,将传入的字符串 str 分割成一个字符数组,接着调用数组的 reverse 方法,将上一步得到的字符数组反转,调用数组的 join 方法,以空字符串作为连接符,将反转后的字符数组重新组合成一个字符串。

这些方法大家都很熟,但不一定表达清楚,要多开口,这样面试时就有话说,面试官也聊得开心,凭各位大佬的实力offer还不是十拿九稳,手到擒来(狗头)。

第二种实现:递归

第二种实现方法,绝对是面试亮点,能在面试中聊出来肯定加分项,说不定你的大厂offer就拿下了,年薪30W+,天哪一年赚够彩礼钱,立马相亲。

言归正传:先看代码

// 递归 ,自顶向下
// js api -> 算法
// 从api到算法的过程
function reverseString(str) {
    if ( str === '' ) {
        return ''; 
    } else {
        return reverseString(str.substr(1)) + str.charAt(0);
    }
}

console.log(reverseString('hello'));
  • 递归终止条件:当输入的字符串 str 为空字符串时,直接返回空字符串,因为空字符串反转后还是空字符串。

  • 递归步骤:对于非空字符串,通过 str.substr(1) 提取除第一个字符之外的剩余字符串,然后对剩余字符串递归调用 reverseString 函数进行反转。

  • 拼接结果:将递归调用得到的反转后的剩余字符串,与原字符串的第一个字符(通过 str.charAt(0) 获取)进行拼接。

  • 返回结果:重复上述步骤,直到满足递归终止条件,最终返回完整的反转字符串。

之所以是亮点是因为它是从API到算法的一种实现方式,逻辑上,它将大问题(反转整个字符串)拆解为小问题(反转部分字符串),通过不断递归缩小问题规模,直到达到终止条件。代码结构清晰,易于理解。这也能突出你的算法能力和对递归的深度理解。

第三种:使用 reduce 方法 这也是亮点,主要体现在 :使用 reduce 方法可以在一行代码中实现字符串反转,代码量少。 符合函数式编程的理念,强调使用纯函数和不可变数据这里还用到扩展运算符... ,以及reduce是高阶函数,你又能聊一聊高阶函数,这不面试就有东西聊了,你占据一些主动权,能自由输出自己比较懂得点,而不是一直等着面试官严刑拷打你才说。

function reverseStr(str) {
    // return [...str].reverse().join('')
    // reduce es6 api 
    return [...str].reduce((reversed,char) => char + reversed,'')
}

console.log(reverseStr('hello'));


  • 将字符串转换为数组:利用扩展运算符 ... 将传入的字符串 str 转换为字符数组。这样做是因为 reduce 是数组的方法,需要对数组进行操作。
  • 调用 reduce 方法:对转换后的字符数组调用 reduce 方法。reduce 方法接收两个参数,第一个参数是一个回调函数,第二个参数是初始值。
  • 定义回调函数:回调函数接收两个参数,reversed 表示累积的结果,也就是当前已经反转好的部分字符串;char 表示当前正在处理的字符。
  • 执行回调函数:在回调函数中,将当前字符 char 拼接到 reversed 字符串的前面,更新 reversed 的值。
  • 设置初始值:初始值设置为空字符串 '',作为反转字符串的起始点。
  • 返回结果reduce 方法会遍历数组中的每个字符,依次执行回调函数,最终返回累积的结果,即反转后的字符串。

那这里呢多提一嘴,帮助大家更好理解reduce方法,

reduce 是 JavaScript 数组对象的一个高阶函数,它用于对数组中的每个元素执行一个自定义的累加器函数,并将结果汇总为单个值。

array.reduce(callback(accumulator, currentValue, currentIndex, array), initialValue)
  • callback:用于处理数组每个元素的函数。

    • accumulator:累加器,存储上一次调用 callback 的返回值,或初始值 initialValue
    • currentValue:当前正在处理的数组元素。
    • currentIndex(可选):当前元素的索引。
    • array(可选):调用 reduce 的原始数组。
  • initialValue(可选):accumulator 的初始值。若未提供,accumulator 初始为数组第一个元素,currentValue 从第二个元素开始。


const numbers = [1, 2, 3, 4, 5];

// 使用 reduce 方法对数组元素进行累加
const sum = numbers.reduce(
  // 回调函数,用于处理累加逻辑
  (accumulator, currentValue) => {
    // 打印当前的累加器值和当前处理的元素值
    console.log(accumulator, currentValue, '-------');
    // 返回累加结果,作为下一次迭代的累加器值
    return accumulator + currentValue;
  }
);

console.log(sum);

image.png

第四种:for of 遍历拼接 这种方案:代码逻辑直观,很容易理解:就是遍历每一项然后将当前字符 char 拼接到 reversed 字符串的前面,直到循环结束就OK了。

function reverseStr(str) {
    let reversed = '';
    for ( const char of str){
        reversed = char + reversed;
    }
    return reversed;
}
console.log(reverseStr('hello'));

基本呢就这些,倒序输出就不多嘴了想必大家了如指掌,到这就结束了,提供了四种方案,都是很不错的方案,大家在面试的时候一定要表达清楚,不能模棱两可,平时多练练表达能力,很多知识大家都懂,就是表达上要改进一下。(当然这只是建议,不喜勿喷)。

image.png