Как убрать маркер сущности Луиса из высказывания

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

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

Когда вы это делаете:

vector<Foo> vec;

// Allocate memory for a thousand Foos:
vec.reserve(1000);

... который фактически не создает тысячу Foos. Он просто выделяет / резервирует память для них. Если vector не использовал здесь место размещения, это было бы построение по умолчанию Foos по всему месту, а также необходимость вызывать их деструкторы даже для элементов, которые вы никогда не вставили в первую очередь.

Allocation! = Construction, Freeing! = Destruction

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

Должно быть разделение между этими идеями, чтобы избежать излишнего вызова конструкторов и деструкторов излишне левым и правым, и поэтому стандартная библиотека разделяет идею std::allocator (которая не создает или не уничтожает элементы, когда он выделяет / освобождает память *) вдали от используемых им контейнеров, которые вручную создают элементы, используя размещение новых и вручную уничтожая элементы, используя явные вызовы деструкторов.

  • Ненавижу дизайн std::allocator, но это другой предмет, о котором я не буду говорить. : -D

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

Естественно, если вы когда-нибудь работаете с помощью пользовательских распределителей для выделения объектов по отдельности, например, в виде бесплатного списка, вы также обычно хотели бы использовать placement new, как это (основной пример, который не беспокоит безопасность исключений или RAII):

Foo* foo = new(free_list.allocate()) Foo(...);
...
foo->~Foo();
free_list.free(foo);
2
задан hengist 16 January 2019 в 22:45
поделиться

2 ответа

В этом конкретном случае (заполнение объекта списка сокращениями / именами состояний) вам лучше будет использовать предварительно созданный объект geographyV2 или предварительно созданный объект домена Places.AbsoluteLocation. (Обратите внимание, что на момент написания этой статьи у предварительно созданного объекта geographyV2 была небольшая ошибка, поэтому лучше использовать предварительно созданный объект домена).

Причина этого двоякая:

Во-первых, географические местоположения уже запечены в LUIS, и они не сталкиваются с обычными синтаксическими словами, такими как «in», «hi» или «me». , Я проверил это в обратном порядке, создав список [Medical], который содержал «ct» в качестве нормализованного значения и «ct scan» в качестве синонима. Когда я набрал «получить мне КТ в КТ», это привело к «получить меня [медицинский] в [медицинский]». Чтобы исправить это, я выбрал второе значение «CT» и переназначил его для объекта Places.AbsoluteLocation. После переподготовки я проверил «когда в КТ показывают мне опции ct», что правильно привело к «когда в [Places.AbsoluteLocation] покажут мне [медицинские] опции». Дальнейшие примеры и обучение улучшат результаты.

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

Надежда на помощь!

0
ответ дан Steven Kanberg 16 January 2019 в 22:45
поделиться

@ Ответ Стивена Канберга был очень полезным, но, к сожалению, не полным для моей ситуации. Я пытался реализовать как geographyV2, так и Places.AbsoluteLocation (отдельно). Ни один из них не работает полностью так, как мне нужно (распознавая состояния и их двухбуквенные сокращения таким образом, чтобы их можно было запрашивать у сущностей в ответе).

Таким образом, я могу выбрать:

  1. Создать свой собственный список состояний, используя имя состояния и двухбуквенную аббревиатуру в качестве синонимов, как описано в самом описании списка. Это работает за исключением двухбуквенных сокращений, которые также являются словами, такими как «in», «hi» и «me».
  2. Использовать встроенную сборку geographyV2, которая не допускает синонимов и вообще не распознает двухбуквенные сокращения, или
  3. Использовать Places.AbsoluteLocation, которая распознает двухбуквенные сокращения для состояний, не смущает их со словами, но также захватывает все местоположения, включая города, страны и адреса, и не делает различий между ними, поэтому я не могу разобрать, какая сущность является государством в высказывании типа «Я живу в Лейк-Стивенс, округ Снохомиш, Вашингтон».

Решение: если я объединю 1 с 3, я могу запросить объекты, которые имеют оба этих типа. Если LUIS помечает слово «in» как штат (штат Индиана), я могу проверить, не было ли это слово также помечено как AbsoluteLocation. Если нет, то я могу смело отказаться от этой сущности. Это не идеально, но это обходной путь, который решает проблему.

0
ответ дан hengist 16 January 2019 в 22:45
поделиться
Другие вопросы по тегам:

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