查找数字的最接近因子

时间:2014-11-12 10:53:38

标签: java algorithm math

我正在尝试将最接近的数字因子的查找自动化到另一个数字;

示例:

最接近700到30的因子是28(30不是700,但是28)。

一个明显的解决方案就是得到700的所有因子并进行简单的距离计算以找到最接近30的因子,但这似乎是低效的。

另一个解决方案是找到所有基本素因子,例如:

private List<Integer> getPrimeFactors(int upTo) {
    List<Integer> result = new ArrayList<>();
    for (int i = 2; i <= upTo; i++) {
        if (upTo % i == 0) {
            result.add(i);
        }
    }
    return result;
}

将这些数字相乘以得到所有组合,从而找到最接近的数字。

我正在尝试编程,因此它是自动化的。 更好的解决方案?

5 个答案:

答案 0 :(得分:0)

您不需要计算所有因素,但您可以从数字两个方向找到最接近的数字,这是给定数字的因素

Pseduo代码将是:

n= given number(dividend);
x= second number( whose closest number is required)
i=0;
if(n%x==0) print x;
else
while(true){
   if(n%(x-i)==0){
      print x-i
      break 
   }
   else if(n%(x+i)==0){
     print x+i;    
       break 
   }
   else i=i+1
}

答案 1 :(得分:0)

    package dummy;

    public class test {

        public static void main(String[] args) {
            int factorOff = 700;
            int factorFrom = 30;
            for (int i = 2; i < factorOff; i++) {
                if (factorOff % (factorFrom + i) == 0) {
                    System.out.println(factorFrom + i);
                    i = factorOff;
                } else if (factorFrom - i > 1 && factorOff % (factorFrom - i) == 0) {
                    System.out.println(factorFrom - i);
                    i = factorOff;
                }
            }
        }
    }

答案 2 :(得分:0)

我的解决方案包含在一个小的静态方法中:

/**
* @param number the number you want the factor to be close to
* @param max the number you want the result to be a factor of
*/
private static int getClosestFactor(int target, int number) {
    for (int i = 0; i < number; i++) {
        if (number % (target + i) == 0) {
            return number + i;
        } else if (number % (target - i) == 0) {
            return target - i;
        }
    }
    return number;
}

答案 3 :(得分:0)

这应该是一个快速的解决方案:

public static int findClosestFactor(int number, int closeTo) {
    int result = 1;
    int currentDist = closeTo - 1;
    // stop conditions for comparison
    boolean compareSmallFactor = true;
    boolean compareLargeFactor = true;
    for (int factor1 = (int) Math.sqrt(number); factor1 > 0; factor1--) {
        if (number % factor1 == 0) {
            if (compareSmallFactor) {
                int dist1 = Math.abs(closeTo - factor1);
                if (dist1 < currentDist) {
                    result = factor1;
                    currentDist = dist1;
                }
                // factor 1 is getting always smaller
                // so you need not compare next time, if go away from target (smaller than target)
                if (factor1 <= closeTo) {
                    compareSmallFactor = false;
                }
            }

            if (compareLargeFactor) {
                int factor2 = number / factor1;
                int dist2 = Math.abs(closeTo - factor2);
                if (dist2 < currentDist) {
                    result = factor2;
                    currentDist = dist2;
                }
                // factor 2 is getting always larger
                // so you need not compare next time, if go away from target (larger than target)
                if (factor2 >= closeTo) {
                    compareLargeFactor = false;
                }
            }

            // if both factors go away from target, you can cancel
            if (!compareSmallFactor && !compareLargeFactor) {
                break;
            }
        }
    }
    return result;
}

答案 4 :(得分:0)

您可以对数字进行分解,然后使用powerset生成器(对于多集[1])来搜索最接近最大值的因子组而不会过度。

可以修改powerset生成器以防止进一步迭代超过所需值(分支和绑定)的分支。 IE:如果因素是(2,5,7,13,19)。该数字为80,您有2*5*7 = 70. 2 * 5 * 7 * 13 = 910。无需检查2 * 5 * 7 * 19,因为它会明显超过最大值

[1]将分解作为多重集处理是一个好主意。例如,在700, ((2,2),(5,2),(7,1))的情况下。您可以将其视为(2,2,5,5,7),但它会做额外的工作,因为不需要多次找到2 * 5 = 10,但如果它不是被视为多重集,那就会发生。