Java 阿克曼函数

Java 阿克曼函数,java,Java,我正在写一个递归程序,它计算 代码如下: public class Ackermann{ public static long ackermann( long m,long n) { return (m==0)? n+1: (m>0 && n==0)? ackermann(m-1,1): (m>0 && n>0)? ackermann(m-1, ac

我正在写一个递归程序,它计算

代码如下:

public class Ackermann{

    public static long ackermann( long m,long n) {
        return
            (m==0)? n+1:
            (m>0 && n==0)? ackermann(m-1,1):
            (m>0 && n>0)? ackermann(m-1, ackermann(m,n-1));
    }


    public static void main(String[]args) {
        long m=4;
        long n=2;
        System.out.println(ackermann(m,n));
    }
}
但它向我展示了错误:

Ackermann.java:7: : expected
   (m>0 && n>0)? ackermann(m-1, ackermann(m,n-1));
                                                 ^
Ackermann.java:7: ';' expected
   (m>0 && n>0)? ackermann(m-1, ackermann(m,n-1));
                                                  ^
Ackermann.java:18: illegal start of expression
public static void main(String[]args){
^
Ackermann.java:18: ';' expected
public static void main(String[]args){
      ^
Ackermann.java:18: illegal start of expression
public static void main(String[]args){
              ^
Ackermann.java:18: ';' expected
public static void main(String[]args){
                       ^
Ackermann.java:18: ';' expected
public static void main(String[]args){
                                    ^
Ackermann.java:26: reached end of file while parsing
}
 ^
8 errors

如何修复此问题?

上一个三元操作没有第三个操作数

(m>0&&n>0)?阿克曼(m-1,阿克曼(m,n-1))

注意有一个
但没有

由于您已经涵盖了所有情况,因此可以将其更改为返回-1,或者引发异常

但是,您也可以在不使用三元运算符的情况下更容易地实现此函数:

public static long ackermann(long m, long n) {
  if (m == 0) {
    return n+1;
  }
  if (m > 0 && n == 0) {
    return ackermann(m-1, 1);
  }
  if (m > 0 && n > 0) {
    return ackermann(m-1, ackermann(m, n-1));
  }
  // Something went wrong
  System.out.println("Invalid inputs: m and n cannot be negative");
  return -1;
}

更多的代码行不一定是坏的,代码高尔夫也不一定是好的。编写你的代码,这样你就可以在一年内回到它,并且能够很容易地找出它想要实现的目标。

对于
(m>0&&n>0)
为假的情况,没有表达式。

你的第三个三元if没有第二个选项。在修复之后,结构本身可能是有效的,它很难看,更详细的检查会很容易地告诉你你做错了什么。重写你的if并意识到你不需要三个,第三个选项就是当两个检查失败时剩下的选项

顺便说一下,计算Ackermann函数并不是很有用,它会在所有
m
大于3的情况下爆炸。您的代码将溢出,而不会产生任何合理的结果。

只需使用

public static long ackermann(long m, long n) {
  return (m==0)?
           n+1:
           (m>0 && n==0)?
             ackermann(m-1,1):
             ackermann(m-1, ackermann(m,n-1)); 
}

最后一个三元运算符没有用,甚至不完整(缺少
else
部分)。

Java只支持这种确切的语法
条件语句?true语句:false语句
没有像
条件?true语句那样的语法

因此,您应该将代码修改为以下内容:

public static long ackermann( long m,long n){
return 
   (m==0)? n+1:
   (m>0 && n==0)? ackermann(m-1,1):
   (m>0 && n>0)? ackermann(m-1, ackermann(m,n-1)):0; 
}

请学习正确缩进代码,删除空白,并将链接作为超链接而不是代码发布。当您运行代码时,您会发现
不够长……Pieter编写代码的最佳方式是什么?@danben提供了一个很好的概述,我建议您看看他的实现。当然,它只会随着您在
main
中输入的值溢出。当一个或两个输入都为负时,此代码将始终失败(即使您有一个无限大的堆栈)。对,不支持负参数。ackermann函数的定义适用于非负数,如中所述。如果希望此函数的用户获得有用的消息,只需添加
If(m