找到数字因子的方法

时间:2014-03-13 02:51:49

标签: java if-statement methods primes factors

我正在尝试编写一个简单的程序,它接受一个非素数并返回它的第一个因子。我必须使用一种方法来做到这一点。我认为我非常接近正确的代码,但我仍然在我的方法中遇到变量定义问题。这是我的(目前不正确的)代码:

public class testing {
    public static void main(String[] args) {

        int a;

        a = 42;

        System.out.println(factor(a));

    }

    //This method finds a factor of the non-prime number
    public static int factor(int m) {   
        for(int y=2 ; y <= m/2 ; y++) {
            if(m%y==0) {
                return y;
                continue;
            }
        }
    return y;
    }
}

请告诉我不正确的事情!

3 个答案:

答案 0 :(得分:6)

关于您的代码:

public static int factor(int m) {   
    for(int y=2 ; y <= m/2 ; y++) {
        if(m%y==0) {
            return y;
            continue;
        }
    }
    return y;
}

在最终return y时,y不存在。它的范围仅限于for语句的内部,因为这是您创建它的地方。这就是你得到未定义变量的原因。

在任何情况下,如果找不到因素,则返回y正好是错误的要做的事情,因为如果你传入(例如)47 ,它会返回2447 / 2 + 1),尽管它不是一个因素。

在返回之后尝试继续循环也没什么意义:-)而且,为了提高效率,你只需要达到m的平方根而不是一半它的。

因此,我会以此为出发点:

public static int factor (int num) {   
    for (int tst = 2 ; tst * tst <= num ; tst++)
        if (num % tst == 0)
            return tst;
    return num;
}

这具有使用素数的优点,因为素数的第一个因素是素数本身。并且,如果你愚蠢地传递一个负数(或少于两个,你也会得到你传入的数字。如果你想要,你可能希望在代码中添加一些额外的检查不同的行为。


你可以通过以下方式加快速度:

public static int factor (int num) {
    if (num % 2 == 0) return 2;
    for (int tst = 3 ; tst * tst <= num ; tst += 2)
        if (num % tst == 0)
            return tst;
    return num;
}

这会预先检查2,然后只使用奇数数字进行余数检查。因为你已经检查了2,你知道它不能是任何偶数的倍数,所以你只需要检查奇数就能使速度加倍。


如果你想让它更快(可能,虽然你应该检查它并记住代码可能更难理解),你可以在评论中使用威尔指出的聪明方案。

如果您考虑上面的循环使用的奇数和一些注释,您可以看到您定期得到三的倍数:

 5
 7
 9   = 3 x 3
11
13
15   = 3 x 5
17
19
21   = 3 x 7
23
25
27   = 3 x 9

当您意识到每个带注释的数字比前一个带注释的数字多六(3 x 2)时,这在数学上是显而易见的。

因此,如果你从五开始并交替添加两个和四个,你将跳过三个的倍数和两个的倍数:

5, +2=7, +4=11, +2=13, +4=17, +2=19, +4=23, ...

可以使用以下代码完成:

public static long factor (long num) {
    if (num % 2 == 0) return 2;
    if (num % 3 == 0) return 3;
    for (int tst = 5, add = 2 ; tst * tst <= num ; tst += add, add = 6 - add)
        if (num % tst == 0)
            return tst;
    return num;
}

您必须预先针对3添加测试,因为它违反2, 4, 2规则(序列3, 5, 7 两个连续两个间隙)但是可能是一个很小的代价,可以从原始搜索空间大致减少25%(超过已经通过跳过所有偶数而实现的50%)。

add设置为2,然后使用add = 6 - add进行更新,这是让24之间的替代方式:

6 - 2 -> 4
6 - 4 -> 2

正如我所说的,这个可能会提高速度,特别是在模数比简单减法更昂贵的环境中,但是你想要真正对它进行基准测试以确定。我只是将其作为另一个可能的优化提供。

答案 1 :(得分:1)

这是你可能想要做的事情:

public static void main(String[] args) {

    int a;

    a = 42;

    System.out.println(factor(a));
}

public static int factor(int m) {

    int y = 0;
    for (y = 2; y <= m / 2; y++) {
        if (m % y == 0) {
            return y;
        }
    }
    return y;
}

输出结果为2

答案 2 :(得分:0)

我们只需要一个简单的for循环,

public static void finfFactor(int z) {
for(int x=1; x <= z; x++) {
    if(z % x == 0) {
        System.out.println(x);
    }
}