仿写一个任意进制转任意进制方法

2020-11-04  本文已影响0人  名侦探柯妍

本帖仅为日常算法练习总结,若有更好的算法欢迎留言分享。

1、先看下js原生方法

function main(num,m,n){
  const s = num+'';
  return parseInt(s,m).toString(n); // parseInt将任意进制转为10进制,再用toString转为任意进制
}

2、先准备一个工具方法将16、36等进制中的字母转成对应值,或将值转换为对应字母。

function getLetterAndAsciiValue(current) {
  // 进制的值对应的字母
  if (/\d/.test(current)) {
    if (Number(current) < 10) return String(current);
    return String.fromCharCode((Number(current) + 55));
  }
  // 进制的字母对应的值
  return String(current.toUpperCase().charCodeAt() - 55);
}

3、写一个方法将任意进制转成10进制

function fromAnyToTen(number, m) {
  const numStr = String(number);
  let sor = 0;
  Object.keys(numStr).forEach(key => {
    sor += Number(getLetterAndAsciiValue(numStr[key])) * Math.pow(m, numStr.length - key - 1);
  });
  return sor;
}

测试一下

console.log(fromAnyToTen(101111, 2), 'from any to ten');
console.log(parseInt(101111, 2), 'by js');
image.png

ok 没问题。。。

4、写一个方法将10进制转换成任意进制

这里我用了递归的方式计算(思路跟数学中的算法一样)

function fromTenToAny(numStr, n) {
  const number = Number(numStr);
  const content = Math.floor(number / n) >= n ? fromTenToAny(Math.floor(number / n), n) : '' + getLetterAndAsciiValue(Math.floor(number / n));
  return content + getLetterAndAsciiValue(number % n);
}

测试一下 2进制和36进制

console.log(fromTenToAny(47, 2), 'from ten to any');
console.log((47).toString(2), 'by js');
console.log(fromTenToAny(78999, 36), 'from ten to any');
console.log((78999).toString(36), 'by js');
image.png

ok 没问题 我们整合一下方法。

5、整合一个从任意进制转换成任意进制的方法

function parseMToN(num, m, n) {
  if (m === n) return num;
  // m为当前进制,转为n进制

  function fromAnyToTen(number) {
    const numStr = String(number);
    let sor = 0;
    Object.keys(numStr).forEach(key => {
      sor += Number(getLetterAndAsciiValue(numStr[key])) * Math.pow(m, numStr.length - key - 1);
    });
    return sor;
  }

  function fromTenToAny(numStr) {
    const number = Number(numStr);
    const content = Math.floor(number / n) >= n ? fromTenToAny(Math.floor(number / n)) : getLetterAndAsciiValue(Math.floor(number / n));
    return content + getLetterAndAsciiValue(number % n);
  }
  // 转为10进制
  if (Number(n) === 10) return fromAnyToTen(num);
  // 10进制转其他进制
  if (Number(m) === 10) return fromTenToAny(num);
  // 非10进制转非10进制
  return fromTenToAny(fromAnyToTen(num));
}

测试一下

console.log(parseMToN('l2', 36, 2));
console.log(main('l2', 36, 2));

console.log(parseMToN('89B', 16, 36));
console.log(main('89B', 16, 36));
image.png
上一篇 下一篇

猜你喜欢

热点阅读