Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 在列表上迭代时在scala中中断循环_Algorithm_Scala_Functional Programming - Fatal编程技术网

Algorithm 在列表上迭代时在scala中中断循环

Algorithm 在列表上迭代时在scala中中断循环,algorithm,scala,functional-programming,Algorithm,Scala,Functional Programming,我正在努力解决一个问题 问题: 您将获得一系列4种颜色的N个球:红色、绿色、黄色和蓝色。当且仅当以下所有条件均为真时,序列才会充满颜色: 红球和绿球一样多。 黄色的球和蓝色的球一样多。 序列的每个前缀中红色球和绿色球的数量之差最多为1。 序列每个前缀中黄色球和蓝色球的数量之差最多为1。 您的任务是编写一个程序,对于给定的序列,如果它充满了颜色,它将打印True,否则将打印False 我的解决方案是:为每个字符串生成所有可能的前缀和后缀,以验证条件编号3和4。但这需要更多的时间 我们可以迭代字符串

我正在努力解决一个问题

问题: 您将获得一系列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)
    }
}

所以,诀窍是首先检查最长的前缀。如果失败了,我们就完蛋了。否则,我们将使用下一个最长的前缀并递归。如果我们得到空字符串,它将传递所有前缀,因此它是有效的

def isValidPrefix(s: String): Boolean = 
if (s.length == 0)
  true
else if (!isValidCondition('R', 'G', groupByChars(s)))
  false
else isValidPrefix(s.init)

所以,诀窍是首先检查最长的前缀。如果失败了,我们就完蛋了。否则,我们将使用下一个最长的前缀并递归。如果我们得到空字符串,它将传递所有前缀,因此它是有效的

def isValidPrefix(s: String): Boolean = 
if (s.length == 0)
  true
else if (!isValidCondition('R', 'G', groupByChars(s)))
  false
else isValidPrefix(s.init)

如果需要,这里有一个使用流的解决方案

代码:-

object RGYB extends App {

val validPattern = List(
        "RG","RYBG","RYGB","RBGY",
        "GR","GYBR","GYRB","GBRY",
        "YB","YRGB","YRBG","YGRB",
        "BY","BRGY","BRYG","BGYR"
        )

        val pattern ="RGRG"
        pattern.sliding(4).foreach { x1 =>
        val count = validPattern.filter { p1 => {
            x1.equalsIgnoreCase(p1)
        } 
        }.size
        if(count<1)
        {
            x1.sliding(2).foreach {
                x2=>
                val counter  = validPattern.filter { p2 => {
                    x2.equalsIgnoreCase(p2)
                } 
                }.size
                if(counter<1)
                {
                    println("false !! not valid due to "+x2);
                    System.exit(0)
                }
            }
            println("false !! not valid due to "+x1);
            System.exit(0)
        }
}

println("True !!"+pattern+" Is a valid string pattern")
}
对象RGYB扩展应用程序{
val validPattern=列表(
“RG”、“RYBG”、“RYGB”、“RBGY”,
“GR”、“GYBR”、“GYRB”、“GBRY”,
“YB”、“YRGB”、“YRBG”、“YGRB”,
“BY”、“BRGY”、“BRYG”、“BGYR”
)
val pattern=“RGRG”
模式.滑动(4).foreach{x1=>
val count=validPattern.filter{p1=>{
x1.等信号情况(p1)
} 
}.尺寸
如果(计算)
val counter=validPattern.filter{p2=>{
x2.等信号情况(p2)
} 
}.尺寸

如果需要,这里有一个使用流的解决方案

代码:-

object RGYB extends App {

val validPattern = List(
        "RG","RYBG","RYGB","RBGY",
        "GR","GYBR","GYRB","GBRY",
        "YB","YRGB","YRBG","YGRB",
        "BY","BRGY","BRYG","BGYR"
        )

        val pattern ="RGRG"
        pattern.sliding(4).foreach { x1 =>
        val count = validPattern.filter { p1 => {
            x1.equalsIgnoreCase(p1)
        } 
        }.size
        if(count<1)
        {
            x1.sliding(2).foreach {
                x2=>
                val counter  = validPattern.filter { p2 => {
                    x2.equalsIgnoreCase(p2)
                } 
                }.size
                if(counter<1)
                {
                    println("false !! not valid due to "+x2);
                    System.exit(0)
                }
            }
            println("false !! not valid due to "+x1);
            System.exit(0)
        }
}

println("True !!"+pattern+" Is a valid string pattern")
}
对象RGYB扩展应用程序{
val validPattern=列表(
“RG”、“RYBG”、“RYGB”、“RBGY”,
“GR”、“GYBR”、“GYRB”、“GBRY”,
“YB”、“YRGB”、“YRBG”、“YGRB”,
“BY”、“BRGY”、“BRYG”、“BGYR”
)
val pattern=“RGRG”
模式.滑动(4).foreach{x1=>
val count=validPattern.filter{p1=>{
x1.等信号情况(p1)
} 
}.尺寸
如果(计算)
val counter=validPattern.filter{p2=>{
x2.等信号情况(p2)
} 
}.尺寸

如果(counter作为另一个答案,这里有一个更简单的解决方案,它会对差异进行短路检查

val valid = List("RGYBRGYB")      
val invalid = List("RGYBR", "RGYBY", "RGYBY", "RGYYB")

def checkBalls(s:String) = {
def differences(s:String, a:Char, b:Char) = {
  def differenceHelp(s:String, a:Char, b:Char, current:Int):Boolean = {
      if (current < -1 || current > 1) false
      else if (s.length == 0) true
      else differenceHelp(s.tail, a, b,
           if (s.head == a) current + 1 else if (s.head == b) current - 1 else current)
    }

  differenceHelp(s, a, b, 0)
}

lazy val cond1 = s.count('R'==) == s.count('G'==)
lazy val cond2 = s.count('Y'==) == s.count('B'==)
lazy val cond3 = differences(s, 'R', 'G')
lazy val cond4 = differences(s, 'Y', 'B')
cond1 && cond2 && cond3 && cond4
} 
valid.forall(checkBalls(_))                       //> res0: Boolean = true
invalid.forall(!checkBalls(_))                    //> res1: Boolean = true
val valid=List(“RGYBRGYB”)
val无效=列表(“RGYBR”、“RGYBY”、“RGYBY”、“RGYYB”)
def校验球(s:字符串)={
定义差异(s:String、a:Char、b:Char)={
def differenceHelp(s:String,a:Char,b:Char,current:Int):布尔={
如果(电流<-1 | |电流>1)为假
如果(s.length==0)为真,则为else
其他差异帮助(s.tail、a、b、,
如果(s.head==a)电流+1 else如果(s.head==b)电流-1 else电流)
}
差异帮助(s、a、b、0)
}
延迟值cond1=s.count('R'==)==s.count('G'==)
延迟值cond2=s.count('Y'==)==s.count('B'==)
lazy val cond3=差异(s,'R,'G')
lazy val cond4=差异(s,‘Y’、‘B’)
第1条和第2条和第3条和第4条
} 
valid.forall(checkBalls())/>res0:Boolean=true
无效。forall(!checkBalls())/>res1:Boolean=true
编辑:作为一种优化,我们可以将cond1作为cond3的一部分(将cond2作为cond4的一部分)。当且仅当字符串末尾的计数为0时,每个值的数量相等。我们可以在差异中检查,并仅当情况如此时返回true。因此

def checkBalls(s:String) = {
def differences(s:String, a:Char, b:Char) = {
  def differenceHelp(s:String, a:Char, b:Char, current:Int):Boolean = {
      if (current < -1 || current > 1) false
      else if (s.length == 0) (count == 0) // <- this line changed
      else differenceHelp(s.tail, a, b,
           if (s.head == a) current + 1 else if (s.head == b) current - 1 else current)
    }

  differenceHelp(s, a, b, 0)
}

lazy val cond3 = differences(s, 'R', 'G')
lazy val cond4 = differences(s, 'Y', 'B')
cond3 && cond4
} 
def checkBalls(s:String)={
定义差异(s:String、a:Char、b:Char)={
def differenceHelp(s:String,a:Char,b:Char,current:Int):布尔={
如果(电流<-1 | |电流>1)为假

否则,如果(s.length==0)(count==0)/作为另一个答案,这里有一个更简单的解决方案,它会短路差异检查

val valid = List("RGYBRGYB")      
val invalid = List("RGYBR", "RGYBY", "RGYBY", "RGYYB")

def checkBalls(s:String) = {
def differences(s:String, a:Char, b:Char) = {
  def differenceHelp(s:String, a:Char, b:Char, current:Int):Boolean = {
      if (current < -1 || current > 1) false
      else if (s.length == 0) true
      else differenceHelp(s.tail, a, b,
           if (s.head == a) current + 1 else if (s.head == b) current - 1 else current)
    }

  differenceHelp(s, a, b, 0)
}

lazy val cond1 = s.count('R'==) == s.count('G'==)
lazy val cond2 = s.count('Y'==) == s.count('B'==)
lazy val cond3 = differences(s, 'R', 'G')
lazy val cond4 = differences(s, 'Y', 'B')
cond1 && cond2 && cond3 && cond4
} 
valid.forall(checkBalls(_))                       //> res0: Boolean = true
invalid.forall(!checkBalls(_))                    //> res1: Boolean = true
val valid=List(“RGYBRGYB”)
val无效=列表(“RGYBR”、“RGYBY”、“RGYBY”、“RGYYB”)
def校验球(s:字符串)={
定义差异(s:String、a:Char、b:Char)={
def differenceHelp(s:String,a:Char,b:Char,current:Int):布尔={
如果(电流<-1 | |电流>1)为假
如果(s.length==0)为真,则为else
其他差异帮助(s.tail、a、b、,
如果(s.head==a)电流+1 else如果(s.head==b)电流-1 else电流)
}
差异帮助(s、a、b、0)
}
延迟值cond1=s.count('R'==)==s.count('G'==)
延迟值cond2=s.count('Y'==)==s.count('B'==)
lazy val cond3=差异(s,'R,'G')
lazy val cond4=差异(s,‘Y’、‘B’)
第1条和第2条和第3条和第4条
} 
valid.forall(checkBalls())/>res0:Boolean=true
无效。forall(!checkBalls())/>res1:Boolean=true
编辑:作为一种优化,我们可以将cond1作为cond3的一部分(将cond2作为cond4的一部分)。当且仅当字符串末尾的计数为0时,每个值的数量相等。我们可以在差异中检查,并仅当情况如此时返回true。因此

def checkBalls(s:String) = {
def differences(s:String, a:Char, b:Char) = {
  def differenceHelp(s:String, a:Char, b:Char, current:Int):Boolean = {
      if (current < -1 || current > 1) false
      else if (s.length == 0) (count == 0) // <- this line changed
      else differenceHelp(s.tail, a, b,
           if (s.head == a) current + 1 else if (s.head == b) current - 1 else current)
    }

  differenceHelp(s, a, b, 0)
}

lazy val cond3 = differences(s, 'R', 'G')
lazy val cond4 = differences(s, 'Y', 'B')
cond3 && cond4
} 
def checkBalls(s:String)={
定义差异(s:String、a:Char、b:Char)={
def differenceHelp(s:String,a:Char,b:Char,current:Int):布尔={
如果(电流<-1 | |电流>1)为假

否则,如果(s.length==0)(count==0)//只是一个旁白,您可能希望
s.inits
返回所有前缀