1.写一个js函数,实现给出一个数字每三位加一个逗号,如输入100000,输出100,000,不考虑负数和小数。 (百度前端面试题)
解法一:
分析:
其实这是number.toLocaleString()输出的结果,包括负数和小数(小数保留三位有效数字)
var num1 = 1234567;
var num2 = -1234567;
var num3 = 1234.5678;
console.log(num1.toLocaleString()) //1,234,567
console.log(num2.toLocaleString()) //-1,234,567
console.log(num3.toLocaleString()) //1,234.568
解法二:
分析:
1234567
使用正则匹配,/((?<=\d)\d{3})+\b/g
匹配到3n的字符串234567
,用/\d{3}/g
匹配到234
和567
,使用数组的map
方法转换成,234,567
,与剩余的1
进行拼接
function getNum(num) {
if(!num) return
let str = parseInt(num).toString()
let re1 = /((?<=\d)\d{3})+\b/g
let re2 = /\d{3}/g
let str1 = str.match(re1)[0] //'234567'
let str2 = str1.match(re2).map((el, index)=> {
return ',' + el
}).join('') //',234,567'
let str3 = str.replace(str1, '') //'1'
return str3 + str2
}
getNum(1234567) //'1,234,567'
解法三:
主要利用到string.slice(-3)依次获取字符串的后三位并存到一个新数组中,
递归直至string的长度小于3,这时候数组存放的是一个个倒序的三位字符串(除了最后一个元素),
然后利用array.reverse().join(',')转换成我们需要的字符串
function toBeLocaleString(num = Number) {
let str = parseInt(num).toString()
let arr = []
s(str, arr)
console.log(arr.reverse().join(','))
}
function s(str = String, arr = Array) {
let strLen = str.length
let arrLen = arr.length
if (strLen > 3) {
arr[arrLen] = str.slice(-3)
str = str.slice(0, - 3)
s(str, arr)
}else {
arr[arrLen] = str
}
}
toBeLocaleString(1234567) //
解法四:
分析:对数字直接操作,链式调用不同数据类型操作的API,返回所需的结果,注意链式调用时每一步的返回值
function localeStr(num) {
if(!num) return
return num
.toString()
.split('')
.reverse()
.map((item, index) => {
return index !=0 && index % 3 === 0 ? `${item},` : item
})
.reverse()
.join('')
}
localeStr(1234567) //'1,234,567'
2.给定一个字符串,找出其中无重复字符的最长子字符串的长度(字节跳动前端面试题)
解法一:
分析:
比如字符串为abcdebcdx
,我们在找这段字符串的不重复的最长子字符串的时候,是从开头第一个元素开始往后遍历,如果发现位置index
处的字符str
跟已经遍历的字符串重复,我们就把之前遍历的重复处的字符repeatStr
去掉,从后一位开始组成我们的无重复子字符串resultStr
,for
循环到字符串的长度totalStrLen
结束。
function filter(str = String) {
let strLen = str.length
let newStr = ''
let newStrLen = Number
for (let i = 0; i < strLen; i++) {
//_str为str中i处的字符
let _str = str.charAt(i)
//index为_str在新字符串中的索引值,如果值为-1,则表示未重复
let index = newStr.indexOf(_str)
if (index === -1) {
newStr += _str
newStrLen = newStrLen > newStr.length ? newStrLen : newStr.length
} else {
newStr = newStr.substr(index+1) + _str
}
}
return newStrLen
}
filter('abcdedaxab') //5
3.实现超出整数范围的两个大正整数相加(腾讯面试题)
分析:
每种数据类型都是有存储范围的
Number.MAX_VALUE = 1.7976931348623157e + 308
Number.MIN_VALUE = 5e - 324
整数类型范围为:-2的负53次方 - 2的53次方
在超出整数范围时,我们采用其他方式运算。首先,我们将两个整数变成相同位数的字符串,将较小的那个前面添加0占位,并逆排序。然后运用数组的方式将两个数组里面的元素对应相加,注意进位,生成新的数组,再将新的数组转换成字符串,最后反转字符串。
function addBigInt (a, b) {
let n1 = a.length
let n2 = b.length
let n = Math.max(n1, n2) - Math.min(n1, n2)
let nMax = Math.max(n1, n2)
//将两个字符串变成相同位数
for (let i = 0; i < n; i++) {
if (n1 > n2) b = '0' + b
if (n1 < n2) a = '0' + a
}
//将字符串变成数组并逆排序
let arr1 = a.split('').reverse()
let arr2 = b.split('').reverse()
//生成项数为nMax,各项为0的数组
let arr = Array.apply(this, Array(nMax)).map((item, index) => {
return 0
})
//进位+1,保存到后一位数中
for (let j = 0; j < nMax; j++) {
let addNum = Number(arr1[j]) + Number(arr2[j])
if (addNum > 9) {
arr[j] += addNum - 10
arr[j + 1] = 1
} else {
arr[j] += addNum
}
}
return arr.reverse().join('')
}
let a = '123456789'
let b = '56789'
addBigInt(a, b) //'123513578'
4.计算出字符串中出现次数最多的字符是什么,出现了几次?(华为面试题)
解法一:
分析:我们可以通过正则的match
方法获取某个字符重复的次数,然后使用replace(re, '')
方法,将已经检测过的重复字符用空字符串去掉,re
指的是某个字符,最后比较哪个字符重复的次数最多就可以了。
function getRepeatStr(str) {
let count = 0
let char = ''
let strLen = str.length
while(str) {
let tempChar= str.charAt(0)
let re = new RegExp(tempChar, 'g')
let tempCount = str.match(re).length
if(tempCount > count) {
count = tempCount
char = tempChar
}
str = str.replace(re, '')
}
if (!str) return {count, char}
}
getRepeatStr('sddffgghhjknvbgghffrrrrrr') //{count: 6, char: 'r'}
解法二:
分析:
利用Array.filter((el, index, array) => {})
去重字符串,保存到新数组,遍历字符串,然后使用string.split(arr[i]).length - 1
获取每个字符的个数,比较得到最多的那个字符和个数。
function getRepeatStr2(str) {
let count = 0
let char = ''
let arr = str.split('')
let noRepeatArr = arr.filter((el, index, array) => {
//输出第一次出现的字符
return array.indexOf(el) === index
})
//利用noRepeatArr里的字符分割str,得到的数组长度-1就是每个字符重复的个数
let len = noRepeatArr.length
for (let i = 0; i < len; i++) {
let tempChar = noRepeatArr[i]
let tempCount = str.split(tempChar).length -1
if (tempCount > count) {
count = tempCount
char = tempChar
}
}
if (char) return {char, count}
}
getRepeatStr2('aaadfffghhjjkkkkkkk') // {char: 'k', count: 7}
5.公司最近新研发了一种产品,共生产了n件。有m个客户想购买此产品,已知每个顾客出价。为了确保公平,公司决定要以一个固定的价格出售产品。每一个出价不低于要价的顾客将会得到产品(每人只买一个),余下的将会被拒绝购买。请你找出能让公司利润最大化的售价。(京东前端面试题)
分析:
假设顾客出价为[2, 8, 7, 10],利润就等于我们的售价price * (比这个售价高的顾客个数),比如售价为2,利润就等于 2 * 4 = 8;售价为7,利润就等于7 * 3 = 21,所以只要比较这个售价 * 该售价以上的顾客数这个值,取最大值的售价即时我们的售价,注意考虑n < m的情况,供不应求时,我们需要截取出价高的顾客出价。
function getBestPrice (n, arr) {
let m = arr.length
let bestPrice = 0
let maxProfit = 0
if (n < m) {
arr = arr.slice(m - n) //截取出价高的人 arr.length === n
}
arr = arr.sort((a, b) => {
return a-b //需对价格进行升序排列
})
let len = arr.length
for (let i = 0; i < len; i++) {
let price = arr[i]
let profit= price * (len - i)
if (profit > maxProfit) {
maxProfit = profit
bestPrice = price
}
}
if (bestPrice) return {bestPrice, maxProfit}
}
getBestPrice(3, [2, 8, 7, 10]) //
6.'123456789876543212345678987654321...'的第n位是什么?(小米面试题)
分析:
可以看到循环体为'1234567898765432',利用数学的最小循环节解,用n除于循环节的余数求解
function getNum (n, str) {
return str.charAt(n % str.length -1)
}
getNum (20, '1234567898765432') //
7.请编写一个Javascript函数parseQueryString,它的用途是把url参数解析为一个对象。(淘宝面试题)
分析:
本题主要是知道url的参数是通过什么分割的,首先用?分割,然后用&分割,最后用=分割
function parseQueryString (url) {
let obj = {}
let key = ''
let value = ''
let arr = url.split('?')[1].split('&')
arr
.map((el, index) => {
return el.split('=')
})
.forEach((el, index) => {
key = el[0]
value = el[1]
obj[key] = value
})
return obj
}
parseQueryString('https://imooc.com?user=Mike&age=27&sex=male')
//{user: "Mike", age: "27", sex: "male"}
8.如果给定字符串是回文,返回true;反之,返回false。回文:如果一个字符串忽略标点符号、大小写和空格,正着读和反着读一模一样,那么这个字符串就是palindrome(回文)。(网易前端面试题)
分析:
首先利用正则去除掉标点符号和空格,将字符串变成小写,然后将字符串转换成数组,利用数组的反转,再转换成新的字符串同原来字符串比较是否一致。
function palindrome (str) {
let re = /[^0-9a-zA-Z]/g
let newStr = str.replace(re, '').toLowerCase() //获取小写后的无标点和空格的字符串
let reverseStr = newStr.split('').reverse().join('') //反转字符串
if (reverseStr === newStr) {
return true
} else {
return false
}
}
palindrome(' -- +=123?ua --*% A-u=3@21') //true
9.确保字符串的每个单词的首字母都大写,其余部分小写。
分析:
利用正则直接筛选出每个单词,再将所得数组每个元素变成小写,每个元素的第一个字符变成大写,最后还原成字符串。
function titleCase (str) {
let re = /\S+/g
let arr = str.match(re)
let newArr = arr.map((el, index) => {
let lowerEl = el.toLowerCase()
let upperEl = lowerEl .charAt(0).toUpperCase()
return upperEl + lowerEl.substr(1)
})
return newArr.join(' ')
}
titleCase("I'm a good boy.\n Ok!") //"I'm A Good Boy. Ok!"
网友评论