使用Scala中的递归获取正确的结果

时间:2014-11-13 20:47:14

标签: scala recursion logic

我创建了一个数据结构来表示一个n * n * n立方体,在这种特殊情况下它是一个4 * 4 * 4的立方体。出于调试的目的,我想实现一个将多维数据集打印到stdout的方法。结果应该是4层,每层由4x4区域组成。

因为我正在学习Scala,所以我希望以“功能性方式”来实现,并提出了递归解决方案。 drawCube方法在所有图层上“循环”,drawLayer方法遍历图层的线条,drawLine方法负责一行。

  • 每行应以斜线开头和结尾
  • 图层应用破折号分隔

代码:

    def drawCube = {
     val n = cube.sidelength
     val nl = sys.props("line.separator")
     val border = " -" * (n * 2 -1)

     def drawLine(acc: String, x: Int, y: Int, z: Int): String = {
      if(x < n) drawLine(acc + getField(x, y, z), x + 1, y, z) else <PosA> + acc + "/" + nl
     }
     def drawLayer(acc: String, y: Int, z: Int): String = {
      if(z >= 0) drawLayer(<PosB> + drawLine(acc, 0, y, z), y, z - 1) else acc + border + nl
     }
     def drawCube(acc: String, y: Int): String = {
      if(y < n) drawCube(drawLayer(acc, y, n - 1), y + 1) else border + nl + acc
     }
     def getField(x: Int, y: Int, z: Int) = {
      // returns a string representation of a specific field from the cube
      // in the following example, it's just a dot for the sake of simplicity
      // in a 4x4x4 cube, the range of x, y and z is from 0 to 3
     }
     println(drawCube("", 0))
    }

无论我是否在位置A 位置B (请参阅上面的占位符)中添加额外的“/”,我总是得到以下结果:

 - - - - - - -
//////////////// .  .  .  . /
 .  .  .  . /
 .  .  .  . /
 .  .  .  . /
 - - - - - - -
 .  .  .  . /
 .  .  .  . /
 .  .  .  . /
 .  .  .  . /
 - - - - - - -
 .  .  .  . /
 .  .  .  . /
 .  .  .  . /
 .  .  .  . /
 - - - - - - -
 .  .  .  . /
 .  .  .  . /
 .  .  .  . /
 .  .  .  . /
 - - - - - - -

正如你所看到的,一切都运行正常,除了前导斜杠,它们都是一次打印而不是一行的开头。这是为什么?什么是正确的位置?也许我花了太多时间用它,但我现在看不出问题。谢谢。

编辑:你可能已经注意到drawLayer方法的停止条件与其他两个方法相比略有不同。这与坐标系的变换有关,原点应显示在左上角。但我不认为这是问题,字段显示在正确的位置。

1 个答案:

答案 0 :(得分:1)

功能风格的巨大优势在于您可以单独测试较小的方法。尝试单独测试drawLine,或者用更简单的方法替换drawLine并测试drawLayer。我建议在基本功能正常工作之前避开累加器 - 简单的0 until n map {drawLine(_, y, z)} mkString可能会出错。

要回答您的具体问题,累加器始终是多维数据集的完整当前图形,以及任何函数的返回值。所以你不能"/" + acc"/" + drawSomething(),因为这总是会在开头添加“/”。相反,您需要在调用acc之前将“/”添加到drawLine end 。即drawLayer应定义为:

def drawLayer(acc: String, y: Int, z: Int): String =
  if(z >= 0) drawLayer(drawLine(acc + "/", 0, y, z), y, z - 1) else acc + "-" + "\n"