【问题标题】:Rewriting java if statements in clojure syntax用clojure语法重写java if语句
【发布时间】:2019-05-29 05:59:27
【问题描述】:

我有一组用 Java 编写的递归 if 语句,我尝试将其用于 clojure 语法,但得到了 ArrayOutOfBound 错误。这些函数接受 row = 0、col = 0 和多维字符数组。

这是 Java 代码:

public static boolean solveMaze(int r, int c, char[][] maze) {

    //check for boundaries
    if(r < 0 || c < 0 || r >= maze.length || c >= maze[0].length)
        return false;
    //base case, did i reach the finish?
    if(maze[r][c] == '@')
        return true;
    //check if I'm at a valid point
    if(maze[r][c] != '-')
    //I have hit a wall, not a valid solution
        return false;
    //must be on a path, may be the right path
    //leave a bread crumb
    maze[r][c] = '!';
    //check above
    if(solveMaze(r-1,c, maze)) {

        maze[r][c] = '+';
        return true;
    }
    //check below
    if(solveMaze(r+1,c, maze)) {

        maze[r][c] = '+';
        return true;
    }
    //check left
    if(solveMaze(r,c-1, maze)) {

        maze[r][c] = '+';
        return true;
    }
    //check right
    if(solveMaze(r,c+1, maze)) {

        maze[r][c] = '+';
        return true;
    }
    //if I reach this point...
    return false;
}

这是我在 clojure 中的代码,它提供了 Index out of bound 错误:

    (defn solveMaze [r c m]
    (def tt true)
    ;(def che false)

    ;check to verify boundaries
    (if (or (or (or (< r 0) (< c 0)) (>= r (count m))) (>= c (count (str (m 0)))))
        false
        true
    )
    ;Check to know if the @ symbol has been found
    (if (= (get-in m[r c]) "@")
        true
        false
    )
    ;Checking if current index is a valid one
    (if (not= (get-in m[r c]) "-")
        ;Wall hit
        false
        true
    )
    ;found a path, leave a breadcrumb
    (def temp_map (assoc-in m[r c] "!"))
    ;Check North
    (if (= (solveMaze (dec r) c m) true)
        (def temp_map (assoc-in m [r c] "+"))
        true   
        ;false
    )
    ;Check South
    (if (= (solveMaze (inc r) c m) true)
        (def temp_map (assoc-in m[r c] "+"))
        true
        ;false
    )
    ;Check East
    (if (= (solveMaze r (dec c) m) true)
        (def temp_map (assoc-in m[r c] "+"))
        true
        ;false
    )
    ;Check West
    (if (= (solveMaze r (inc c) m) true)
        (def temp_map (assoc-in m[r c] "+"))
        true
        ;false
    )
    ;If code gets here
    (= tt false)

)

请问有什么我做错了吗???我已经尝试了几个使用 clojure 的 if 构造,但它不起作用。

【问题讨论】:

  • 在许多情况下,您无法将 java 程序逐字翻译成 clojure。 if 不会自行返回,但一切都会返回最后一条语句的结果。所以至少你必须级联你的 if 语句。除了顶级之外,也永远不要def。使用let
  • 嗨 cfrick,感谢您的评论,这是否意味着我无法在 clojure 中获得相同的构造?
  • @FoskieBlue 是和否。你需要的是阅读一些 clojure 的基础知识,因为你在做什么是违反习惯的(至于函数内部的defs)和错误的(至于其余的)。执行此类操作的 clojure 方法是 cond clojuredocs.org/clojure.core/cond
  • Clojure 函数的主体是一系列表达式。这些是按顺序评估的。最后的值被返回。任何先前表达式的值都将被丢弃。因此,您检查rc 是否在界限内,但false 结果被丢弃,并且无论rc 值的有效性如何,评估都会继续进行。我将为此向您展示惯用的 Clojure,它很有趣,因为它是如此不同,它将引导您走上正义之路。但既然问题已经结束,我只能指出你的直接错误。

标签: clojure


【解决方案1】:

您需要阅读 Clojure 的基础知识:

【讨论】:

  • 其实任何一个,第一章就足够了
  • 这是准确,但我不确定这是认真回答问题。可能更好地投票结束这个问题太宽泛而无法回答(对于大多数“请为我翻译此代码”的问题通常都是这种情况,这些问题不会缩小一个单一的、具体的、狭隘的陈述,并尽可能最小化周围基础设施的数量,使其可运行/可测试)。
【解决方案2】:

使用条件而不是 if 来解决这个问题。代码现在执行的方式是首先评估 if,然后转到下一行执行其余代码。使用 cond,如果一个表达式被评估为真,它会返回该值并且不会评估其他表达式。

参考:https://clojuredocs.org/clojure.core/cond

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-08
    相关资源
    最近更新 更多