2011-12-30 2 views
3

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

char array[] = {'a','b','c','d','e'}; 

Будет ли он фактически выполнять 5 раз для назначения каждой переменной; как мы делаем в цикле. Если предположение верно, почему это так?

+1

Я бы предположил, что любой неидиотский компилятор выполнит его в 'O (n)' с не более чем 5 назначениями в 5 разных мест памяти. (и, возможно, меньше, если он решит векторизовать) – Mysticial

+0

Если массив такой же, как в вашем примере, компилятор просто поместил бы значения массива в виде последовательного фрагмента памяти в сегменте данных приложений, и пусть 'array' указывает на это. Никакой инициализации или цикла вообще. –

+3

@Joachim: нет, если 'array' находится в стеке, он должен быть инициализирован локально тогда.(Но в стандарте нет ничего, что говорило бы о том, как компилятор должен это сделать, поэтому вопрос не отвечает в ответ - проверьте вывод компилятора. GCC делает 5 байтов здесь.) – Mat

ответ

3

В зависимости от того, где происходит объявление и интеллекта компилятора, это может быть O (1) или O (n). в некоторых случаях:

  1. глобальная декларация, умный компилятор будет положить его в разделе данных, уже инициализирован, таким образом, O (1)
  2. локальное объявление, если доказано, что только для чтения с помощью смарт-компилятор, это может быть как выше, плюс ссылочное присвоение массиву, но все же O (1)
  3. Локальная декларация, чтение записи, может быть выделение памяти + 5 присвоений (очевидно, O (n) ИЛИ распределение памяти + копия данных массива (например, 2, но данные копируются вместо ссылки), последний может быть O (1) с векторизованным кодом (ну ... более или менее, потому что это зависит от множества вещей)
+0

Для 2., я думаю, должно быть больше, чем что. Также необходимо, чтобы компилятор смог доказать, что никогда не было сравнения базового адреса массива. Два экземпляра одного и того же массива, например, из разных рекурсивных вызовов, всегда должны быть разными. Единственный случай, когда я знаю, где такое сгибание разрешено, - это «сложные» литературные составные литералы. –

+0

@JensGustedt без 'const', это, возможно, необходимо. но настоящий интеллектуальный компилятор может рассматривать его так, как будто он объявлен 'const', независимо от того, объявлено оно так или нет. – LeleDumbo

+0

Даже с 'const', для двух объектов, которые отличаются проверкой с' == 'для своих адресов, нужно возвращать' false'. Это требование выполняет два экземпляра одной и той же переменной, которые соответствуют двум различным рекурсивным вызовам. –

1

Это O (N). Это может быть быстрый или эффективный O (N). И если это статически выделенный массив, инициализация будет выполняться только один раз.

Но в любом случае это O (N).

Обратите внимание, что даже если это массив, который помещается в двоичное изображение программы (поскольку компилятор определяет, что массив никогда не изменяется), это все еще операция O (N) для инициализации, хотя инициализация может происходят до того, как событие программы достигнет main() или сделано как часть загрузки изображения программы.

Это O (N), потому что независимо от того, что инициализация должна записывать в каждое местоположение массива, поэтому массив, который в 100 раз длиннее другого, будет иметь порядок в 100 раз больше операций, выполняемых для завершения инициализации ,

+0

Я не понимаю. Насколько я знаю, значения такой статической инициализации помещаются в двоичное изображение. Обычно эта часть двоичного файла тогда «mmap» (или аналогичная) с «копией при записи». Накладные расходы на инициализацию тогда возникают только тогда, когда значение записывается в определенное место. В частности, переменная, которая никогда не имеет доступа, вообще не имеет накладных расходов. В терминах обозначения BigO общая стоимость - «O (M)», где «M» - это номер для доступа к отдельным местоположениям массива. Так что с точки зрения bigO нет накладных расходов вообще. Однако константа, спрятанная в bigO, является страницей. –

0

Как и другие, это можно сделать в O (n) времени.

Но это никогда не может быть O (1) !! Как вы можете писать в n ячейках памяти (независимо от того, какой тип памяти мы имеем) за меньшее время? O (1) означает, что операция не зависит от размера входа. Я не хочу приводить в дискуссию машины для обучения, но где-то во время выполнения всегда будет операция O (n) с вышеуказанным оператором.

+0

Нет, этот анализ слишком грубый. Вы должны измерить его в «M» количество раз, когда программа доступа к элементу массива получает доступ. См. Мой комментарий для ответа Мишеля Берра. –

+0

@User - Вы можете написать сразу несколько символов, особенно если строка коротка. На моей 64-битной машине компилятор перемещает 8 символов за один раз с использованием одного регистра. –

+0

@BoPersson да, но количество символов, которые вы можете перемещать сразу, ограничено. – UmNyobe

0

Сложность времени будет равна 0. Не O или o (n). Место для массива будет установлено с начальными значениями ДО ПРОГРАММЫ ПРОГРАММЫ. Место и значения будут подготовлены на стадии компиляции и настроены на этап компоновки.

Не будет никаких команд для реализации указанной линии. И НЕТ времени.

Смежные вопросы