我如何将此编程逻辑写入函数方法签名中?我试图循环/遍历数组直到满足条件,然后根据该条件中断。我主要是尽力避免来自 scala.util.control.Breaks
的 var
和 breakable
。它使用闭包(在本例中为字典)来检查是否满足条件/谓词。我的想法是,我循环遍历一个数组,直到满足谓词为止。我还避免将数组转换为列表。使用数组是否不允许我拼接数组,例如进行模式匹配?
val dictionary = Array.fill(128)(false)
def isUnique(array: Array[Char]): Option[Char] = {
// traverse each element of the array {
// if a character.toInt is in the dictionary, insert into dictionary
// exit loop, with the character which broke the loop
// else
// set dictionary(character.toInt) to true and continue looping
// }
}
这是一个示例用例:
val word = "abcdefggghijklmnopqrstuvqxyz".toArray
val charThatBrokeIt = isUnique(word)
编辑:也可以随意建议或提议其他返回类型,例如 bool 值、元组、案例类或任何其他类型。就我而言,Option[Char]
可能不是一个好的结果值。例如。无论循环是否提前(短路)爆发,我都可能返回 false
。
最佳答案
首先,一个String
已经像一个集合了,所以你应该使用 String
而不是Array[Char]
。其次,您可以利用惰性来允许短路,同时仍将算法分成几个部分,使用 .view
.
def breaksUnique(word: String): Option[Char] = {
val cumulativeSets = word.view.scanLeft(Set.empty[Char]){_ + _}
val zipped = cumulativeSets zip word
val nonDupsDropped = zipped dropWhile {case (set, char) => !(set contains char)}
nonDupsDropped.map{_._2}.headOption
}
前两行写起来就好像它们处理整个单词一样,但因为它们对 View 进行操作,所以它们仅根据需要进行计算。
cumulativeSets
是迄今为止所见过的每个字符的集合序列。如果你在“abb”上运行它,你会得到 Set(), Set(a), Set(a,b), Set(a,b)
。使用 zip
与原始单词组合。 ,给予(Set(),a), (Set(a),b), (Set(a,b),b)
。然后,我们只需删除该字符未出现在集合中的所有对,然后返回第一个未删除的元素。
关于arrays - 数组遍历中没有 var 或可破坏的 : How to "break" when a predicate is met,?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47383693/