查找两个数的公因数的最有效方法

时间:2019-03-11 07:28:29

标签: go math

我有两个数字,例如数字是12和16。

  

12的因子是1、2、3、4、6、12

     

因子16是1,2,4,8,16

     

这两个数字的共同因素是1、2和4。

因此,公因数为3。我需要构建一个Go程序来查找两个数字的数公因数。但是程序应该是高效的,并具有最少的循环数或无循环数。 我将提供我的代码,您也可以使用另一种最佳方法做出贡献并提出建议。

package main

import "fmt"

var (
    fs    []int64
    fd    []int64
    count int
)

func main() {
    commonFactor(16, 12)
    commonFactor(5, 10)
}

func commonFactor(num ...int64) {
    count = 0
    if num[0] < 1 || num[1] < 1 {
        fmt.Println("\nFactors not computed")
        return
    }
    for _, val := range num {
        fs = make([]int64, 1)
        fmt.Printf("\nFactors of %d: ", val)
        fs[0] = 1
        apf := func(p int64, e int) {
            n := len(fs)
            for i, pp := 0, p; i < e; i, pp = i+1, pp*p {
                for j := 0; j < n; j++ {
                    fs = append(fs, fs[j]*pp)
                }
            }
        }
        e := 0
        for ; val&1 == 0; e++ {
            val >>= 1
        }
        apf(2, e)
        for d := int64(3); val > 1; d += 2 {
            if d*d > val {
                d = val
            }
            for e = 0; val%d == 0; e++ {
                val /= d
            }
            if e > 0 {
                apf(d, e)
            }
        }
        if fd == nil {
            fd = fs
        }
        fmt.Println(fs)
    }
    for _, i := range fs {
        for _, j := range fd {
            if i == j {
                count++
            }
        }
    }
    fmt.Println("Number of common factors =", count)
}

输出为:

  

16的因素[1 2 4 8 16] 12的因数:[1 2 4 3 6 12]

     

公因子数= 3

     

5的因素:[1 5] 10的因数:[1 2 5 10]

     

公因子数= 2

Goplayground

2 个答案:

答案 0 :(得分:1)

答案1,没有循环,只是递归

SELECT t1.col1, t1.col2, t1.col3, j1.Cnt, /* same for j2 */
FROM table1 as t1
LEFT JOIN (select j_employee_id,j_week_ending,COUNT(j_id) AS Cnt
     from jointable1
     where j_reason <> 'DNC'
     group by j_employee_id,j_week_ending) j1
ON (t1.t_employee_id = j1.j_employee_id
    AND t1.t_week_ending = j1.j_week_ending)
/* Same again for j2 */
/* Don't need GROUP BY out here at all now? */

但是,这会以较大的数字爆炸,例如42512703

替换使用迭代版本的函子可以处理更大的数字

package main

import (
    "fmt"
    "os"
    "strconv"
)

func factors(n int, t int, res *[]int) *[]int {
    if t != 0 {
        if (n/t)*t == n {
            temp := append(*res, t)
            res = &temp
        }
        res = factors(n, t-1, res)
    }
    return res
}

func cf(l1 []int, l2 []int, res *[]int) *[]int {
    if len(l1) > 0 && len(l2) > 0 {
        v1 := l1[0]
        v2 := l2[0]
        if v1 == v2 {
            temp := append(*res, v1)
            res = &temp
            l2 = l2[1:]
        }
        if v2 > v1 {
            l2 = l2[1:]
        } else {
            l1 = l1[1:]
        }
        res = cf(l1, l2, res)
    }
    return res
}

func main() {
    n, err := strconv.Atoi(os.Args[1])
    n2, err := strconv.Atoi(os.Args[2])
    if err != nil {
        fmt.Println("give a number")
        panic(err)
    }
    factorlist1 := factors(n, n, &[]int{})
    factorlist2 := factors(n2, n2, &[]int{})
    fmt.Printf("factors of %d %v\n", n, factorlist1)
    fmt.Printf("factors of %d %v\n", n2, factorlist2)
    common := cf(*factorlist1, *factorlist2, &[]int{})
    fmt.Printf("number of common factors = %d\n", len(*common))

}

答案 1 :(得分:0)

func Divisors(n int)int{

prev := []int{}

for i := n;i > 0;i--{
    prev = append(prev,i)
}

var res int

for j := prev[0];j > 0;j--{
    if n % j == 0 {
        res++
    }
}

return res

}