我正在寻找在给定具有以下逻辑的List [String]时返回true或false的方法。
例如
现在我想要一个函数hasTwoStarts,如果列表中有任何开头,然后是两个中的任何一个,它将返回该函数。这意味着以下任何组合应返回true:
"1 start" "1 start" [A, B, Z, M, A]
"1 start" "2 start" [A, B, Z, C, T]
"2 start" "1 start" [Z, B, C, X, A]
"2 start" "2 start" [B, X, C, M, B, C]
并且如果以上情况均不返回,则返回false
在非功能性情况下,这可以通过脏循环逻辑来实现,但是有没有更好的功能性方法来解决此问题?
还要最小化列表的迭代次数。
答案 0 :(得分:2)
此解决方案仅遍历列表,并在找到解决方案后立即停止。它是尾递归的,因此应该编译成一个简单的循环。
def hasTwoStarts[T](list: List[T]) = {
@annotation.tailrec
def loop(l: List[T], startCount: Int, seenB: Boolean): Boolean = l match {
case _ if startCount == 2 => true
case Nil => false
case h :: t => h match {
case A =>
loop(t, startCount + 1, seenB)
case B =>
loop(t, startCount, true)
case C if seenB =>
loop(t, startCount + 1, false)
case _ =>
loop(t, startCount, seenB)
}
}
loop(list, 0, false)
}
这是解决该问题的非常具体的方法,如果更改了任何“开始”条件,则需要重新进行处理。
答案 1 :(得分:1)
问题似乎有点含糊(至少比public class Model {
private String name;
private String type;
private String string;
public Model(String name, String type, String string) {
this.name = name;
this.type = type;
this.string = string;
}
}
和"1 start"
的名字更好吗?),您可以使用以下代码片段 em>
从这些实用程序方法开始
"2 start"
写一个给出// Utility methods
def endIndexOf1Start(list: List[String], startIndex: Int = 0): Option[Int] = {
val firstIndex: Int = list.indexOf("A", from=startIndex)
if (firstIndex >= 0) Some(firstIndex) else None
}
def endIndexOf2Start(list: List[String], startIndex: Int = 0): Option[Int] = {
lazy val indexOfB: Int = list.indexOf("B", from=startIndex)
lazy val indexOfC: Int = list.indexOf("C", from=indexOfB)
if ((indexOfB >= 0) && (indexOfC > indexOfB)) Some(indexOfC) else None
}
def endIndexOfSomeStart(list: List[String], startIndexOpt: Option[Int] = None): Option[Int] = {
val startIndex: Int = startIndexOpt.getOrElse(0)
lazy val _endIndexOf1Start: Option[Int] = endIndexOf1Start(list, startIndex)
lazy val _endIndexOf2Start: Option[Int] = endIndexOf2Start(list, startIndex)
_endIndexOf1Start.orElse(_endIndexOf2Start)
}
的方法:是否有2个单独的(不重叠)开始
Boolean
提供示例输入
// Final decider method
def containsTwoStarts(list: List[String]): Boolean = {
lazy val endIndexOfFirstStart: Option[Int] = endIndexOfSomeStart(list)
lazy val endIndexOfSecondStart: Option[Int] = endIndexOfSomeStart(list, endIndexOfFirstStart)
(endIndexOfFirstStart.nonEmpty && endIndexOfSecondStart.nonEmpty)
}
这是输入输出示例
// Sample input
val sampleInputs: List[List[String]] = List(
List("A", "B", "Z", "M", "A"),
List("A", "B", "Z", "C", "T"),
List("Z", "B", "C", "X", "A"),
List("B", "X", "C", "M", "B", "C")
)
// invocation sampleInputs.map(l => endIndexOf1Start(l, 0)) sampleInputs.map(l => endIndexOf2Start(l, 0)) sampleInputs.map(l => endIndexOfSomeStart(l, None)) sampleInputs.map(containsTwoStarts)