返回信息流问一个Scala的问题吧,不知道版上有没有人会,这个算是Java的一个延伸拓展吧……
def transformCapitalize(w: String) : Iterator[String] =
要求返回w的所有大小写可能的结果
比如我输入的w是“taco”
返回的结果就是List ("taco", "tacO", "taCo", "taCO", "tAco", "tAcO", "tACo", "tACO",
"Taco", "TacO", "TaCo", "TaCO", "TAco", "TAcO", "TACo", "TACO")
不知道有没有什么简单的算法?
这是一条镜像帖。来源:北邮人论坛 / java / #22476同步于 2012/5/18
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
[问题][讨论]问一个Scala的问题
rayzl0523
2012/5/18镜像同步4 回复
订阅后,新回复会通过你的通知中心匿名送达。
4 条回复
def capitalize(c: Char): List[Char] = List(c.toLower, c.toUpper)
def split(w: String): List[Char] = w.toList
def transformCapitalize(w: String): List[String] = split(w).map(capitalize).foldLeft(List[String]()) { (acc, xs) =>
acc match {
case Nil => xs.map(_.toString)
case _ => for {
a <- acc
x <- xs
} yield a + x
}
}
新手贴一个:我这个从结果上看是正确的,但是,Scala应该不像Haskell那样惰性求值。
package junk
object UpAndDown extends App {
def upAndDown(l: Char) = List(l.toLower, l.toUpper)
assert(upAndDown('w') == List('w','W'))
def tcRecursive(w: List[Char]) : List[List[Char]] = {
w match {
case Nil => List(List())
case l::ls => for {
x <- upAndDown(l)
xs <- tcRecursive(ls)
} yield (x :: xs)
}
}
assert(tcRecursive(List()) == List(List()))
assert(tcRecursive(List('a')) == List("a","A").map(_.toList))
assert(tcRecursive(List('a','b')) == List("ab","aB","Ab","AB").map(_.toList))
def transformCapitalize(w: String): Iterator[String] = {
tcRecursive(w.toList).map(_.mkString).iterator;
}
assert(transformCapitalize("").toList == List(""))
assert(transformCapitalize("a").toList == List("a","A"))
assert(transformCapitalize("ab").toList == List("ab","aB","Ab","AB"))
for (x <- transformCapitalize("taco")) println(x)
}
由于没有惰性求值,下面这个将永远算不完……
import scala.util.control.Breaks._
var i = 0;
for (x <- transformCapitalize("pneumonoultramicroscopicsilicovolcanoconiosis")) {
println(x)
i = i+1
if (i>=10) {
break;
}
}
【 在 shallwebupt 的大作中提到: 】
: def capitalize(c: Char): List[Char] = List(c.toLower, c.toUpper)
: def split(w: String): List[Char] = w.toList
: def transformCapitalize(w: String): List[String] = split(w).map(capitalize).foldLeft(List[String]()) { (acc, xs) =>
: ...................
我再问问:如何用Scala编出Haskell的这种效果:
module Main where
import Char
lu x = [toLower x, toUpper x]
upAndDown :: String -> [String]
upAndDown "" = [""]
upAndDown (l:ls) = [x:xs|x <- lu l, xs <- upAndDown ls]
-- This is simpler
upAndDown2 :: String -> [String]
upAndDown2 = sequence . map lu
-- This should be safe and fast
first10 = take 10 $ upAndDown "abcdefghijklmnopqrstuvwxyz"
【 在 wks 的大作中提到: 】
: 新手贴一个:我这个从结果上看是正确的,但是,Scala应该不像Haskell那样惰性求值。
: [code=scala]
: package junk
: ...................
自己回答吧。Scala的scala.collection.immutable.Stream是惰性的容器。只有当真正需要求值的时候才会去计算。一般把List改称Stream就可以达到目的。
下面这个程序输入很长的字符串,在列举时会一个一个地输出,而不是要等到全部计算完毕。如果你使用类似.take(10)这样的方法限制,最终就只会计算前10个,后面的不会去计算。
object UpAndDown3 extends App {
def capitalize(c: Char): Stream[Char] = Stream(c.toLower, c.toUpper)
def split(w: String): Stream[Char] = w.toStream
def transformCapitalize(w: String): Stream[String] = split(w).map(capitalize).foldRight(Stream("")) { (xs, acc) =>
for {
x <- xs
a <- acc
} yield (x + a)
}
val theWord = "pneumonoultramicroscopicsilicovolcanoconiosis"
for (x <- transformCapitalize(theWord)) {
println(x)
}
}
【 在 wks 的大作中提到: 】
: 我再问问:如何用Scala编出Haskell的这种效果:
: [code=text]
: module Main where
: ...................