【算法基础】近期接触的一些JS基础算法题总结---求乘法持久性

199 阅读3分钟

从 20 年 4 月开始学习开始至今已有一年余,虽然没有多用功,但也不算浑浑噩噩。

遇到的困难很多,也很多次想放弃。

但是我都从养猪转职到码农来了,每次难以继续的时候想到这一点,就感觉这个坎好像也就那么回事。

不妨先收起退堂鼓再试一试。


题目: 编写一个函数persistence,它接受一个正参数number并返回其乘法持久性。

乘法持久性 : 一个数字中各个位的数字相乘,其得数若超过一位,则再次进行相乘,直到乘积为个位数为止时,所乘的次数。

例:

 persistence(39) === 3 // 因为 3*9 = 27, 2*7 = 14, 1*4=4
                       // 4为最终结果,共相乘3次。
                 
 persistence(999) === 4 // 因为 9*9*9 = 729, 7*2*9 = 126,
                        // 1*2*6 = 12,  1*2 = 2
                        // 2为最终结果,共相乘4次
                  
 persistence(4) === 0 // 因为 4 已经时只有一位的数字了,共相乘0次

首先需要能够求出参数各位的积,通常来说最简单的笨办法是将参数转为一个数组,将数组中的各项相乘。


   function persistence(number){
       let arr = String(number).split('')
        // 将参数第一位赋值给product
        let product = Number(arr[i])
        // 从第二项开始乘起,因为第一项已经赋值给product了
       for(let i=1;i<arr.length;i++){
           product *= Number(arr[i])
       }
   }

但是我们的目的实际上不光是求出积,而是为了得到做乘法的次数,所以实际上我们需要的不仅是运算的结果,还需要一个计数器。

(参数本身也需要一个验证,在判断数字位数大于1时才会进行运算,否则直接return 0就可以了。)

   function persistence(number){
       let arr = String(number).split('')
       // 将上一次乘积的第一位赋值给product
       let product = Number(arr[i])
       let counter = 0
       // 从第二项开始乘起,因为第一项已经赋值给product了
       if(String(Number).length>1){
           for(let i=1;i<arr.length;i++){
           product *= Number(arr[i])
           }
       }else{
           return 0
       }
   }

接下来需要琢磨在得到积之后应该做什么。

首先,只要成功得出积,就应将计数器 +1 (counter += 1

然后继续判断它们的积: product 是否只有一位,若不是,则需要再次进行相同的步骤,如果是,则可以输出counter作为结果了。

if(String(product).length >1){
     counter += 1
    // 这里需要一些代码来重复上面的步骤
}else{
     counter += 1
     return counter
}

最后,只需要再次判断及做乘法的步骤就可以了。

显然这里很适合使用递归---用一个新的函数将上面的方法包起来,在符合继续运算的条件时,将本次算出来的积作为参数,再次调用该方法本身,直至拿到我们需要的结果。

function persistence(number) {
    // 不知道新方法叫什么,就叫它 rua 吧,rua~
    function rua(number){
        if(String(number).length>1){
        let arr = String(number).split('')
        // 将上一次乘积的第一位赋值给product
        let product = Number(arr[i])
        let counter = 0
        // 从第二项开始乘起,因为第一项已经赋值给product了
        for(let i=1;i<arr.length;i++){
            product *= Number(arr[i])
        }
        if(String(product).length>1){
            counter += 1
            return rua(product)
        }else{
            counter += 1
            return counter
        }
    }else{
        return 0
    }
}
    return rua(number)
}

大功告。。并没有大功告成

我发觉输出的结果只有01,为什么?

因为计数器counter的值并没有被保存下来,每次再重新调用函数rua的时候,counter都被重新赋值为0了

所以我们要将计数器的值像积一样,通过参数传到下一次执行时。

function persistence(number) {
    function rua(number,n){
        // 在方法开始执行的时候,将上次计数器得到的值赋值给counter,并将它传入下一次方法执行时
        // 这样计数器的值就能够被保存下来了
        let counter = n
        if(String(number).length>1){
        let arr = String(number).split('')
        let product = Number(arr[i])
        // 从第二项开始乘起,因为第一项已经赋值给product了
        for(let i=1;i<arr.length;i++){
            product *= Number(arr[i])
        }
        if(String(product).length>1){
            counter += 1
            return rua(product,counter)
        }else{
            counter += 1
            return counter
        }
    }else{
        return 0
    }
}
    // 计数器初始值为 0
    return rua(number,0)
}

这样就可以得到一个数字的乘法持久性了。

本文主要为了记录我的一些思路,实际上并没有做代码优化,看起来很乱。。今天将思路分享给大家,如果能够帮到你,那我也算没白学。

写方法时不要总想着一步到位,看到复杂需求的时候一定要拆的尽可能细,也许有时候看到某位大佬的方法简洁明了,那多数也是大佬优化打磨后的结果。