Search code examples
iosarraysswiftsearchlongest-substring

Find most common substring from an Array of Strings


I want to search a word from an array of strings.

array = ["ram","gopal","varma","govind","ravan","alan"]

if my search text is goal i want to list as follows:

result = ["gopal","govind","alan"]

ie in gopal & goal only p is missing so it should be in search list with higher priority.

Is there any way to do such filtering?


Solution

  • The longest common subsequence between two strings can be defined recursively as follows :

    func lcs(_ str1: String, _ str2: String, _ i: String.Index, _ j: String.Index) -> Int 
    {
        if (i == str1.startIndex || j == str2.startIndex) {
            return 0
        }
    
        let beforeI = str1.index(before: i)
        let beforeJ = str2.index(before: j)
    
        if str1[beforeI] == str2[beforeJ] {
            return 1 + lcs(str1, str2, beforeI, beforeJ)
        } else {
            return max(lcs(str1, str2, i, beforeJ), lcs(str1, str2, beforeI, j))
        }
    }
    

    You can find a complete explanation of how this dynamic programming algorithm works here.

    So, given an array of strings and a search text :

    let array = ["ram", "gopal", "varma", "govind", "ravan", "alan", "logan"]
    let searchText = "goal"
    

    We can associate a score to each element of the array, filter only those that have a non-zero score, sort them by score, and then only key the words from the tuples :

    let result = array
        .map { ($0, lcs(searchText,
                        $0,
                        searchText.endIndex,
                        $0.endIndex)) }
        .filter { $0.1 > 0 }
        .sorted { $0.1 > $1.1 }
        .map { $0.0 }
    
    print(result)
    

    Which yields :

    ["gopal", "govind", "alan", "logan", "ram", "varma", "ravan"]