将标题首字母大写

269 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

一、题目描述:

给你一个字符串,它由单个空格连接一个或多个单词组成,每个单词都只包含英文字母。按照以下规则转换:

  • 如果长度小于等于 2,则我们将该单词全部转化为小写;
  • 如果长度大于 2,则我们将该单词首字母转化为大写,其余字母转化为小写。

输入:A beautiful GIRL 输出:a Beautiful Girl

二、思路分析:

根据题目的要求我们发现处理字符串最常用的是正则匹配,于是就写出了下面代码:

function capitalizeTitle(title) {
  let fixTitle = ' ' + title
  let lowTitle = fixTitle.toLowerCase().replace(/ ([a-z])/g, (a, b) => {
    return ' ' + b.toUpperCase()
  })
  return lowTitle.slice(1)
}
console.log(capitalizeTitle('A beautiful GIRL'))
// A Beautiful Girl

写完之后发现还是有问题,无法满足第一条规则(一个字母应该转换成小写)。那么就只能放方案了。

我们要处理字符串,但是字符串又不能直接修改,于是我们需要先把字符串转换为数组,就可以修改数组的每一项了,但是具体怎么修改呢?我们可以通过双指针的形式,l表示左边,r表示右边,r向右移动的时候发现是空格就要停止,需要处理左边的字母。

function capitalizeTitle(title) {
  let n = title.length
  let l = 0
  let r = 0
  let titleList = title.split('')
  titleList.push(' ') // 处理末尾的边界条件
  while (r < n) {
    while (titleList[r] !== ' ') {
      r++
    }
    if (r - l > 2) { // 规则2
      titleList[l] = titleList[l].toUpperCase()
      l++
    }
    while (l < r) { // 规则1
      titleList[l] = titleList[l].toLowerCase()
      l++
    }
    l = r + 1
    r++

  }
  titleList.pop()
  return titleList.join('')
}
console.log(capitalizeTitle('A beautiful GIRL'))

代码的执行流程是这样的:

l指针 r指针  字符
0    1     字符 A
2    11    字符 beautiful
12   16    字符 GIRL

四、总结:

双指针在算法中是非常常见,我们面试之前一定要掌握。比如:字节跳动面试算法题:将下划线命名转为驼峰命名。

function capitalizeTitle(title) {
  let n = title.length
  let l = 0
  let r = 0
  let titleList = title.split('')
  titleList.push('_')
  console.log(n, titleList.length) 
  while (r < n) {
    while (titleList[r] !== '_') {
      r++
    }
    if (l === 0) {
      titleList[l] = titleList[l].toLowerCase()
      l++
    } else {
      titleList[l] = titleList[l].toUpperCase()
      l++
    }
    while (l < r) {
      titleList[l] = titleList[l].toLowerCase()
      l++
    }
    l = r + 1
    r++

  }
  titleList.pop()
  return titleList.reduce((a, b) => {
    if (b !== '_') {
      return a + b
    }
    return a
  }, '')
}
console.log(capitalizeTitle('A_beautiful_GIRL'))
// aBeautifulGirl

关于驼峰转换为下划线其实通过正则就可以简单的完成

function change (title) {
  return title.replace(/[A-Z]/g, (a) => {
    return '_' + a.toLowerCase()
  })
}

console.log(change('aBeautifulGirl'))
// a_beautiful_girl

掌握了原理之后使用起来都相当简单了,需要注意的是边界情况,为了处理最后一个字符,通常会在最后面添加特殊符号方便处理。