Можем ли мы вызвать функцию через карту, передавая имя функции в значении функции Hashmap - PullRequest
0 голосов
/ 29 июня 2018

Я столкнулся с одной проблемой, я должен найти положение робота в сетке, он может двигаться в прямом направлении и может изменить свое направление на север, юг, восток и запад, и ему была предоставлена ​​заданная последовательность команд , Итак, какой будет конечная позиция робота. Использование любого типа ветвления условия (например, if / else, switch / case) запрещено.

ПРИМЕР-
ГРИД (100 * 500)
Начальная позиция робота - (5,3)
Возможные команды -
N-Север,
E-East,
W-Запад,
S-Юг,
M-движение вперед
Пример ввода - {N, S, M.M, E, W, E, S, M, S, M}

Мой Алго-
Я думаю, что могу использовать карту, где мои ключи будут командами, а значения будут функциями, выполняемыми для этой конкретной команды. Но я не понимаю, как вызвать функцию через значение HashMap. Также мы должны принять во внимание конечные случаи, когда у сетки больше не будет возможных движений.

Я попробовал этот код согласно предложению, но не понимал, как давать динамические команды, используя Enum

public class RobotMovesInGrid {
    Scanner input = new Scanner(System.in);
    String command=input.next();
    int commLength = command.length();

    static enum Command {
        N{@Override public void execute(String g, String r){ System.out.println("do the N move here"); }},
        E{@Override public void execute(String g, String r){ System.out.println("do the E move here"); }},
        S{@Override public void execute(String g, String r){ System.out.println("do the S move here"); }},
        W{@Override public void execute(String g, String r){ System.out.println("do the W move here"); }},
        M{@Override public void execute(String g, String r){ System.out.println("do the M move here"); }};
        public abstract void execute(String g, String r);

    }
    public void nextPosition() {
        Command c1;
        for(int i=0;i<commLength;i++) {
            if (command.charAt(i)=='N'||command.charAt(i)=='E'|| command.charAt(i)=='S'|| command.charAt(i)=='W'||command.charAt(i)=='M')

                c1= Command.M;// Here instead of M, I am trying to give dynamic commands but it is not taking it
            System.out.println("Current position is"+c1);
        }

    //return c1;
    }
}

Может кто-нибудь предложить мне, как вызывать методы Enum, используя команды, заданные в качестве ввода.

Ответы [ 2 ]

0 голосов
/ 29 июня 2018

Во-первых, кажется, что в параметрах присваивания отсутствует свойство «начальная облицовка» или ограничение, что первая команда никогда не будет M. (потому что, если у тебя нет начальной грани, как ты узнаешь, в каком направлении «двигаться вперед», если первая команда - M?)

Однако, игнорируя эту проблему, вы можете использовать рекурсию для этого решения. Учитывая размер сетки, начальную позицию и список ходов ...

public GridPosition findFinalPosition(Grid theGrid, GridPosition startPosition, List<MoveDirections> theMoves) {

    if (theMoves.length() == 0) {
       return startPosition;
    }
    GridPosition nextPosition = theGrid.findNextPosition(startPosition, theMoves.getAt(0));

    List<MoveDirections> remainingMoves = new ArrayList<MoveDirections>()
    for (int i = 1; i < theMoves.length(); i++) {
         remainingMoves.add(theMoves.getAt(i));
    }

    return findFinalPosition(theGrid, nextPosition, remainingMoves);

При таком рекурсивном методе вам просто нужно реализовать "findNextPosition" без использования if / else или switch ... (и контролировать ходы, которые выходят за пределы сетки и т. Д.)

Так как это кажется очевидным назначением класса, я не собираюсь показывать вам, как я реализовал бы "findNextPosition" без использования if / else или switch ... Но, подсказка, мое решение реализовало бы перечисление, подобное @ Отметьте ответ Джеронимуса.

0 голосов
/ 29 июня 2018

Использование Map для последовательности команд не имеет никакого смысла, потому что карта (независимо от подклассов) не сохраняет порядок своих элементов. Это имеет смысл для отображения команд на функции, но есть более простой способ.

Это отвечает на вопрос: «как вызвать функцию через значение [a]».

Вот шаблон для перечисления, который может выполнять метод:

static enum Command {
    N{@Override public void execute(Grid g, Robot r){ System.out.println("do the N move here"); }},
    E{@Override public void execute(Grid g, Robot r){ System.out.println("do the E move here"); }},
    S{@Override public void execute(Grid g, Robot r){ System.out.println("do the S move here"); }},
    W{@Override public void execute(Grid g, Robot r){ System.out.println("do the W move here"); }},
    M{@Override public void execute(Grid g, Robot r){ System.out.println("do the M move here"); }};
    public abstract void execute(Grid g, Robot r);
}

С помощью этого перечисления вы можете сохранить последовательность в списке или передать перечисления вокруг.

    Command c1 = Command.M; // hardcoded Move
    Command c2 = getNextMove(); // from a method: public Command getNextMove(){...}
    Command c3 = list.get(3); // from a collection: List<Command>

С любым из этих экземпляров вы можете вызывать функцию с соответствующими экземплярами вашей программы:

    c1.execute(g, r);

С g и r каждый из пяти методов должен иметь достаточно информации для выполнения действительной команды робота.

...