找到列表中所有数字因子的最小整数

时间:2014-02-10 06:42:32

标签: algorithm list math numbers

有没有办法从列表中找到N个数字的最大公约数。

例如: 有一个像4,24,64,80,40,1264这样的列表......我想要一个方法,我可以在列表中找到最大公约数。在上面的例子中,它是最大公约数4。我想要的是一个动态解决方案,在列表上工作并给出价值。 (整数除以列表的所有数字而不给出提醒)

解决方案可以是任何语言,C#最好(利用Linq)。

PS: 很抱歉,如果您认为这属于math.stackexchange.com,我实际上对于要发布的内容感到困惑。

编辑:对不起我最初使用LCD的无知。

5 个答案:

答案 0 :(得分:2)

最小公倍数函数(LCM)是关联和可交换的。因此,您只需执行以下操作即可计算n个数组A的LCM。

k = 1
for i = 1..n
    k = LCM(k, A[i])

现有的LCM算法。见这里:http://en.m.wikipedia.org/wiki/Least_common_multiple

答案 1 :(得分:1)

我认为你想要的是Greatest Common Divisor(GCD)而不是Least Common Multiple(LCM)。您的示例的GCD和LCM应分别为475840

您可以按prime factorization获取数字列表的GCD和LCM。它可以编码为动态解决方案(通过记录每个素因子的最小和最大指数)。以列表为例:

4 = 2^2
24 = 2^3 * 3
64 = 2^6
80 = 2^4 * 5
40 = 2^3 * 5
1264 = 2^4 * 79

因此GCD为2^2 = 4,LCM为2^6 * 3 * 5 * 79 = 75840

答案 2 :(得分:1)

执行以下操作: -

  
      
  1. 在列表中找到最小的数字S.
  2.   
  3. 找到S的所有主要除数。
  4.   
  5. 对于每个素数pi找到xi = minimum(k1,k2,k3,...)其中ki是pi的幂,数量为arr [i]
  6.   
  7. GCD = x1 * x2 * .. xk
  8.   

注意:你可以在3中的任何迭代时停止。当ki = 1时,因为它将是最小的。

Java实施: -

public static long lgcd(long[] arr) {

        long min = arr[0];

        for(int i=0;i<arr.length;i++) {
            if(min>arr[i]) {
                min = arr[i];
            }
        }

        ArrayList div_primes = new ArrayList();
        boolean isPrime[] = new boolean[(int)Math.sqrt(min)+1];
        for(int i=0;i<isPrime.length;i++)
            isPrime[i] = true;

        for(int j=2;j<isPrime.length;j++) {
            if(isPrime[j]) {
                int x = 2*j;
                if(min%j==0) {
                    div_primes.add(j);
                } 
                for(;x<isPrime.length;x=x+j) {
                    isPrime[x] = false;
                }
            }
        }

        if(div_primes.size()<1) {
           div_primes.add(min);
        }

        long gcd = 1;

        for(int i=0;i<div_primes.size();i++) {
            long curr = (Integer)div_primes.get(i);
            long x = min;
            for(int j=0;j<arr.length;j++) {
                long acc = arr[j];
                long fact = 1;
                while(acc>1&&acc%curr==0) {
                    acc = acc/curr;
                    fact = fact*curr;
                }
                x = Math.min(x,fact);
                if(fact==1)
                    break;
            }
            gcd = gcd*x;
        }
        return(gcd);
    }

时间复杂度:

  
      
  1. 素数以O(sqrt(S))
  2. 计算   
  3. 总素数除数为O(log(S))
  4.   
  5. GCD计算: - O(log(S)* N)
  6.   

修改:忘记添加最小数字本身为素数的边案例,以便在代码后添加

if(div_primes.size()<1){
            div_primes.add(min);
        }

答案 3 :(得分:0)

你可以这样简单地简短列表,然后运行一个循环,它将访问每个值,并在每个成功除法后的内循环递增计数器中将列表中的所有其他值除以,然后将先前计数与当前外部的当前计数进行比较内循环然后如果当前计数较小则存储实际值。希望这可以解决你的问题

答案 4 :(得分:0)

GCD和LCM都是这样计算的:

  • 在素数中解析列表中的每个元素。为60 = 2 ^ 2 * 3 * 5。将这些素数表示写为向量。如60 =(2,1,1,0,0,..)
  • 对于GCD,在所有表示中找到相同位置的最小值。对所有职位重复。
  • 对于LCM,它将是最大值。
  • 将这些表示形式转回素数并将它们重新变回。

我记得,这是学校六年级的课程。 (12岁 - 孩子)