Java 我的语法有什么问题吗?我这样做是否有效?
我正在尝试一种方法,它能告诉我天气好坏,一个数是素数是真是假。代码如下:Java 我的语法有什么问题吗?我这样做是否有效?,java,syntax,methods,Java,Syntax,Methods,我正在尝试一种方法,它能告诉我天气好坏,一个数是素数是真是假。代码如下: class prime { public static boolean prime (int a, int b) { if (a == 0) { return false; } else if (a%(b-1) == 0) { return false;
class prime
{
public static boolean prime (int a, int b)
{
if (a == 0)
{
return false;
}
else if (a%(b-1) == 0)
{
return false;
}
else if (b>1)
{
prime (a, b-1) ;
}
else
{
return true;
}
}
public static void main (String[] arg)
{
System.out.println (prime (45, 45)) ;
}
}
当我尝试编译此文件时,会收到以下错误消息:
prime.java:23: missing return statement
}
^
1 error
我可能误解了错误消息所说的内容,但在我看来,并没有缺少返回语句,因为对于每一组可能的条件,我都有一个返回语句。如果a为0,则返回false;如果不是,则检查a是否可除以b;如果是,则返回;如果不是,则返回;如果b大于1,则重新开始。如果b不大于1,它也会返回
- 而且,不得不这样做似乎有点混乱 使此方法取两个整数 都是相同的int
- 我的语法有什么问题/为什么会收到错误消息?有没有办法让我在main中使用的方法只需要取一个int(也许另一个方法会将该int分割成两个克隆,然后传递给
property)公共静态布尔素数
- 还是有更有效的解决方法 这是我错过的 完全
b
大于1
,则函数不会返回任何内容
可能是
返回素数(a,b-1);
?您似乎有这样一种印象,因为递归最终会找到一个会命中return语句的基本情况,那么该返回将在所有递归调用中冒泡出来。这不是真的。每个递归调用都必须像下面这样传递结果:
return prime(a, b - 1);
为了提高效率,更多地考虑你的条件。你真的需要测试从2到N的每一个因子吗?是否有一个不同的停止点可以帮助质数测试更快地完成
为了制作一个更好的API,考虑将递归方法私有化,用一个公共入口点帮助引导过程。
public static boolean prime(int n) {
return recurse(n, n);
}
private static boolean recurse(int a, int b) {
...
}
将一个方法设置为private意味着不能从另一个类调用它。该类的用户实际上看不到它。这里的目的是通过提供一个public helper方法来隐藏“丑陋”的额外参数
想想一些复合数的因子。10因子到5×2。12因子到6×2。14因子到7×2。现在想想25.25因子到5×5。9呢?你看到一个模式了吗?顺便说一下,如果这不是家庭作业,请让我知道。这对我来说很难。在你的
素数函数中,有四种可能的code路径,其中一个路径不返回任何内容。这就是错误消息所抱怨的。您需要替换:
prime (a, b-1) ;
与:
在else if(b>1)
情况下
话虽如此,这实际上不是计算一个数是否为素数的好方法。问题是,每个递归调用都分配一个堆栈帧,如果您试图确定9999999是否为素数,您将遇到严重的堆栈溢出问题
递归对于某些问题的子集来说是一个非常好的工具,但是你需要知道堆栈的深度。至于更有效的解决方案,你可以进行很多测试来确定一个数字不是素数,然后用蛮力测试来检查其他数
你应该注意的一件事是首先检查较小数字的可分性,因为这会更快地缩小搜索范围。并且不要在乘法可以完成的地方使用除法,乘法通常更快(尽管并不总是如此)
还有一些可能是鬼鬼祟祟的把戏:
- 除2以外,以2、4、6、8或0结尾的每个数字都是非素数
- 除5以外,以5结尾的每一个数字都是非素数。
仅这两条规则就可以减少60%的搜索空间。假设您以字符串形式获取测试编号,那么即使在转换为整数类型之前,也可以测试该字符串的最后一位数字
对于整除性检查,有一些更复杂的规则。如果你取9的倍数,将所有数字相加,得到一个新的数字,然后再对该数字进行一次运算,直到得到一个数字,你会发现它总是9
这将使您的搜索空间再减少10%,尽管需要花费更多的时间进行检查。请记住,这些检查只对非常大的数字有利。对于32位整数来说,优势并不是很大,因为预先计算的位图在那里会更有效(见下文)
对于一个简单的开始,我将使用以下迭代解决方案:
public static boolean prime (int num) {
int t = 2;
while (t * t <= num) {
if ((num % t) == 0) {
return false;
}
t++;
}
return true;
}
递归方法必须返回一个值才能展开
public static boolean prime (int a, int b)
{
if (a == 0)
{
return false;
}
else if (a%(b-1) == 0)
{
return false;
}
else if (b>1)
{
return prime (a, b-1) ;
}
else
{
return true;
}
}
我可能会用另一种方式编写,但这就是您无法编译代码的原因。为了回答为什么7不起作用,请假设您是计算机,并通过您的逻辑进行操作。以下是您编写的内容
class prime
{
public static boolean prime (int a, int b)
{
if (a == 0)
{
return false;
}
else if (a%(b-1) == 0)
{
return false;
}
else if (b>1)
{
// Have to add the return statement
// here as others have pointed out!
return prime(a, b-1);
}
else
{
return true;
}
}
public static void main (String[] arg)
{
System.out.println (prime (45, 45)) ;
}
}
让我们从7开始
if(7 == 0) // not true, don't enter this block
else if(7 % 6 == 0) // not true
else if(7 > 1) // true, call prime(7, 6)
if(7 == 0) // not true, don't enter this block
else if(7 % 5 == 0) // not true
else if(6 > 1) // true, call prime(7, 5)
if(7 == 0) // not true, don't enter this block
else if(7 % 4 == 0) // not true
else if(5 > 1) // true, call prime(7, 4)
…继续向下调用prime(7,2)
否则如果(7%1==0)为true,则返回false
当你开始调用prime(n,2)
时,它总是返回false,因为你有一个逻辑错误。我认为原来的问题已经得到了回答-你需要在的主体中插入return
,否则如果(b>1)
-我只是想指出,当b的值为1时,您的代码仍然会崩溃,抛出一个算术异常
,因为a%(b-1)
将被计算为a%0
,导致被零除
如果(a==0 | | b==1){}
这不会改善程序查找素数的方式,只是确保少了一种方法使其崩溃。与@paxdiblo的答案类似,但效率略高
public static boolean isPrime(int num) {
if (num <= 1 || (num & 1) == 0) return false;
for (int t = 3; t * t <= num; t += 2)
if (num % t == 0)
return false;
return true;
}
public静态布尔值isPrime(int num){
如果(num),即必须使用返回素数(a,b-1);
而不仅仅是素数(a,b-1);
但如果b>1,则它将
if(7 == 0) // not true, don't enter this block
else if(7 % 6 == 0) // not true
else if(7 > 1) // true, call prime(7, 6)
if(7 == 0) // not true, don't enter this block
else if(7 % 5 == 0) // not true
else if(6 > 1) // true, call prime(7, 5)
if(7 == 0) // not true, don't enter this block
else if(7 % 4 == 0) // not true
else if(5 > 1) // true, call prime(7, 4)
if(7 == 0) // not true, don't enter this block
public static boolean isPrime(int num) {
if (num <= 1 || (num & 1) == 0) return false;
for (int t = 3; t * t <= num; t += 2)
if (num % t == 0)
return false;
return true;
}