Игнорирование случая, пунктуации и пробелы в струнах

StackOverflow https://stackoverflow.com/questions/2169170

  •  24-09-2019
  •  | 
  •  

Вопрос

Какой самый эффективный способ игнорирования случая, пунктуации и пробела в строках? Эти строки следует разделить словами вместо персонажей, следует игнорировать вышеупомянутые детали на сравнениях, а ломтики этих слов-строк должны быть максимально эффективными со скоростью со скоростью.

Я собирался использовать корпус и пременную нечувствительные строки для следующего кода, но после просмотра, сколько времени потребуется для оценки 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)
Это было полезно?

Решение

«Какой лучший способ понять эту проблему?»

Лучший - и только - путь - это определить, что этот объект «означает» и какая длина этого объекта «означает».

Объект, по-видимому, является список слов. Больше ничего. Это кажется ценностью в _string.

Это не ясно, что _simple это, кроме недоступного фильтрованного подмножества слов в _string.

Так в чем же длина? Длина слова или длина слов в отфильтрованном подмножестве?

Только вы можете определить, что этот класс означает. Отказ То имея в виду Затем определите, как реализовать __len__. Отказ Пока вы не определите смысл, невозможно определить, как все должно быть реализовано.

Другие советы

Если вы хотите итерацию на строке экземпляра, чтобы повторить его self.__string, как твой __iter__ Способ указывает, единственный разумный выбор для длины также для возврата длины __string -- это было бы действительно свойственный, если len(x) а также sum(1 for _ in x) привело к разным ценностям.

Я должен признать, что я не понимаю цели этого класса (и, в частности, почему вы сделали ужасный выбор наличия его старого стиля, и почему вы используете такой арендуемый способ построить __simple), но внутренняя консистенция важна в любом случае. Итак, либо изменить __iter__, или сделать __len__ логически совместим с этим.

Ваша логика нарезки также полностью избегает - почему вы строите ломтик __simple таким образом, что, вероятно, отличается от того, что вы получите, восстановив его с ломтика __string? Например, если self.__string '? BOH!' и поэтому self.__simple это «бо», почему бы вы хочу self[1:-1] иметь __string «БО», но с __simple «о», так несовместимых, разных и несовместимых от __simple Вы бы пересматривали его с ломтика ...?

Я думаю, это не герман к этому q о длине, но мне просто интересно эти многочисленные, чрезвычайно своеобразные варианты дизайна, которые вы делаете ...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top