Рекурсивная функция пасхального яйца на java

Мне дали задание на java, оно включает в себя игру с пасхалкой, которая начинается, когда я даю вам n яиц, и заканчивается, когда у вас остается ровно m яиц. На любом этапе игры, допустим, у вас осталось n яиц, тогда вы можете отдать часть яиц, но вы должны соблюдать следующие правила:

• Если n четно, то вы можете вернуть ровно n/2 яиц.

• Если n делится на 3 или 4, то вы можете умножить две последние цифры n и вернуть это количество яиц.

• Если n делится на 5, то вы можете вернуть ровно m яиц.

• Если n — простое число, то вы можете отдать ровно одно яйцо.

Мне нужно написать функцию picnic, которая вернет true, если, применив правила в некотором порядке, у нас останется ровно m яиц; ложь иначе:

public static boolean picnic(int n, int m) { … }

при этом мои задачи:

а) Предоставьте рекуррентные отношения для пикника (int n, int m)

б) Реализовать рекурсивную функцию в Java, используя рекуррентные отношения

c) Разработать полное рекурсивное дерево вызовов для picnic(250, 42)

г) Какова здесь схема рекурсии? (хвостовая рекурсия или нет? древовидная или линейная рекурсия?)

e) Напоминает ли эта функция какую-либо стратегию построения алгоритма? Если да, то какой?

Я уже сделал вопрос а) с этим в качестве ответа:

public class EasterEggs {   
    public static boolean picnic (int n, int m) {
        if (n == m)
        return true;
        else return (picnic(n,m));
    }
}

И я не уверен, как реализовать рекурсивную функцию. Я пытался несколько раз, но до сих пор ничего.

Вопросы b и c - мои самые большие проблемы, и я уверен, что смогу понять d и e. Может ли кто-нибудь помочь мне с этим? И, возможно, показать мне, как это можно реализовать?


person LearningToProgram    schedule 04.04.2016    source источник
comment
Если n!=m, рекурсия никогда не завершается (приводит к переполнению).   -  person blazs    schedule 04.04.2016
comment
@blazs, потому что код отвечает только а), а не (пока) б)   -  person f1sh    schedule 04.04.2016
comment
ваш рекурсивный вызов picnic должен заменить n на число, меньшее n. Для этого примените каждое возможное правило и используйте пикник на том числе, которое у вас осталось после применения правила. Также следует проверить случай, когда n ‹ m.   -  person Yoav Gur    schedule 04.04.2016
comment
Правила противоречат друг другу: например, если n делится на 4, оно также четно, а 5 — простое число, которое делится на 5. Должны ли вы брать на себя приоритет среди правил?   -  person Joni    schedule 04.04.2016


Ответы (3)


Вы должны:

Создайте перечисление, представляющее ваши различные правила (их 4: p). Допустим, вы назвали свое перечисление ERule

создать рекурсивную функцию с аргументами

  • оставшиеся яйца (изначально == n)
  • m

Условия выхода для рекурсивной функции:

  • п = м (правда)
  • п ‹ м (ложь)
  • никакое правило не может применяться к n (false)

если условия выхода не выполняются, то просто вызовите рекурсивную функцию для каждого правила, которое может быть применено к текущему n (вызовите ее для измененного значения n, в зависимости от проверяемого условия). Результатом является оператор ИЛИ для всех результатов.

person Ji aSH    schedule 04.04.2016

В рекуррентном отношении нам не нужно определять класс и методы, как вы упомянули в своем вопросе. Это рекурсия дерева, а не рекурсия хвоста. И эта функция напоминает нам о стратегии дизайна Backtracking.

для части б) мое решение простое и грубое.

public class EasterEggs {   
    public static boolean picnic (int n, int m) {
      if (n == m)
        return true;
      if(n < m)
        return false;

      boolean result = false;

      if(n%2 == 0)
         result = picnic(n-n/2,m);
      if((n%3 == 0 || n%4 == 0) && (result == false))
         result = picnic(n-lastTwoDigitMultiply(n),m);
      if(n%5 == 0 && (result == false))
         result = picnic(n-m,m);
      if(isPrime(n) && (result == false))
         result = picnic(n-1,m);

      return result;  
    }
}
person nishant10    schedule 04.04.2016

Это лучшая функция для возврата данного массива, делится он или нет

/* Пример данных

  • {3, 3, 6, 36} 3
  • {4} 2
  • {3, 4, 3, 6, 36} 3
  • {6, 12, 24, 36} 12
  • {} */

открытый класс IsDivisible {

public static void main(String[] args) {

    int[] sampleData = { 3, 3, 6, 36 };
    int divisible = 3;

    int result = isDivisible(sampleData, divisible);
    System.out.println(result);

}

static int isDivisible(int[] givenArray, int isDivisible) {

    for (int i = 0; i < givenArray.length; i++) {

        if ((givenArray[i] % isDivisible) != 0) {

            return 0;

        }
    }

    return 1;
}

}

person Addisu Dessalegn    schedule 07.03.2021
comment
пожалуйста, отредактируйте формат своего ответа и добавьте некоторые пояснения - person Pejman Kheyri; 07.03.2021