【发布时间】:2015-07-02 10:28:21
【问题描述】:
我正在尝试解决一个问题。
问题: 给你一个由 4 种颜色的 N 个球组成的序列:红色、绿色、黄色和蓝色。当且仅当以下所有条件都为真时,该序列才充满颜色:
红球和绿球一样多。 黄球和蓝球一样多。 序列的每个前缀中红球和绿球的数量之差最多为 1。 序列的每个前缀中黄球和蓝球的数量之差最多为1。 你的任务是编写一个程序,对于给定的序列,如果它充满颜色则打印 True,否则打印 False。
我的解决方案:对于每个字符串,我生成所有可能的前缀和后缀来验证条件编号 3 和 4。但这需要更多时间。
我们可以遍历字符串并验证条件,而不是每次都生成前缀和验证条件。当条件不满足时,我想跳出循环。我无法以实用的方式获得它。有人可以帮助我如何实现它。
我的解决方案:
object Test {
def main(args: Array[String]) {
def isValidSequence(str: String) = {
def isValidCondition(ch1:Char, ch2:Char, m:Map[Char, Int]):Boolean = m.getOrElse(ch1, 0) - m.getOrElse(ch2, 0) > 1
def groupByChars(s:String) = s.groupBy(ch => ch).map(x => (x._1, x._2.length))
def isValidPrefix(s:String):Boolean = (1 to s.length).exists(x => isValidCondition('R', 'G', groupByChars(s.take(x))))
val x = groupByChars(str)
lazy val cond1 = x.get('R') == x.get('G')
lazy val cond2 = x.get('B') == x.get('Y')
lazy val cond3 = isValidPrefix(str)
lazy val cond4 = isValidPrefix(str.reverse)
cond1 && cond2 && !cond3 && !cond4
}
def printBoolValue(b:Boolean) = if(b) println("True") else println("False")
val in = io.Source.stdin.getLines()
val inSize = in.take(1).next().toInt
val strs = in.take(inSize)
strs.map(isValidSequence(_)).foreach(printBoolValue)
}
}
【问题讨论】:
-
顺便说一句,您可能希望
s.inits在 isValidPrefix 中返回所有前缀。 -
如果你使用
.par,你会同时进行多次迭代,所以真的不清楚“跳出循环”是什么意思。 -
为了让它更快,我使用了.par。不打算使用。将删除它
-
您的代码还有其他问题。对于条件 4,您似乎正在检查后缀,而不是带有黄色/蓝色的前缀。对于 isValidCondition,您正在检查第一种颜色的 # 不比第二种颜色多 1,但条件是差异最多为一个(换句话说,检查需要是对称的)。重复的 groupByChars 有点矫枉过正,只需
s.count('R'==)就可以了。以此类推。
标签: algorithm scala functional-programming