newb:comapring两个字符串

你好, 是否有一种聪明的方式来查看两个相同长度的串是否有所不同 只有一个角色,以及两个字符串中的角色. 例如. str1 = yaqtil str2 = yaqtel 它们在str1 [4]上有所不同,区别是('i','e') 但是,如果有str1 = yiqtol和str2 = yaqtel,我不感兴趣. 谁能建议这样做的简单方法? 我的下一个问题是,我有300,000多个单词的列表,我想找到 每对这样的字符串. 我以为我会首先排序 字符串,但是如何迭代以下内容: str1 str2 str3 str4 str5 这样我比较了str1&str2,str1&str3,str 1&str4,str1&str5, str2&str3,str3&str4,str3&str5,str4&str5. 提前致谢, 马修

# 回答1

>是否有一种聪明的方法来查看两个相同长度的串是否有所不同 装饰零件是这样的 l = <字符串列表> l = [(len(w),w)对于w中的w] L.Sort() l = [w for _,w in L] diez
# 回答2

曼斯蒂写道: 这样的东西也许? - - - 贾斯汀
# 回答3

曼斯蒂写道: 如果您的琴弦很短,您也可以这样做 首先按长度分类: def fuzzy_keys(s): 对于范围(len(s))的POS: 屈服S [0:pos]+chr(0)+s [pos+1:] def fuzzy_insert(d,s): 对于fuzzy_keys中的fuzzy_key(s): 如果D中的fuzzy_key: strings = d [fuzzy_key] 如果类型(字符串)为列表: 字符串 += S 别的: d [fuzzy_key] = [Strings,s] 别的: D [fuzzy_key] = S def gather_fuzzy_matches(d): 对于D.Itervalues()中的字符串: 如果类型(字符串)为列表: 屈服字符串 ACC = {} fuzzy_insert(acc," yaqtel") fuzzy_insert(acc," yaqtil") fuzzy_insert(ACC," OAQTIT") 打印列表(gather_fuzzy_matches(ACC)) 印刷 [['yaqtil','oaqtil'],['yaqtel','yaqtil']](_@_ _) 曼斯蒂写道: 对于Xrange(len(wist))中的index1: 对于Xrange中的index2(index1+1,len(单词)): 如果diffbyonlyone(单词[index1],单词[index2]): 打印单词[index1] +" - " +单词[index2] ....但是一定要运行,只能在您拥有 已经根据某些标准(例如单词长度)确定了 可能匹配. 算一算; 这是很多比较!
# 回答4

" manstey" 在消息中写道 新闻:11 ****************************************************************************************** 错误的 这利用了真正评估为1的Python公约 错误评估为0. - 保罗
# 回答5

" Paul McGuire" 写道:... return len(a)== len(b)和sum(map(lambda(x,y):x == y) ,zip(a,b))))> = len(a)-1 是的! 怎么样(未经测试): DEF OFFBYNOMORETHANONECHARACTER(A,B): 返回len(a)== len(b)和\ len([i for i in xrange(len(a))如果a [i]!= b [i]])<= 1 这似乎更直接. 我不确定这是正确的 考虑"苹果"和"苹果"是一个角色,即使 它们的长度不平等. 但是我认为这种功能对于手头的问题没有用, 由于大约有n = 300,000个单词,因此比较它们中的每对 是o(n ** 2),有点痛苦. ID 使用以下装饰量不合格的方法: #生成所有方法 def generate_all_variants(word): wlower = word.lower() 产量(wlower,word) 对于i在Xrange(len(word))中的我: 产量(wlower [:i] + wlower [i + 1:],word) 用它来生成所有单词的所有变体 字典,然后将它们写入文件,每行包含一个 变体加原始单词. 然后使用分类实用程序 UNIX"分类"程序来对文件进行排序. 这些程序有效地工作 即使文件太大而无法容纳内存. 然后阅读排序 文件以在变体上找到等价类.
# 回答6

曼斯蒂写道: 不确定它是否可以处理300000个单词,但这是可以玩的. 导入系统 def find_similars(单词,查找= none,dupes = none): 如果查找没有: 查找= {} 如果骗子没有: dupes = set() 用单词词: low_word = word.lower() 如果Low_word不在骗子中: dupes.add(low_word) 最后=无 对于i,c中的c(low_word): 如果C ==最后:继续 key = low_word [:i],low_word [i+1:] 如果在查找中关键: 查找[key] .append(word) 别的: 查找[key] = [word] 最后= c 返回(如果Len(group)> 1)在Lookup.itervalues()中组的组) def main(): 导入Optparse parser = optparse.optionparser() parser.usage +=" infile [s]" parser.add_option(" - n"," - limit",type =" int",help ="最多都 限制单词") 选项,args = parser.parse_args() 如果args: 单词=(w.strip()for for在open(fn)中为w的args中的fn) 别的: 单词=(w.strip()对于sys.stdin中的W) 如果options.limit不是没有: 从Itertools Import Islice 单词= islice(单词,max_len) 对于find_similars(单词)中的组: 打印"" .join(排序(组)) 如果__name__ ==" __ -main __": 主要的() 彼得
# 回答7

>使用Levenshtein距离. 鉴于两个字符串的长度相同,我 假设(如其他海报似乎已经完成了),"只有一个 字符"排除插入和删除操作. 在这种情况下,可以通过简单的循环在O(n)时间中解决问题 这计算了差异的数量,并记录了 首先(如果有)差异. 任何全距离列文申的方法 没有预处理必须花费O(n ** 2)时间. 可以采取 OP不在乎距离的事实的优势 确切的是不是1; 0与2、3、4等一样糟糕. 情况可以实现O(n)时间[参考. UKKONEN]. 但是(a) 仍然需要跟踪我们正在谈论的差异(b) 关于OP问题的极端过度杀伤.
# 回答8

" John Machin" 在消息中写道 新闻:11 ****************************@j73g2000cwa.googlegroups.com ... 这是一个实现4种不同方法的课程 问题,具有可配置数量的最大不匹配(其中A和B为 比较字符串): 1.使用sum(map(lambda(x,y):x!= y,itertools.izip(a,b)))进行计数 不匹配 - 无短路 2.使用总和(ABS(ABS,ITE) rtools.starmap(cmp,itertools.izip(a,b))))) 不匹配 - 无短路 3.使用明确循环比较从 itertools.izip(a,b) - 当不匹配数量超过数量时,短路 允许的数字 4.使用iTertool的循环.当时计数不匹配 - 当不匹配数量超过允许数量时,短路 还要注意初始化器中的短路 - 如果字符串为 比较的长度比允许的不匹配的数量短,而不是 它们将始终匹配,无需比较. (在OP的具体情况下 情况,任何两个单字符串都将在一个字符中匹配). 当然,这无助于解决该计划的更大问题 设计 - 我只是想了解更多有关Itertools的信息. :) - 保罗 从Itertools导入IZIP,Starmap,请 offbynomorethanonecharacter(对象): def __init __(self,a,b,maxmismatches = 1): len_a = len(a) self.val =无 如果len_a!= len(b): self.val = false elif len_a <= maxMismatches: self.val = true 别的: self.a = a self.b = b self.maxmismatches = maxmismatches def eval1(self): #使用lambda的地图单线 - 总和计数不匹配 self.val = sum(map(lambda(x,y):x!= y,izip(self.a,self.b)))<= = self.maxmismatches def eval2(self): #使用abs和cmp的地图单线 - 总和计数不匹配不匹配 self.val = sum(map(abs,starmap(cmp,izip(self.a,self.b)))))<= self.maxmismatches def eval3(self): #显式遍历,当不匹配太多时带有短路 成立 不匹配= 0 对于(AC,BC),IZIP(self.A,self.b): 如果AC!= BC: 不匹配 += 1 如果不匹配> self.maxmismistes: self.val = false 休息 别的: self.val = true def eval4(self): #使用take的遍历,也是短路时的短路 发现不匹配 NumMismatches = 0 maxMismatches = self.maxmismatches stilok = lambda(s,t)=(无,无):nummismatches <= maxMismatches 对于(AC,BC),在Take(Stillok,izip(self.a,self.b))中: Nummismatches +=(AC!= BC) self.val = stillok() #特殊实例方法返回此对象的"布尔值" def __nonzero __(self): 如果self.val无: #更改此行以使用您要测试的任何评估方法 self.eval1() 返回self.val DEF测试(A,B): 打印A,B 印刷布尔(Offbynomorethanonecharacter(a,b)) 打印 测试(" ABC"," ABD") 测试(" ABC"," AXD") 测试(" Yaqtil"," Yaqtel") test(" yiqtol"," yaqtel")
# 回答9

我认为解决问题的一种方法可能是: 1)创建一个小python脚本以在许多人中分开原始单词 文件,每个文件仅包含相同长度的单词. 每一个 文件名可以包含相对单词长度. 2)用两个嵌套循环编写一个小C程序,扫描所有 对单个文件的单词对,寻找单个字符 使用字符扫描的差异. 可能有很多 可能会加快此搜索的可能技巧(例如将单词分开 亚组,使用一些装配衍生的技巧等),但也许您 不需要它们. 作为C数据结构,您可以模拟 使用一个块 (因为您知道一个单词的长度,所以 Python可以没有空间和返回). 我建议c,因为如果单词的长度相同,那么 您有30000^2 = 90 000 000 000对进行测试. 如果需要,在创建C程序之前,您可以创建一点 python+psyco prototype使用阵列. 有时Psyco很快使用它们). 再见, 熊
# 回答10

>我建议c,因为如果单词的长度相同,则 抱歉,您有(n*(n-1))/2对测试(〜45 000 000 000). bearophile
# 回答11

bedeydebeyde*******@lycos.com写道:对不起,您有(n*(n-1))/2对测试(〜45 000 000 000) . 仍然很糟糕. 使用更好的算法!
# 回答12

保罗·鲁宾(Paul Rubin)写道: 抱歉,您有(n*(n-1))/2对测试(〜45 000 000 000). 仍然很糟糕. 使用更好的算法! 为了将所有这些视角介绍,这是一个非常相似的现实世界 问题: 您有一个带有300,000个记录的客户数据库. 他们之中有一些是 复制,因为记录客户的记录有差异 名称,例如单键式错别字. 任务是找到一对行 可能是重复的. 450亿个comaprisons [1] 爱情. 这是一种更好的算法的线索:Knuth的Taocp Vol 3 [1973 版本]第6章(搜索)第三页"好像单词是拼写的 向后".如果您发现自己在阅读Soundex,那么 绝对走得太远了:-) [1]:主题中的" comapring":这是一场'现场的游戏 错误"?OP计数相邻字符的换位是 "因一个角色而变化"? 欢呼
# 回答13

保罗·鲁宾(Paul Rubin)>仍然可怕. 使用更好的算法!< 我同意,这是O(n^2),但是如果您只需要1次运行此程序, 该程序在C中,您不想花很多时间思考 并编码更好的算法(或者您无法做到) 幼稚的解决方案可以足够(如果运行时间约为30-90 分钟). 解决单一问题的总时间通常是思维的总和 时间 +编程时间 +运行时间:-) Paul Rubin>使用它来生成所有单词的所有变体 词典,然后将它们写入一个文件中,每行包含一个 变体加原始单词. 然后使用分类实用程序 UNIX"分类"程序来对文件进行排序. 这些程序有效地工作 即使文件太大而无法容纳内存. 然后阅读排序 文件以在变体上找到等价类.<< 如果这些单词都是5个字符,那么我认为您正在创建: (len(小写)-1) * 5 * 30000 = 3750000 Len 5+5的字符串(加上将其保存到文件中),这意味着 大约37 MB的文件. 如果您 有很多. 您的解决方案看起来不错:-)(这使我想起了一些词签名 用于查找Anagrams的技巧). 再见, 熊

标签: python

添加新评论