簡體   English   中英

統一Swift中的數組和數組切片

[英]Unify Arrays and Array Slices in Swift

我是Swift的新手,也是Apple編程的新手。 我寫了這段代碼來進行二分查找。

func binarySearch<X:Comparable> (needle:X, haystack:[X])->X? {
    if haystack.isEmpty { return nil }
    let mid = haystack.count / 2
    let found = haystack[mid]
    if found == needle {
        return needle
    }
    else if found < needle {
        return binarySearch(needle, haystack[0..<mid])
    }
    else {
        return binarySearch(needle, haystack[mid+1..<haystack.count])
    }
}

我在遞歸調用上遇到語法錯誤,因為第二個參數是ArraySlice<X>而不是Array<X>

我通過使用相同的版本重載binarySearch來解決這個問題,除了第二個參數是ArraySlice<X>類型。

如果它可以在一個函數中完成,我認為它會更優雅。 是否有合適的類型統一Array和ArraySlice? 我嘗試使用ArrayLiteralConvertible<X>但由於某些原因沒有count成員。 我在文檔中找到自己的方法仍然有點麻煩,所以我可能很容易忽略一個更好的選擇。

你能建議一個好方法嗎? 如果它涉及使用內置類,你可以給我一個關於如何為自己下次找到它的提示,而不是寫給SO嗎?

要解決您的初始問題,請使用切片調用Array構造函數以獲取數組:

func binarySearch<X:Comparable> (needle:X, haystack:[X])->X? {
    if haystack.isEmpty { return nil }
    let mid = haystack.count / 2
    let found = haystack[mid]
    if found == needle {
        return needle
    }
    else if needle < found {
        return binarySearch(needle, Array(haystack[0..<mid]))
    }
    else {
        return binarySearch(needle, Array(haystack[mid+1..<haystack.count]))
    }
}

此外,您的情況應該是if needle < found

是的,Array / ArraySlice很煩人。 您需要的基本通用要求在問題中詳細說明。 但是,為了滿足您的要求,不幸的是,您必須獲得一些非常可怕的功能簽名。 但是可能:

func bSearch<
  S : Sliceable where S.SubSlice : Sliceable,
  S.SubSlice.Generator.Element == S.Generator.Element,
  S.SubSlice.SubSlice == S.SubSlice,
  S.Generator.Element : Comparable,
  S.Index : IntegerArithmeticType,
  S.Index : IntegerLiteralConvertible,
  S.SubSlice.Index == S.Index
  >(el: S.Generator.Element, list: S) -> S.Generator.Element? {

    if list.isEmpty { return nil }

    let midInd = list.endIndex / 2

    let midEl: S.Generator.Element = list[midInd] // type inference giving me some bugs here

    if midEl == el {
      return el
    }

    return midEl < el ?
      bSearch(el, list: list[midInd+1..<list.endIndex]) :
      bSearch(el, list: list[0..<midInd])
}

而對於Swift 1.2,只需更換機身:

if isEmpty(list) { return nil }

let midInd = list.endIndex / 2

let midEl: S.Generator.Element = list[midInd] // type inference giving me some bugs here

if midEl == el {
  return el
}

return midEl < el ?
  bSearch(el, list[midInd+1..<list.endIndex]) :
  bSearch(el, list[0..<midInd])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM