我们可以通过映射调用函数,在Hashmap函数的值中传递函数名称

时间:2018-06-29 13:30:58

标签: java arrays enums hashmap

我遇到了一个问题,我必须找到一个机器人在网格中的位置,它可以向前移动,并且可以将其面向北,南,东和西的方向改变,并且已经提供了给定的命令序列。那么,机器人的最终位置是什么。 禁止使用任何类型的条件分支(例如if / else,switch / case)。

示例-
网格-(100 * 500)
机器人的初始位置-(5,3)
可能的命令-
北北,
E-East,
W-West,
南南,
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 :(得分:0)

首先,似乎分配参数缺少“初始面”属性或第一个命令永远不会为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 ...(以及控制脱离网格的移动等)

由于这似乎是一个显而易见的类分配,因此我不向您展示如何在不使用if / else或switch的情况下实现“ findNextPosition”。但是,提示提示,我的解决方案将实现类似于@Mark Jeronimus的答案。

答案 1 :(得分:-1)

在命令序列中使用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);

使用gr时,这五个方法中的每一个都应具有足够的信息来执行有效的机器人命令。