Repo // Megrez v2.0.2 update.
This commit is contained in:
parent
d0df22b5d4
commit
e20f95c4b5
|
@ -223,34 +223,6 @@ extension Array where Element == Megrez.Compositor.Node {
|
|||
}
|
||||
return counter
|
||||
}
|
||||
|
||||
public func findNode(at cursor: Int, target outCursorPastNode: inout Int) -> Megrez.Compositor.Node? {
|
||||
guard !isEmpty else { return nil }
|
||||
let cursor = Swift.max(0, Swift.min(cursor, keys.count))
|
||||
|
||||
if cursor == 0, let theFirst = first {
|
||||
outCursorPastNode = theFirst.spanLength
|
||||
return theFirst
|
||||
}
|
||||
|
||||
// 同時應對「游標在右端」與「游標離右端還差一個位置」的情形。
|
||||
if cursor >= keys.count - 1, let theLast = last {
|
||||
outCursorPastNode = keys.count
|
||||
return theLast
|
||||
}
|
||||
|
||||
var accumulated = 0
|
||||
for neta in self {
|
||||
accumulated += neta.spanLength
|
||||
if accumulated > cursor {
|
||||
outCursorPastNode = accumulated
|
||||
return neta
|
||||
}
|
||||
}
|
||||
|
||||
// 下述情形本不應該出現。
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Private Methods
|
||||
|
|
|
@ -13,7 +13,7 @@ extension Megrez {
|
|||
/// 簡單的貝氏推論:因為底層的語言模組只會提供單元圖資料。一旦將所有可以組字的單元圖
|
||||
/// 作為節點塞到組字器內,就可以用一個簡單的有向無環圖爬軌過程、來利用這些隱性資料值
|
||||
/// 算出最大相似估算結果。
|
||||
public class Compositor {
|
||||
public struct Compositor {
|
||||
/// 就文字輸入方向而言的方向。
|
||||
public enum TypingDirection { case front, rear }
|
||||
/// 軌格增減行為。
|
||||
|
@ -51,7 +51,7 @@ extension Megrez {
|
|||
self.separator = separator
|
||||
}
|
||||
|
||||
public func clear() {
|
||||
public mutating func clear() {
|
||||
cursor = 0
|
||||
keys.removeAll()
|
||||
spans.removeAll()
|
||||
|
@ -62,7 +62,7 @@ extension Megrez {
|
|||
/// 在游標位置插入給定的索引鍵。
|
||||
/// - Parameter key: 要插入的索引鍵。
|
||||
/// - Returns: 該操作是否成功執行。
|
||||
@discardableResult public func insertKey(_ key: String) -> Bool {
|
||||
@discardableResult public mutating func insertKey(_ key: String) -> Bool {
|
||||
guard !key.isEmpty, key != separator, langModel.hasUnigramsFor(key: key) else { return false }
|
||||
keys.insert(key, at: cursor)
|
||||
resizeGrid(at: cursor, do: .expand)
|
||||
|
@ -77,7 +77,7 @@ extension Megrez {
|
|||
/// 如果是朝著與文字輸入方向相反的方向砍的話,游標位置會自動遞減。
|
||||
/// - Parameter direction: 指定方向(相對於文字輸入方向而言)。
|
||||
/// - Returns: 該操作是否成功執行。
|
||||
@discardableResult public func dropKey(direction: TypingDirection) -> Bool {
|
||||
@discardableResult public mutating func dropKey(direction: TypingDirection) -> Bool {
|
||||
let isBackSpace: Bool = direction == .rear ? true : false
|
||||
guard cursor != (isBackSpace ? 0 : keys.count) else { return false }
|
||||
keys.remove(at: cursor - (isBackSpace ? 1 : 0))
|
||||
|
@ -90,7 +90,7 @@ extension Megrez {
|
|||
/// 按幅位來前後移動游標。
|
||||
/// - Parameter direction: 移動方向。
|
||||
/// - Returns: 該操作是否順利完成。
|
||||
@discardableResult public func jumpCursorBySpan(to direction: TypingDirection) -> Bool {
|
||||
@discardableResult public mutating func jumpCursorBySpan(to direction: TypingDirection) -> Bool {
|
||||
switch direction {
|
||||
case .front:
|
||||
if cursor == width { return false }
|
||||
|
@ -158,7 +158,7 @@ extension Megrez.Compositor {
|
|||
/// - Parameters:
|
||||
/// - location: 給定的幅位座標。
|
||||
/// - action: 指定是擴張還是縮減一個幅位。
|
||||
func resizeGrid(at location: Int, do action: ResizeBehavior) {
|
||||
mutating func resizeGrid(at location: Int, do action: ResizeBehavior) {
|
||||
let location = max(min(location, spans.count), 0) // 防呆
|
||||
switch action {
|
||||
case .expand:
|
||||
|
@ -255,7 +255,7 @@ extension Megrez.Compositor {
|
|||
}
|
||||
}
|
||||
|
||||
func updateCursorJumpingTables(_ walkedNodes: [Node]) {
|
||||
mutating func updateCursorJumpingTables(_ walkedNodes: [Node]) {
|
||||
var cursorRegionMapDict = [Int: Int]()
|
||||
cursorRegionMapDict[-1] = 0 // 防呆
|
||||
var counter = 0
|
||||
|
|
|
@ -11,7 +11,7 @@ extension Megrez.Compositor {
|
|||
/// 對於 `G = (V, E)`,該算法的運行次數為 `O(|V|+|E|)`,其中 `G` 是一個有向無環圖。
|
||||
/// 這意味著,即使軌格很大,也可以用很少的算力就可以爬軌。
|
||||
/// - Returns: 爬軌結果+該過程是否順利執行。
|
||||
@discardableResult public func walk() -> ([Node], Bool) {
|
||||
@discardableResult public mutating func walk() -> ([Node], Bool) {
|
||||
var result = [Node]()
|
||||
defer {
|
||||
walkedNodes = result
|
||||
|
|
|
@ -144,13 +144,17 @@ extension Megrez.Compositor {
|
|||
guard let overridden = overridden else { return false } // 啥也不覆寫。
|
||||
|
||||
for i in overridden.spanIndex..<min(spans.count, overridden.spanIndex + overridden.node.spanLength) {
|
||||
/// 咱們還得重設所有在相同的幅位座標的節點。舉例說之前爬軌的結果是「A BC」
|
||||
/// 咱們還得弱化所有在相同的幅位座標的節點的複寫權重。舉例說之前爬軌的結果是「A BC」
|
||||
/// 且 A 與 BC 都是被覆寫的結果,然後使用者現在在與 A 相同的幅位座標位置
|
||||
/// 選了「DEF」,那麼 BC 的覆寫狀態就有必要重設(但 A 不用重設)。
|
||||
arrOverlappedNodes = fetchOverlappingNodes(at: i)
|
||||
for anchor in arrOverlappedNodes {
|
||||
if anchor.node == overridden.node { continue }
|
||||
if !overridden.node.key.contains(anchor.node.key) || !overridden.node.value.contains(anchor.node.value) {
|
||||
anchor.node.reset()
|
||||
continue
|
||||
}
|
||||
anchor.node.overridingScore /= 2
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
|
|
@ -17,8 +17,8 @@ extension Megrez.Compositor {
|
|||
/// [("a", -114), ("b", -514), ("c", -1919)] 的話,指定該覆寫行為則會導致該節
|
||||
/// 點返回的結果為 ("c", -114)。該覆寫行為多用於諸如使用者半衰記憶模組的建議
|
||||
/// 行為。被覆寫的這個節點的狀態可能不會再被爬軌行為擅自改回。該覆寫行為無法
|
||||
/// 防止其它節點被爬軌函式所支配。這種情況下就需要用到 kOverridingScore
|
||||
/// - withHighScore: 將該節點權重覆寫為 kOverridingScore,使其被爬軌函式所青睞。
|
||||
/// 防止其它節點被爬軌函式所支配。這種情況下就需要用到 overridingScore
|
||||
/// - withHighScore: 將該節點權重覆寫為 overridingScore,使其被爬軌函式所青睞。
|
||||
public enum OverrideType: Int {
|
||||
case withNoOverrides = 0
|
||||
case withTopUnigramScore = 1
|
||||
|
@ -32,7 +32,7 @@ extension Megrez.Compositor {
|
|||
/// 找出「A->bc」的爬軌途徑(尤其是當 A 和 B 使用「0」作為複寫數值的情況下)。這樣
|
||||
/// 一來,「A-B」就不一定始終會是爬軌函式的青睞結果了。所以,這裡一定要用大於 0 的
|
||||
/// 數(比如野獸常數),以讓「c」更容易單獨被選中。
|
||||
public static let kOverridingScore: Double = 114_514
|
||||
public var overridingScore: Double = 114_514
|
||||
|
||||
private(set) var key: String
|
||||
private(set) var keyArray: [String]
|
||||
|
@ -81,7 +81,7 @@ extension Megrez.Compositor {
|
|||
public var score: Double {
|
||||
guard !unigrams.isEmpty else { return 0 }
|
||||
switch overrideType {
|
||||
case .withHighScore: return Megrez.Compositor.Node.kOverridingScore
|
||||
case .withHighScore: return overridingScore
|
||||
case .withTopUnigramScore: return unigrams[0].score
|
||||
default: return currentUnigram.score
|
||||
}
|
||||
|
@ -139,4 +139,45 @@ extension Array where Element == Megrez.Compositor.Node {
|
|||
|
||||
/// 從一個節點陣列當中取出目前的索引鍵陣列。
|
||||
public var keys: [String] { map(\.key) }
|
||||
|
||||
/// 在陣列內以給定游標位置找出對應的節點。
|
||||
/// - Parameters:
|
||||
/// - cursor: 給定游標位置。
|
||||
/// - outCursorPastNode: 找出的節點的前端位置。
|
||||
/// - Returns: 查找結果。
|
||||
public func findNode(at cursor: Int, target outCursorPastNode: inout Int) -> Megrez.Compositor.Node? {
|
||||
guard !isEmpty else { return nil }
|
||||
let cursor = Swift.max(0, Swift.min(cursor, keys.count))
|
||||
|
||||
if cursor == 0, let theFirst = first {
|
||||
outCursorPastNode = theFirst.spanLength
|
||||
return theFirst
|
||||
}
|
||||
|
||||
// 同時應對「游標在右端」與「游標離右端還差一個位置」的情形。
|
||||
if cursor >= keys.count - 1, let theLast = last {
|
||||
outCursorPastNode = keys.count
|
||||
return theLast
|
||||
}
|
||||
|
||||
var accumulated = 0
|
||||
for neta in self {
|
||||
accumulated += neta.spanLength
|
||||
if accumulated > cursor {
|
||||
outCursorPastNode = accumulated
|
||||
return neta
|
||||
}
|
||||
}
|
||||
|
||||
// 下述情形本不應該出現。
|
||||
return nil
|
||||
}
|
||||
|
||||
/// 在陣列內以給定游標位置找出對應的節點。
|
||||
/// - Parameter cursor: 給定游標位置。
|
||||
/// - Returns: 查找結果。
|
||||
public func findNode(at cursor: Int) -> Megrez.Compositor.Node? {
|
||||
var useless = 0
|
||||
return findNode(at: cursor, target: &useless)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue