2017-06-06 113 views
0

我有一个表格,其中包含英语单词列表,我试图选择可以使用给定字符串制作的所有单词"hand"(如在游戏拼字游戏中)选择以任意顺序包含子集字符的行

+--------+ 
| word | 
+--------+ 
| test | 
| father | 
| woman | 
| zebra | 
+--------+ 

我到目前为止的查询只会检查手中是否存在任何字符。

SELECT * FROM words WHERE word SIMILAR to '%e%|%z%|%h%'; 
/* returns test, father and zebra as they all contain either e,z or h */ 

但是这并没有考虑到一个字是否包含字符比手多次呢,我使用python中的代码来检查单词是否有效

def isValidWord(word, hand): 
    """Return true or false can the word be made using the characters in the hand""" 
    for i in word: # for each character in word 
     if hand.count(i)<word.count(i): # is the character in the hand enough times 
      return False 
    return True # if every character in the word is present in the hand 

我的问题我该如何构建一个查询来检查单词中的每个字符并确保该字符的出现次数不超过字符串出现次数? 或者这不是数据库的工作吗?

在此先感谢。

+1

这不是一个(关系)数据库的工作,要坦率地说。 –

+0

是的,我认为可能是这种情况,我是PostgreSQL的新手,我不知道是否有一些内置的方法可以简化它的工作,唉。 –

回答

2

这不是一个(关系型)数据库的工作,要坦率地说。

既然这两千字的英文,即使你把它们吹到所有可以想象的淡出,也不会超过大概10万字,我真的不明白你为什么要用这个数据库。只需用python写一个内存中的单词列表,你就可以简单地通过线性列表。

有几种方法可以更快地搜索数据量,但关系数据库无法应用其中的任何一种。另外,考虑到字母是单个字节的数据,速度增益应该可以忽略不计。

如果你担心性能:是的,在python中这样做确实会产生很大的运行时间开销,因为计数字母非常快并且可以高度优化,但是python本身是一种复杂的语言并且执行它会设置一些限制。

考虑数据量处理是相当小的,我的做法是:

  1. 准备一个单词表:按字母顺序排列在你的字典中的每个单词的字母排序,并使用排序字符串作为真正的单词的关键。你会发现一个排序的字符串可以映射到多个单词。
  2. 排序你的手
  3. 对于你的单词列表每个键的字母,检查它是否是你的手的一个子集。这应该是非常快的,因为之前的排序允许您避免重复检查(即如果您在单词表的开头,第一个单词以a开头,但最低的手字母是e,请跳至第一个单词开头与e)。

任何种类的树结构都可以在算法上更快,但在大多数PC风格的处理器上,编写得很好的C代码将编译为非常快速的SIMD字符串比较。