前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >就因为这道题,面字节差点儿就寄了...

就因为这道题,面字节差点儿就寄了...

作者头像
前端胖头鱼
发布2024-02-28 17:31:33
930
发布2024-02-28 17:31:33
举报
文章被收录于专栏:胖头鱼学前端胖头鱼学前端

1.# 62进制的大数相加

代码语言:javascript
复制

// 实现两个62进制数的大数加法
// 输入:两个 62 进制数,String 类型,仅考虑整数
// 输出:两数之和,String 类型
// 62 进制数:按照 1-9,a-z,A-Z 递增

function sum (a, b) {}

不知道你们看到这道题时是什么感受!!!

我当时的想法是:“好像只听过2进制、8进制、16进制、32进制,62进制是什么鬼?

终于在看到这段信息后恍然大悟:62 进制数:按照 1-9,a-z,A-Z 递增

我掰着手加脚指头数了数...

  1. 0 ~ 9 是10个数
  2. a ~ z 是26个字母
  3. A ~ Z 是26个字母

加起来就是62个数,刚好凑齐62进制。

1.1 10进制大数相加(整数)

突然看到求62进制的两数之和,我内心多少是有点懵逼的,懵逼的点在哪?

就是字母咋相加啊?比如 1a(10进制的72) + 2 = 1c(10进制的74)

不过作为接受过9年义务教育的社会主义接班人,一年级咱们就学会了加法(也就是所谓的10进制加法)

回顾一下小学知识: 19 + 23?

代码语言:javascript
复制
1. 个位数相加:9 + 3 = 12。写下 2,进位 1。
  19
+ 23
-----
   2
   
2. 十位数相加并加上进位:1 + 2 + 1(进位)= 4。
  19
+ 23
-----
  42

非常简单是不是?咱们尝试一下用程序来计算两个10进制数的加法。

别担心,朋友,这段代码虽然看起来长了点,但它完全模拟的小学加法,很容易看懂。

敲黑板:10进制的大数相加也是面试的热点

代码语言:javascript
复制
const addBigNumbers = (a, b) => {
  // 从尾部往前计算
  let i = a.length - 1
  let j = b.length - 1
  // 进位标志,1或者0
  let carry = 0
  let result = ''

  while (i >= 0 || j >= 0 || carry) {
    const n1 = +(a[ i ] || 0)
    const n2 = +(b[ j ] || 0)
    // 当前位相加(包含进位部分)
    let sum = n1 + n2 + carry
    // 当前位相加如果>=10,说明要往前进1,否则要重置进位标志
    if (sum >= 10) {
      sum -= 10
      carry = 1
    } else {
      carry = 0
    }
    // 递减往前算
    i--
    j--
    // 当前位 + 前面低位的结果
    result = sum + '' + result
  }

  return result
}

console.log(addBigNumbers('19', '23')) // 42
console.log(addBigNumbers('100', '1024')) // 1124

1.2# 62进制与10进制之间如何转换?

其实咱们知道如何实现10进制大数相加之后,62进制的大数相加也就完成了一大半,只要解决这2个问题,面试官就该给你过了。

  1. 62进制转化为10进制
  2. 10进制转化为62进制

想想只要能将62进制转化为10进制进行相加,再把结果转化为62进制,问题不就迎刃而解了吗?

代码语言:javascript
复制
1a (10进制的72) + 2 = 1c (10进制的74)

1.3# 62进制转化为10进制

让我们一起来回顾一下计算机基础知识:62进制转化为10进制的规则

设 62 进制数为 d[n]d[n-1]...d[1]d[0],其中 d[i] 表示第 i 位的数字(从右向左,最低位为0)。

则该数的十进制值为:

代码语言:javascript
复制
d[0] * 62^0 + d[1] * 62^1 + ... + d[n] * 62^n

举个例子

代码语言:javascript
复制
1a = 1 * 62^1 + 10 * 62^0 // 62进制中的a代表10进制中的10,b代表的是11以此类推
   = 1 * 62 + 10 * 1
   = 62 + 10
   = 72

有了这个规律用代码实现就很方便了.

代码语言:javascript
复制
const base62ToDecimal = (str) => {
  const base = 62
  const digits = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
  let len = str.length
  let sum = 0
  let n =0 // 最后一位是0,倒数第二位是1...

  while (len--) {
    let digit = digits.indexOf(str[ len ]) // 获取当前位的10进制数,例如a表示10进制的10,b表示11,c表示12...
    sum += digit * Math.pow(base, n)
    n++
  }

  return sum
}

// 示例
console.log(base62ToDecimal('1a')) // 72
console.log(base62ToDecimal('1c')) // 74

1.4# 10进制转化为62进制

同样 10进制转化为62进制也有规律可言:

  1. 用输入的十进制数除以 62,得到商和余数。
  2. 将余数对应的 62 进制字符放在结果的最低位。
  3. 将商作为新的输入,重复步骤 1 和 2,直到商为 0。
  4. 将得到的所有余数按照逆序排列,就是最终的 62 进制表示。

举个例子: 将10进制的72转化为64进制是啥?

代码语言:javascript
复制

第一步,将 72 不断除以 62,得到的余数就是 62 进制数的低位数字。依次计算如下:

1. 72 ÷ 62 = 1 ... 10 (余数为 10,10对应的62进制字符为 'a')
2. 1 ÷ 62 = 0 ... 1 (余数为 1,1对应的62进制字符为 '1')

第二步,将每次得到的余数按照逆序排列,就是最终的62进制表示:

72(10进制)= '1a'(62进制)

根据规律聪明的你也能很快用程序来实现10进制到62进制的转换

代码语言:javascript
复制
const decimalToBase62 = (decimal) => {
  const base = 62
  const digits = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
  let result = []

  while (decimal > 0) {
    const remainder = decimal % base // 取余

    result.push(digits[ remainder ]) // 将余数真正对应62进制字符存入数组

    decimal = Math.floor(decimal / base) // 计算商,用于下次计算
  }

  return result.reverse().join('') || '0' // 反转结果
}

console.log(decimalToBase62('72')) // 1a
console.log(decimalToBase62('74')) // 1c

1.5 解题啦!!!

啰嗦了这么多,大家有没有发现解决62进制大数相加所需的知识点实在是太基础了

  1. 会小学加法
  2. 会进制转换

最后请丢出这份代码,亮瞎面试官的眼吧!!!

代码语言:javascript
复制
// 62进制转10进制
const base62ToDecimal = (str) => {
  const base = 62
  const digits = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
  let len = str.length
  let sum = 0
  let n =0 // 最后一位是0,倒数第二位是1...

  while (len--) {
    let digit = digits.indexOf(str[ len ]) // 获取当前位的10进制数,例如a表示10进制的10,b表示11,c表示12...
    sum += digit * Math.pow(base, n)
    n++
  }

  return sum
}
// 10进制转62进制
const decimalToBase62 = (decimal) => {
  const base = 62
  const digits = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
  let result = []

  while (decimal > 0) {
    const remainder = decimal % base // 取余

    result.push(digits[ remainder ]) // 将余数真正对应62进制字符存入数组

    decimal = Math.floor(decimal / base) // 计算商,用于下次计算
  }

  return result.reverse().join('') || '0' // 反转结果
}


const addBigBase62Numbers = (a, b) => {
  // 转化为10进制的字符串
  a = '' + base62ToDecimal(a)
  b = '' + base62ToDecimal(b)

  // 从尾部往前计算
  let i = a.length - 1
  let j = b.length - 1
  // 进位标志,1或者0
  let carry = 0
  let result = ''

  while (i >= 0 || j >= 0 || carry) {
    const n1 = +(a[ i ] || 0)
    const n2 = +(b[ j ] || 0)
    // 当前位相加(包含进位部分)
    let sum = n1 + n2 + carry
    // 当前位相加如果>=10,说明要往前进1,否则要重置进位标志
    if (sum >= 10) {
      sum -= 10
      carry = 1
    } else {
      carry = 0
    }
    // 递减往前算
    i--
    j--
    // 当前位 + 前面的
    result = sum + '' + result
  }

  return decimalToBase62(result) // 将10进制再转化为62进制
}

console.log(addBigBase62Numbers('1a', '2')) // 1c
console.log(addBigBase62Numbers('Z', '1')) // 10

2.# 另一种解法

咱们废了老大劲,写了一大坨的代码才实现这个功能,有没有其他更简便一点的解法呢?

其实62进制的数学性质和10进制类似,只是基数(62)不同而已,在10进制中是逢十进一,62进制中就是逢62进一了。所以在我们知道10进制的大数相加如何解之后,仅仅需要做少量的修改就可以变成62进制的大数相加。

搞起!!!

代码语言:javascript
复制
const addBigBase62Numbers = (a, b) => {
  const digits = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
  let i = a.length - 1
  let j = b.length - 1
  let carry = 0
  let result = ''

  while (i >= 0 || j >= 0 || carry) {
    const n1 = digits.indexOf(a[i] || 0) // 获取当前位的10进制表示,如a表示10,b表示11 
    const n2 = digits.indexOf(b[j] || 0) // 获取当前位的10进制表示,如a表示10,b表示11 
    let sum = n1 + n2 + carry
    // 62进1
    if (sum >= 62) {
      sum -= 62
      carry = 1
    } else {
      carry = 0
    }
    // digits[sum] 将当前位转换回62进制
    result = digits[sum] + result

    i--
    j--
  }

  return result
}


console.log(addBigBase62Numbers('1a', '2')) // 1c
console.log(addBigBase62Numbers('Z', '1')) // 10

好舒畅、代码一下子少了一大坨,又可以和面试官吹牛逼了...

3.# 举一反三

文中我们只处理了整数的62进制大数相加,聪明你可以尝试一下这几种场景

  1. 带小数的62进制大数相加?
  2. n进制的大数相加?
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-02-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端胖头鱼 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.# 62进制的大数相加
    • 1.1 10进制大数相加(整数)
      • 1.2# 62进制与10进制之间如何转换?
        • 1.3# 62进制转化为10进制
          • 1.4# 10进制转化为62进制
            • 1.5 解题啦!!!
            • 2.# 另一种解法
            • 3.# 举一反三
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档