How to split text without spaces into a list of words using dictionary-based segmentation in Swift

1 Answer

0 votes
/*
    Helper: check if a substring is in the dictionary.
    Uses a simple array of strings and linear search.
*/
func dictContains(_ candidate: String, _ dict: [String]) -> Bool {
    return dict.contains(candidate)
}

/*
    This function performs the segmentation and returns the result.
    It contains your original DP logic exactly as before.
*/
func segmentText(_ text: String, _ dict: [String]) -> [String] {
    let n: Int = text.count
    let chars: [Character] = Array(text)

    // dp[i] = index j such that text[j:i] is a valid word and dp[j] is valid
    var dp: [Int] = Array(repeating: 0, count: n + 1)
    var valid: [Bool] = Array(repeating: false, count: n + 1)

    valid[0] = true // empty prefix is valid

    for i in 1...n {
        for j in 0..<i {
            // Check whether dp[j] contains a valid split point;
            if valid[j] {
                // Create substring text[j:i]
                let candidate = String(chars[j..<i])

                // Verify whether this substring is a valid dictionary word.
                if dictContains(candidate, dict) {
                    dp[i] = j
                    valid[i] = true
                    break // found a valid segmentation ending at i
                }
            }
        }
    }

    // If dp[n] is not valid, segmentation is impossible
    if !valid[n] {
        return []
    }

    // Backtrack to recover words
    var words: [String] = []
    var idx: Int = n

    while idx > 0 {
        let j = dp[idx]
        let w = String(chars[j..<idx])
        words.append(w)
        idx = j
    }

    // Reverse the collected words
    return words.reversed()
}

/* Example usage */
let text = "thisisatestfoo"

let dict = [
    "this", "is", "a", "test", "hello", "world", "foo", "bar"
]

let words = segmentText(text, dict)

print("Segmentation result:")
for w in words {
    print(w)
}



/*
run:

Segmentation result:
this
is
a
test
foo

*/

 



answered Sep 8 by avibootz

Related questions

...