给定字典列表和输入字,如果输入字的长度与字典中的词汇长度相同,则返回true。
dictionary = ["apple", "testing", "computer"];
singleType(dictionary, "adple") // true
singleType(dictionary, "addle") // false
singleType(dictionary, "apple") // false
singleType(dictionary, "apples") // false
如果我们忽略hashmap所需的预处理时间,我提出了一个在线性时间内运行的解决方案。
O(k*26) => O(k)
,其中k = length of the input word
我的线性解决方案就像将字典列表转换为哈希映射,其中键是单词,值是布尔值,然后遍历输入单词中的每个字符,并用1替换每个字符26字母并检查它是否映射到哈希图。
但是他们说我可以比O(k*26)
做得更好,但是怎么做?
答案 0 :(得分:2)
您可以使用包含单个拼写错误的单词的所有变体扩展字典,但是您只需添加一些"通配符"而不是实际拼写错误。该地方的?
或*
字符。然后,您可以检查(a)单词是否在正确拼写的单词集中,以及(b)用相同的通配符替换单词中的任何字母,该单词可以在具有相同通配符的单词集中找到一个错字。
Python中的示例:
>>> dictionary = ["apple", "testing", "computer"]
>>> wildcard = lambda w: [w[:i]+"?"+w[i+1:] for i in range(len(w))]
>>> onetypo = {x for w in dictionary for x in wildcard(w)}
>>> correct = {w for w in dictionary}
>>> word = "apxle"
>>> word not in correct and any(w in onetypo for w in wildcard(word))
True
这将查找的复杂性降低到仅O(k),即仍然是字母数的线性,但没有高常数因子。然而,它确实使字典大大夸大了一个等于单词中平均字母数的因子。
答案 1 :(得分:1)
对于单个查找,我将按字长过滤字典,然后一旦错误计数> 1,就迭代字,计算错误,并挽救每个字。 1.
val dictionary = List ("affen", "ample", "apple", "appse", "ipple", "appl", "pple", "mapple", "apples")
@annotation.tailrec
def oneError (w1: String, w2:String, err: Int) : Boolean = w1.length match {
case 0 => err == 1
case _ => if (err > 1) false else {
if (w1(0) == w2(0)) oneError (w1.substring (1), w2.substring (1), err) else
oneError (w1.substring (1), w2.substring (1), err + 1)
}
}
scala> dictionary.filter (_.length == 5).filter (s => oneError ("appxe", s, 0))
res5: List[String] = List(apple, appse)
为了处理更长的文本,我会预处理字典并将其拆分为地图(word.length - > List(words))。
对于高度冗余的自然语言,我会从文本中构建一组唯一的单词,只查找一次单词。
对于单字查找,最坏的情况是对初始函数的n次调用,其中n = max(dictionary.groupBy(w.length))。
每个单词查找(单词长1)将至少执行2步直到失败,但大多数单词(假设没有病态输入和字典)仅访问2个步骤。从剩下的那些,大多数被排除在3个步骤之后,依此类推。
这是一个版本,显示它看起来有多深:
def oneError (word: String) : Array[String] = {
@tailrec
def oneError (w1: String, w2:String, steps: Int, err: Int) : Boolean = w1.length match {
case 0 => {print (s"($steps) "); err == 1}
case _ => if (err > 1) {print (s"$steps "); false } else {
if (w1(0) == w2(0)) oneError (w1.substring (1), w2.substring (1), steps +1, err) else
oneError (w1.substring (1), w2.substring (1), steps + 1, err + 1)
}
}
val d = dict (word.length)
println (s"Info: ${d.length} words of same length")
d.filter (entry => oneError (word, entry, 0, 0))
}
示例输出,编辑:
scala> oneError ("fuck")
Info: 3352 words of same length
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 (4) 3 3 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 (4) (4) 3 3 3 3
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 3 3 (4) (4) 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
3 3 3 3 3 3 (4) 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
3 (4) (4) (4) (4) (4) (4) (4) (4) (4) (4) (4) (4) (4) (4) 3 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 (4) (4) 3 3 3 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
3 3 3 (4) 3 3 2 2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 (4) 3 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
res53: Array[String] = Array(Buck, Huck, Puck, buck, duck, funk, luck, muck, puck, suck, tuck, yuck)
答案 2 :(得分:0)
听起来你正在寻找关于字典条目的模式1的编辑距离。例如,如果模式为“adple”且字典条目为“apple”,则会导致编辑距离为1。您还有一个额外的约束,即模式与字典条目的长度相同,但这很容易实现。