Структура данных или алгоритм для вторых поисков градуса в подлинейное время?

Попробуйте это так:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:edocu="http://www.edocu.com"
exclude-result-prefixes="edocu">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:variable name="new-namespace" select="concat('http://www.asdf.no/eDocu/', //edocu:eDocuID)"/>

<xsl:template match="*">
    <xsl:element name="{name()}" namespace="{$new-namespace}">
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

<xsl:template match="edocu:address">
    <xsl:element name="address" namespace="{$new-namespace}">
        <xsl:apply-templates/>
        <xsl:element name="new_element" namespace="{$new-namespace}">
            <xsl:value-of select="edocu:address_Street"/>
            <xsl:value-of select="edocu:address_Number"/>
            <xsl:value-of select="edocu:address_Letter"/>
        </xsl:element>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>
5
задан Steven 26 December 2015 в 19:30
поделиться

4 ответа

Для соединений как это на больших наборах данных современный RDBMS будет часто использовать алгоритм, названный слиянием списка. Используя Ваш пример:

  1. Подготовьте список, A, всех авторов, которые живут в Чикаго и сортируют их по автору в O (Nlog (N)) время.*
  2. Подготовьте список, B, всех (автор, название книги) пары и отсортируйте их по автору в O (Mlog (M)) время.*
  3. Поместите эти два списка "рядом" и сравните авторов от "вершины" (лексикографически минимальный) элемент в каждой груде.
    • Действительно ли они - то же? Раз так:
      • Произведите (автор, название книги) пара от top(B)
      • Удалите вершину груды B
      • Goto 3.
    • Иначе, top(A).author < top(B).author? Раз так:
      • Удалите вершину груда
      • Goto 3.
    • Иначе это должно быть это top(A).author > top(B).author:
      • Удалите вершину груды B
      • Goto 3.

* (Или O (0) время, если таблица уже отсортирована по автору или имеет индекс, который является.)

Цикл продолжает удалять один объект за один раз, пока обе груды не пусты, таким образом беря O (N + M) шаги, где N и M являются размерами груд A и B соответственно. Поскольку две "груды" отсортированы по автору, этот алгоритм обнаружит каждую пару соответствия. Это не требует индекса (хотя присутствие индексов может устранить необходимость одной или обеих операций вида в запуске).

Обратите внимание, что RDBMS может выбрать другой алгоритм (например, простой, который Вы упомянули), если бы он оценивает, что это было бы быстрее, чтобы сделать так. Анализатор запроса RDBMS обычно оценивает затраты с точки зрения доступов к диску и процессорное время для многих тысяч разных подходов, возможно принимая во внимание такую информацию как статистические дистрибутивы значений в соответствующих таблицах, и выбирает лучшее.

2
ответ дан 14 December 2019 в 19:28
поделиться

Инвертированный индекс.

Так как это имеет цикл, я уверен, что он приводит O к сбою (n) тест. Однако, когда Ваш набор результатов имеет n строки, невозможно постараться не выполнять итерации по набору результатов. Запрос, однако, является двумя поисками хеша.

from collections import defaultdict

country = [ "England", "USA" ]

author=  [ ("Milton", "England"), ("Shakespeare","England"), ("Twain","USA") ]

title = [ ("Milton", "Paradise Lost"), 
    ("Shakespeare", "Hamlet"),
    ("Shakespeare", "Othello"),
    ("Twain","Tom Sawyer"),
    ("Twain","Huck Finn"),
]

inv_country = {}
for id,c in enumerate(country):
    inv_country.setdefault(c,defaultdict(list))
    inv_country[c]['country'].append( id )

inv_author= {}
for id,row in enumerate(author):
    a,c = row
    inv_author.setdefault(a,defaultdict(list))
    inv_author[a]['author'].append( id )
    inv_country[c]['author'].append( id )

inv_title= {}
for id,row in enumerate(title):
    a,t = row
    inv_title.setdefault(t,defaultdict(list))
    inv_title[t]['title'].append( id )
    inv_author[a]['author'].append( id )

#Books by authors from England
for t in inv_country['England']['author']:
    print title[t]
1
ответ дан 14 December 2019 в 19:28
поделиться
SELECT a.*, b.*
   FROM Authors AS a, Books AS b
   WHERE a.author_id = b.author_id
     AND a.birth_city = "Chicago"
     AND a.birth_state = "IL";

Хороший оптимизатор обработает это в меньше, чем время, которое потребовалось бы для чтения целого списка авторов и целого списка книг, который является подлинейным временем, поэтому. (Если у Вас есть другое определение того, под чем Вы подразумеваете подлинейный, высказываетесь.)

Обратите внимание, что оптимизатор должен смочь выбрать порядок, в котором можно обработать таблицы, который является самым выгодным. И это относится к наборам N-уровня запросов.

1
ответ дан 14 December 2019 в 19:28
поделиться

Вообще говоря, RDBMSes обрабатывают эти типы запросов очень хорошо. И коммерческие и механизмы базы данных с открытым исходным кодом развились за десятилетия с помощью всех разумных вычислительных применимых алгоритмов, чтобы сделать просто эту задачу максимально быстро.

Я рисковал бы предположением, что единственный способ, которым Вы победите RDBMS в скорости, если Ваши данные конкретно организованы, и потребуйте определенных алгоритмов. Некоторые RDBSes позволяют Вам указать, какой из базовых алгоритмов можно использовать для управления данными, и с с открытым исходным кодом, можно всегда переписывать или реализовывать новый алгоритм в случае необходимости.

Однако, если Ваш случай не является совершенно особым, я полагаю, что это могло бы быть серьезное излишество. Для большинства случаев я сказал бы, что помещение данных в RDBMS и управлении им через SQL должно работать достаточно хорошо так, чтобы Вы не волновались о базовых алгоритмах.

1
ответ дан 14 December 2019 в 19:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: