Случается, когда вы пытаетесь получить доступ к объекту объекта, пока нет объекта.
Типичный пример для non-object notice будет
$users = json_decode('[{"name": "hakre"}]');
echo $users->name; # Notice: Trying to get property of non-object
В этом случае $users
представляет собой массив (а не объект), и он не имеет никаких свойств.
Это похоже для доступа к несуществующему индексу или ключу массива (см. Примечание: Undefined Index ).
Этот пример значительно упрощен. Чаще всего такое уведомление сигнализирует неконтролируемое возвращаемое значение, например. когда библиотека возвращает NULL
, если объект не существует или просто неожиданное значение, отличное от объекта (например, в результате Xpath, структуры JSON с непредвиденным форматом, XML с неожиданным форматом и т. д.), но код не проверяет такой условие.
Поскольку эти не-объекты часто обрабатываются дальше, часто возникает фатальная ошибка при вызове метода объекта для не-объекта (см.: Неустранимая ошибка: вызов члену function ... на не-объекте ), останавливая скрипт.
Его можно легко предотвратить, проверив условия ошибки и / или переменную, соответствующую ожиданию. Здесь такое уведомление с примером DOMXPath:
$result = $xpath->query("//*[@id='detail-sections']/div[1]");
$divText = $result->item(0)->nodeValue; # Notice: Trying to get property of non-object
Проблема заключается в доступе к свойству nodeValue
первого поля, пока он не был проверен, существует ли он или нет в $result
коллекция. Вместо этого он платит, чтобы сделать код более явным, назначив переменные объектам, на которых работает код:
$result = $xpath->query("//*[@id='detail-sections']/div[1]");
$div = $result->item(0);
$divText = "-/-";
if ($div) {
$divText = $div->nodeValue;
}
echo $divText;
Связанные ошибки:
Ваш вариант использования, по-видимому, будет, "вставляют данные однажды (например, запуск приложения) и затем выполняют много чтений, но немногих если любые дополнительные вставки".
Поэтому необходимо использовать алгоритм, который быстр для поиска информации, в которой Вы нуждаетесь.
я поэтому думал бы, что HashTable был самым подходящим алгоритмом для использования, поскольку это просто генерирует хеш ключевого объекта и использует это для доступа к целевым данным - это - O (1). Другие - O (N) (Связанные списки размера N - необходимо выполнить итерации через список по одному, в среднем времена N/2) и O (регистрируют N) (Двоичное дерево - Вы делите на два пространство поиска с каждым повторением - только если дерево сбалансировано, таким образом, это зависит от Вашей реализации, несбалансированное дерево может иметь значительно худшую производительность).
Просто удостоверяются, что существует достаточно пробелов (блоки) в HashTable для Ваших данных (R.e., комментарий Soraz к этому сообщению). Большинство реализаций платформы (Java.NET, и т.д.) будет иметь качество, которое Вы не должны будете волновать по поводу реализаций.
Вы делали курс о структурах данных и алгоритмах в университете?
Стандартная торговля offs между этими структурами данных применяется.
То, что все, кажется, забывают, - то, что для маленького нс, IE немного символов в Вашей таблице, связанный список может быть намного быстрее, чем хеш-таблица, хотя в теории ее асимптотическая сложность действительно выше.
существует известная кавычка из Примечаний Щуки по Программированию в C: "Правило 3. Необычные алгоритмы являются медленными, когда n является маленьким, и n является обычно маленьким. Необычные алгоритмы имеют большие константы. Пока Вы не знаете, что n часто будет большим, не становитесь необычными". http://www.lysator.liu.se/c/pikestyle.html
я не могу сказать из Вашего сообщения, если Вы будете иметь дело с маленьким N или нет, но всегда помнить, что лучший алгоритм для крупного N не обязательно хорош для маленького нс.
Мне нравится ответ счета, но он действительно не синтезирует вещи.
От этих трех вариантов:
Связанные списки относительно не спешат объекты поиска от (O (n)). Таким образом, если Вы имеете партия из объектов в Вашей таблице, или Вы собираетесь быть выполнением большого количества поисков, тогда они не лучший выбор. Однако их легко создать, и легкий записать также. Если таблица является маленькой, и/или Вы только когда-либо делаете одно небольшое сканирование через нее после того, как она создается, то это могло бы быть выбором для Вас.
Хэш-таблицы могут быть ослепительно быстрыми. Однако для него для работы необходимо выбрать хороший хеш для входа, и необходимо выбрать таблицу, достаточно большую для содержания всего без большого количества хэш-коллизий. То, что это означает, является Вами, должны знать что-то о размере и количестве Вашего входа. Если Вы портите это, Вы заканчиваете с действительно дорогим и сложным набором связанных списков. Я сказал бы, что, если Вы не знаете заранее примерно, как большой таблица будет, не используйте хэш-таблицу. Это не соглашается с Вашим "принятым" ответом. Извините.
, Который оставляет деревья. У Вас есть опция здесь хотя: балансироваться или не балансироваться. Что я нашел путем изучения этой проблемы на коде C и Фортрана, который мы имеем, вот то, что вход таблицы символов имеет тенденцию быть достаточно случайным, который Вы только теряете о древовидном уровне или два, не балансируя дерево. Учитывая, что сбалансированные деревья медленнее для вставки элементов в и более тверды реализовать, я не обеспокоился бы ими. Однако, если у Вас уже есть доступ к хорошим отлаженным библиотекам компонентов (например: STL C++), тогда Вы могли бы также идти вперед и использовать сбалансированное дерево.
Это кажется, что следующее может все быть верным:
Если так, Вы могли бы рассмотреть отсортированный список по любой из этих других структур. Это работало бы хуже, чем другие во время вставок, поскольку отсортированный список является O (N) на вставке, по сравнению с O (1) для связанного списка или хэш-таблицы и O (журнал 2 Н для сбалансированного двоичного дерева. Но поиски в отсортированном списке могут быть быстрее, чем любая из этих структур других (я объясню это вскоре), таким образом, можно будет преуспеть. Кроме того, если Вы выполняете все свои вставки сразу (или иначе не требуйте поисков, пока все вставки не завершены), тогда можно упростить вставки до O (1) и сделать один намного более быстрый вид в конце. Кроме того, отсортированный список использует меньше памяти, чем любая из этих других структур, но единственный способ, которым это, вероятно, будет иметь значение, состоит в том, если у Вас есть много маленьких списков. Если у Вас будут один или несколько больших списков, то хэш-таблица, вероятно, превзойдет отсортированный список по характеристикам.
, Почему поиски могли бы быть быстрее с отсортированным списком? Ну, ясно, что это быстрее, чем связанный список с O последнего (N) время поиска. С двоичным деревом поиски только остаются O (журнал 2 Н, если дерево остается отлично сбалансированным. Хранение сбалансированного дерева (красно-черный, например) добавляет ко времени вставки и сложности. Кроме того, и со связанными списками и с двоичными деревьями, каждый элемент является отдельно выделенным <глоток> 1 глоток> узел , что означает, что необходимо будет разыменовать указатели и вероятно перейти к потенциально широко переменным адресам памяти, увеличивая возможности неудачного обращения в кэш.
Что касается хэш-таблиц, необходимо, вероятно, читать пара из другие вопросы здесь на StackOverflow, но основные моменты интереса здесь:
, Конечно, если Вы действительно заботитесь о том, как любая из этих структур данных будет работать, необходимо протестировать их. У Вас должно быть мало проблемы при нахождении хороших реализаций любого из них для наиболее распространенных языков. Не должно быть слишком трудно бросить некоторые Ваши реальные данные в каждой из этих структур данных и видеть, который работает лучше всего.
Несколько вещей не упустить.
Двоичные деревья только имеют O (зарегистрируйте n), поиск и вставляет сложность, если дерево , балансировался . Если Ваши символы вставляются в довольно случайный вид, это не должно быть проблемой. Если они будут вставлены в порядок, Вы будете создавать связанный список. (Для Вашего определенного приложения они не должны быть ни в каком виде порядка, таким образом, необходимо быть хорошо.), Если существует шанс, что символы будут слишком организованными, Красно-черный , Дерево является более оптимальным вариантом.
Хэш-таблицы дают O (1) средняя вставка и сложность поиска, но существует протест здесь, также. Если Ваша хеш-функция плоха (и я имею в виду действительно плохой), Вы могли бы закончить тем, что создали связанный список здесь также. Любая разумная строковая хеш-функция должна сделать, тем не менее, таким образом, это предупреждение действительно только, чтобы удостовериться, что Вы знаете, что это могло произойти. Необходимо быть в состоянии просто протестировать ту хеш-функцию, не имеет многих коллизий по ожидаемому диапазону исходных данных, и Вы будете в порядке. Еще один незначительный недостаток состоит в том при использовании хэш-таблицы фиксированного размера. Большинство реализаций хэш-таблицы растет, когда они достигают определенного размера (коэффициент загрузки, чтобы быть более точным, см. здесь для деталей). Это должно избежать проблемы, которую Вы получаете при вставке миллиона символов в десять блоков. Это просто приводит к десяти связанным спискам со средним размером 100 000.
я только использовал бы связанный список, если бы у меня была действительно короткая таблица символов. Является самым легким реализовать, но лучшая производительность случая для связанного списка является худшей производительностью случая для Ваших других двух опций.
Другие комментарии сфокусировались на добавляющих/получающих элементах, но это обсуждение не завершено, не рассматривая то, что оно берет для итерации по всему набору. Короткий ответ здесь - то, что хэш-таблицы требуют, чтобы меньше памяти выполнило итерации, но деревья требуют меньшего количества времени.
Для хэш-таблицы, память наверху итерации по (ключ, значение) пары не зависит от способности таблицы или числа элементов, сохраненного в таблице; на самом деле итерация должна потребовать просто единственной индексной переменной или два.
Для деревьев, объем памяти, требуемый всегда, зависит от размера дерева. Можно или поддержать очередь непосещаемых узлов при итерации или добавить дополнительные указатели на дерево для более легкого повторения (делающий дерево, в целях повторения, действия как связанный список), но так или иначе, необходимо выделить дополнительную память для повторения.
, Но ситуация инвертируется когда дело доходит до синхронизации. Для хэш-таблицы время это берет для итерации, зависит от способности таблицы, не количества сохраненных элементов. Таким образом, таблица, загруженная на 10% способности, сопроводит в 10 раз дольше для итерации, чем связанный список с теми же элементами!
Этот вопрос проходит различные контейнеры в C#, но они подобны на любом языке, который Вы используете.
Это зависит от нескольких вещей, конечно. Я сказал бы, что связанный список является правильным, так как он имеет немного подходящих свойств для работы таблицей символов. Двоичное дерево могло бы работать, если Вы уже имеете один и не должны проводить время, пишущий и отлаживая его. Моим выбором была бы хэш-таблица, я думаю, что это - более или менее значение по умолчанию с этой целью.
Если Вы не ожидаете, что Ваша таблица символов будет маленькой, я должен избегать связанных списков. Список 1 000 объектов в среднем возьмет 500 повторений для нахождения любого объекта в нем.
двоичное дерево А может быть намного быстрее, пока оно сбалансировано. При сохранении содержания сериализированная форма будет, вероятно, отсортирована, и когда она будет перезагружена, получающееся дерево будет полностью несбалансированным как следствие, и она будет вести себя то же как связанный список - потому что это в основном, чем это стало. Алгоритмы сбалансированного дерева решают этот вопрос, но делают целую хижину более сложной.
А hashmap (пока Вы выбираете подходящий алгоритм хеширования) похож на лучшее решение. Вы не упомянули свою среду, но примерно всем современным языкам встроили Hashmap.