我正在尝试构建一种可以在不使用任何预先实现的功能(例如“ sort”等)的情况下在数组中查找重复项的算法。
我没有错误,但是我的功能无法正常工作……您知道为什么吗? (我只是开始Scala编程)
def duplicate(s: Array[Int], length: Int): Boolean = {
var i = 0 // start counting at value 0
var j = 0
var result:Boolean = false
var isDupli:Boolean = false
while(j < length && result == false) {
if (s(i) == s(j)) {
isDupli = true
result = true
}
j += 1
}
result
}
var myArray = Array(2,2,2,2)
duplicate(Array(2,2), 2)
我在线找到了一些代码,但是人们正在使用函数排序。我的目标是滚动数组以查找任何重复项...
答案 0 :(得分:2)
对您的代码的一些观察:
i
,因此您无需检查任何后续元素是否重复。length
参数是多余的,因为我们可以通过Array
(或s
)属性来发现.length
,.size
的长度。使用.length
属性更安全,因为它始终有效。例如,duplicate(Array(1, 2, 3, 4, 5, 3), 10)
会导致异常(java.lang.ArrayIndexOutOfBoundsException
),因为数组没有10个成员。j
初始化为与i
相同的值,然后比较s(i) == s(j)
,因此即使没有第一个元素,也总是要获取第一个元素的重复项数组中的重复项。result
(指示您是否找到了结果),而不是isDupli
(指示您是否找到了重复结果)。幸运的是,我们只需要其中之一,因为找到结果与找到重复项相同。这是解决这些问题并简化某些代码的另一个版本:
def duplicate(s: Array[Int]): Boolean = {
val length = s.length
var i = 0 // start counting at value 0
var foundDuplicate = false // Type inference means Scala knows this is Boolean
// Loop through each member until we've found a duplicate.
//
// Note that "!foundDuplicate" is the same as "foundDuplicate == false"
while(i < length && !foundDuplicate) {
// Now compare to each of the remaining elements. Start at the element above i.
var j = i + 1
// Loop through each of the remaining elements.
while(j < length && !foundDuplicate) {
// If we find a match, we're done.
if (s(i) == s(j)) {
foundDuplicate = true
}
// Look at the next j
j += 1
}
// Look at the next i
i += 1
}
// Return the result. If we didn't find anything, this will still be false.
foundDuplicate
}
val myArray1 = Array(1, 2, 3, 4, 5, 6, 2, 8, 9)
val myArray2 = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)
duplicate(myArray1) // Returns true
duplicate(myArray2) // Returns false
但是,尽管这完全是 procedural 代码,但在 Scala 中,我们可以使用更好的 functional 样式。 (过程代码使用var
s,while
循环等,在 Scala 中不受欢迎。)
import scala.annotation.tailrec
def duplicate(s: Array[Int]): Boolean = {
// Helper function to search the array for matches to element at i
@tailrec // Indicates function is tail recursive.
def matchElement(i: Int): Boolean = {
// Helper function to search for a match in remainder of array.
@tailrec
def matchRem(j: Int): Boolean = {
// If j has reached the end of the array, we had no match.
if(j >= s.length) false
// Otherwise, does this element match the target? Match found.
else if (s(i) == s(j)) true
// Otherwise, look at the next element after j.
else matchRem(j + 1) // Recursive call
}
// If this is the last character of the array, then we can't have a match.
if(i >= s.length - 1) false
// Otherwise did we find a duplicate in the remainder of this array?
else if(matchRem(i + 1)) true
// Otherwise, perform another iteration looking at the next element.
else matchElement(i + 1) // Recursive call
}
// Start the ball rolling by looking at for duplicates of the first character.
matchElement(0)
}
乍一看,这看起来可能很复杂,但是请注意,它没有任何 var
声明或while
循环。当然,这是一个自己动手的解决方案。使用其他Array
函数可以更简单地实现这一目标。
答案 1 :(得分:-1)
在您的代码中,变量isDupli
无用,因为无论如何您都返回result
布尔变量。另外,您不会递增变量i
。您可以如下使用for loop
:
def duplicate(s: Array[Int], length: Int): Boolean ={
var result:Boolean = false; val r = Range(0,length)
for(i<-r;j<-(i+1) until length; if(s(i)==s(j))) result = true
result
}
在Scala REPL中:
scala> duplicate(Array(2,2),2)
res4: Boolean = true
scala> duplicate(Array(2,3),2)
res5: Boolean = false
scala> duplicate(Array(2,3,2),3)
res6: Boolean = true
scala> duplicate(Array(2,3,4),3)
res7: Boolean = false