Функция Аккермана - PullRequest
4 голосов
/ 29 мая 2010

Я пишу рекурсивную программу, которая вычисляет функцию Аккермана .

Вот код:

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

Как это можно исправить?

Ответы [ 5 ]

9 голосов
/ 29 мая 2010

Ваша последняя троичная операция не имеет третьего операнда.

(m>0 && n>0)? ackermann(m-1, ackermann(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;
}

Больше строк кода не обязательно плохо, а код гольфа не обязательно хорошо. Напишите свой код таким образом, чтобы вы могли вернуться к нему через год и легко понять, для чего он предназначен.

4 голосов
/ 29 мая 2010

Просто используйте

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).

4 голосов
/ 29 мая 2010

Ваш третий троичный, если не имеет второго варианта. И сама конструкция может быть действительной после исправления этого, она уродлива, и более детальная проверка легко покажет вам, что вы сделали неправильно. Перепишите свои if и поймите, что вам не нужно три, третий вариант - это то, что остается, когда две проверки не пройдены.

Кстати, вычисление функции Аккермана на самом деле не очень полезно, оно взрывается для всех m больше 3. Ваш код будет просто переполнен без каких-либо разумных результатов.

2 голосов
/ 29 мая 2010

Java поддерживает только этот точный синтаксис conditional?true-statement:false-statement там нет синтаксиса типа conditional?true-statement.

Так что вы должны изменить свой код примерно так:

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; 
}
1 голос
/ 29 мая 2010

Нет выражения для случая, когда (m>0 && n>0) является ложным

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...