我正在尝试编写一个简单的程序,它接受一个非素数并返回它的第一个因子。我必须使用一种方法来做到这一点。我认为我非常接近正确的代码,但我仍然在我的方法中遇到变量定义问题。这是我的(目前不正确的)代码:
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;
}
}
请告诉我不正确的事情!
答案 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
,它会返回24
(47 / 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
进行更新,这是让2
和4
之间的替代方式:
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);
}
}