目标是编写一个为某个值生成格雷码的函数。
目前我有这个:
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的初学者)
答案 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))
}
}