构造自定义for循环

时间:2013-11-05 11:31:33

标签: scala for-loop

目标是编写一个为某个值生成格雷码的函数。

目前我有这个:

def gray(i: Int): List[String] = {
    if(i == 0) List("")
    else {
      val l = gray(i - 1)
      (l map {"0" + _}) ::: (l map{"1" + _})
    }
}

gray(3)的输出:List(000, 001, 010, 011, 100, 101, 110, 111)

然后我尝试用for循环构造这个List。想象一下:

对于n = 2,我会:

def gray(i: Int): List[String] = {
    (for{a <- 0 to 1
         b <- 0 to 1} yield a+""+b).toList 
}

对于n = 3,我会:

def gray(i: Int): List[String] = {
    (for{a <- 0 to 1
         b <- 0 to 1
         c <- 0 to 1} yield a+""+b+""+c).toList 
  }

显然这不考虑i,所以我想知道我们是否可以使用i构建一个为循环表达式构造自定义的函数。

构造我的意思是:

如果i == 2,请为循环创建2变量并生成它们,如果i == 3然后创建3并生成它们等等。

有可能吗? (我是Scala的初学者)

3 个答案:

答案 0 :(得分:5)

def gray(n: Integer): List[List[Char]] = {
    if (n == 0) List(List()) else
      for {
        c : List[Char] <- gray(n - 1)
        i : Char <- List('0', '1')
      } yield i :: c
  }                  //> gray: (n: Integer)List[List[Char]]

val of0 = gray(0)    //> of0  : List[List[Char]] = List(List())
val of1 = gray(1)    //> of1  : List[List[Char]] = List(List(0), List(1))
val of2 = gray(2)    //> of2  : List[List[Char]] = List(List(0, 0), List(1, 0), List(0, 1), List(1, 1))
...

答案 1 :(得分:3)

您无法这样做的原因是因为必须在编译时指定for expression,因为i仅在运行时可用。这样做的一个选择是使用生成所需for expression的宏,但即使在这种情况下,您也必须通过传递一个常量整数(而不是仅在运行时解析的int变量)来调用该宏

答案 2 :(得分:1)

应该做的伎俩?

object GrayTest {

  def gray(i:Int):List[String] =
  {
    if (i == 0 ) List("")
    else {
      val l = gray(i-1)
      l.map("0" + _) ::: l.reverse.map("1"+_)
    }
  }

  def main(arg:Array[String]) =
  {
    println(gray(3))
  }

}