JS求最大公约数

背景介绍

Vue2.x项目上有这样的要求,上传指定比例的图片,然后给一个提示给用户,比如图片是375x250,最终比例就是5:3,因为375*250会在很多页面用到,就通过混入复用了,但是,提示还是直接黏贴原型图里的。

虽然后续改了大小,尝到了封装的甜头,可比例却不是自动更新的...

实现一

首先想到的就是穷举了

function getRaioStr(...rest: number[]) {
  const list = [...rest];
  const min = Math.min(...list);
  for (let i = 1; i <= min; i++) {
    const allow = list.every((item) => item / i === parseInt(item / i + ''));
    if (allow) {
      list.forEach((item, index, arr) => (arr[index] = item / i));
    }
  }
  const str = list.join(':');
  return str;
}

明显计算了很多次

function getRaioStr(...rest: number[]) {
  let list = [...rest];
  const min = Math.sqrt(Math.min(...list));
  for (let i = 2; i <= min; i++) {
    const tempList: number[] = [];
    const allow = list.every((item) => {
      let number = item / i;
      if (number === parseInt(number + '')) {
        tempList.push(number);
        return true;
      }
      return false;
    });
    if (allow) {
      list = tempList;
    }
  }
  const str = list.join(':');
  return str;
}

看似正确,其实有个致命的问题

getRaioStr(8, 4)
// 4:2
getRaioStr(375, 250));
//75:50

出现一个公约数后,要重置循环标记和最小值

function getRaioStr(...rest: number[]) {
  let list = [...rest];
  let min = Math.sqrt(Math.min(...list));
  for (let i = 2; i <= min; i++) {
    const tempList: number[] = [];
    const allow = list.every((item) => {
      let number = item / i;
      if (number === parseInt(number + '')) {
        tempList.push(number);
        return true;
      }
      return false;
    });
    if (allow) {
      i = 1;
      min = Math.sqrt(Math.min(...list));
      list = tempList;
    }
  }
  const str = list.join(':');
  return str;
}

也可以从大往小循环

辗转相除法

辗转相除法又名广义欧几里得除法,是用来求解两个数的最大公约数的最佳算法之一。
算法原理:若a除以b的余数为r , 则有 (a , b) = ( b ,r ) ((a,b)表示a和b的最大公约数)

function getRaioStr(...restList: number[]) {
  let arrList = [...restList];
  function gsy(m: number, n: number): number {
    return m % n == 0 ? n : gsy(n, m % n);
  }
  while (arrList.length > 1) {
    arrList.push(gsy(arrList.pop(), arrList.pop()));
  }
  const num = arrList[0];
  const result = restList
    .map((item, i, arr) => (arr[i] = item / num))
    .join(':');
  return result;
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容