【问题标题】:Can we call a function through map, passing function name in value of Hashmap function我们可以通过map调用函数吗,在Hashmap函数的值中传递函数名
【发布时间】:2018-06-29 13:30:57
【问题描述】:

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

示例-
网格-(100*500)
机器人初始位置-(5,3)
可能的命令-
N-北,
东东,
西西,
南-南,
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 方法。

【问题讨论】:

  • 您应该制作功能接口图。 baeldung.com/java-8-functional-interfaces
  • 最好在每个条目中使用 enumexecute() 方法
  • 也许你过于复杂了。为什么不为您的 4 个可能的命令设置一个 switch 语句或 if else 块。
  • 禁止使用条件分支,如 if/else 或 switch。这就是为什么必须使用其他方法来解决这个问题

标签: java arrays enums hashmap


【解决方案1】:

首先,赋值参数似乎缺少“初始朝向”属性或第一个命令永远不会是 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 的回答。

【讨论】:

    【解决方案2】:

    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,这五种方法中的每一种都应该有足够的信息来执行有效的机器人命令。

    【讨论】:

    • 我想我们一次只能得到一个命令。而且我们需要检查机器人是否可以移动到那个位置,因为它可能不是网格的结尾
    • 我是使用枚举的新手,请您帮我如何动态地给出命令名称而不是硬编码。我试过这段代码。在问题中添加。
    • 动态名称是什么意思?您是要更改命令的名称以进行国际化等,还是要从该静态列表中动态创建命令列表?
    猜你喜欢
    • 2016-11-23
    • 1970-01-01
    • 1970-01-01
    • 2020-01-19
    • 1970-01-01
    • 2011-02-20
    • 1970-01-01
    • 2010-09-20
    • 1970-01-01
    相关资源
    最近更新 更多