2010-01-30 73 views
0

什么是忽略字符串中的大小写字母,标点符号和空白字符的最有效方法?这些字符串应该被分成单词而不是字符,应该忽略前面提到的比较细节,并且这些字串的切片应该尽可能高效地记住速度。忽略字符串中的大小写,标点符号和空白字符

我打算在下面的代码中使用大小写不敏感的字符串,但看到评估class Slice: def __eq__(self, other): return self.root == other.root需要多长时间后,我决定改用data = tuple(string.split())。具有对大小写不敏感的字符串,标点符号和间距以及对单词而不是字符的处理对于在下面的代码中已经表达的计算上昂贵的算法来说太昂贵了。

class Slice: 

    def __init__(self, data, offset, length): 
     self.prefix = data[:offset] 
     self.root = data[offset:offset+length] 
     self.suffix = data[offset+length:] 

    def __eq__(self, other): 
     return self.root == other.root 

    def __len__(self): 
     return len(self.root) 

################################################################################ 

class Match: 

    def __init__(self, data, key, prefix_tree, suffix_tree): 
     self.data = data 
     self.key = key 
     self.prefix_tree = prefix_tree 
     self.suffix_tree = suffix_tree 
     self.__value = len(key) + prefix_tree.value() + suffix_tree.value() 

    def value(self): 
     return self.__value 

################################################################################ 

class Tree(tuple): 

    def __new__(cls, nodes): 
     tree = super().__new__(cls, nodes) 
     tree.__value = max(map(Match.value, tree)) if tree else 0 
     return tree 

    def value(self): 
     return self.__value 

    def find(self, value): 
     for index, match in enumerate(self): 
      if match.value() == value: 
       return index 
     raise ValueError() 

################################################################################ 

def search(data, key): 
    length = 0 
    nodes = [] 
    for d_block in shrink(data, len(key)): 
     block_len = len(d_block) 
     if length > block_len: 
      return Tree(nodes) 
     for k_block in slide(key, block_len): 
      if d_block == k_block: 
       length = block_len 
       prefix_tree = search(d_block.prefix, k_block.prefix) 
       suffix_tree = search(d_block.suffix, k_block.suffix) 
       match = Match(d_block, k_block, prefix_tree, suffix_tree) 
       nodes.append(match) 
    return Tree(nodes) 

def shrink(data, max_len): 
    for length in range(min(len(data), max_len), 0, -1): 
     for block in slide(data, length): 
      yield block 

def slide(data, length): 
    for offset in range(len(data) - length + 1): 
     yield Slice(data, offset, length) 

################################################################################ 

def build_tree(nodes): 
    match = nodes[nodes.find(nodes.value())] 
    node = match.key 
    if match.prefix_tree: 
     node.prefix = build_tree(match.prefix_tree) 
    if match.suffix_tree: 
     node.suffix = build_tree(match.suffix_tree) 
    return node 

def flatten_tree(node): 
    array = [0] 
    _flatten(node, array) 
    return tuple(array) 

def _flatten(node, array): 
    if isinstance(node.prefix, Slice): 
     _flatten(node.prefix, array) 
    else: 
     array.append(node.prefix) 
    array[0] += 1 
    array.append((array[0], node.root)) 
    if isinstance(node.suffix, Slice): 
     _flatten(node.suffix, array) 
    else: 
     array.append(node.suffix) 
+0

如果有一些上下文/文档是关于什么类用于... – 2010-01-30 19:54:30

+0

请不要使用'__'作为你的“私人”变量名称。请使用'_':这是更常见的,并且减少我们的大脑阅读代码的压力。 – 2010-01-30 20:25:03

+1

我有点困惑;什么是问题? – mithrandi 2010-01-31 03:15:55

回答

2

“什么是最好的路要走关于解决这个问题?“

最好的唯一的方法是定义这个对象“意味着什么”以及这个对象的长度是什么意思。

该对象似乎是一个单词列表。而已。这似乎是_string中的值。

目前还不清楚_simple是什么,除了在_string中的字不可访问的过滤子集。

那么长度是多少?单词的长度或过滤子集中单词的长度?

只有您可以定义此类意味着。然后含义将确定如何实施__len__。在定义含义之前,不可能确定应该如何实施。

2

如果你想在一个String实例迭代遍历其self.__string,为您__iter__方法表明,对于长度唯一明智的选择也是回归的__string长度 - 这将是真正奇特如果len(x)sum(1 for _ in x)导致不同的值。

我不得不承认,我不明白这个班的目的(特别是为什么你做了这个老式的可怕选择,为什么你用这种扭曲的方式来构建__simple),但内部反正一贯性很重要。因此,要么改变__iter__,要么使__len__在逻辑上与它兼容。

你的切片逻辑也完全逃脱我 - 你为什么要以这种方式构建切片的__simple,这种方式可能与通过从切片的__string重建切片所得到的方式不同?例如,如果self.__string是'?Boh!'因此self.__simple是'boh',你为什么要想要self[1:-1]有一个'Boh'的__string但是'__simple'为'o',所以与__simple不兼容,不同和不一致,通过重新计算得到切片......?

我想这是不有密切关系这种问答关于长度,但我只是好奇你正在做的是,这些很多,非常奇特的设计选择......

+0

自从Python 3.0问世以来,我只用这种语言编写代码(目前是3.1)。如果您熟悉3.1中的类是如何工作的,那么您知道这是一种新式类(Python 3.x中的所有类都是新类)。因此,没有必要显式继承'object'。至于切片是如何工作的,请注意以下这行:'self .__ string = tuple(string.split())'这些字符串对象对字而不是字符起作用。 – 2010-01-31 03:21:54

+0

@Noctis,你已经彻底改变了代码(例如,我再没有看到任何String类!),我无法将我的注释重新连接到当前代码。对于Python 3来说,这很好,但在你的Q中提到它显然会更好,因为*不是*今天绝大多数Python用户正在使用的;-)。 – 2010-01-31 05:27:10

相关问题