< STRONG> Вопросы

1) Почему фрагмент кода ниже обозначен как O (log n) (по лектору)?

2) Почему цикл for не завершается сразу, когда n> 0? редактировать: ответ ниже - всегда> 0, так что бесконечный (теоретически) цикл или до переполнения (на практике)

< Сильный > Фон Я делаю курс и сегодня вечером у нас была сессия по временной сложности алгоритмов. Это преподается с Java. Для всех остальных фрагментов кода я понял всю сложность, но этот меня полностью смущает.

public class SampleClassOnly {
   public static void main(String[] args) {
     int n = 100;
     for(int j = n; j > 0; j++){
     System.out.println(j);
     }
   }
}

Теперь я запустил код, чтобы проверить его, и для n <= 0 я вижу, что он имеет сложность O (1), поскольку выполняется 5 шагов. Для n> 0 кажется, что он работает более 1000 раз (я использовал визуализатор, чтобы проверить это визуально - см. Ниже)

Меня также смущает то, что он не останавливается при выполнении условия завершения, т. Е. J> 0 (выделено ниже).

Code being run in Visualiser

Возможно, я упускаю что-то очевидное? Цените любые указатели. Спасибо.

-4
srattigan 19 Сен 2017 в 23:35

3 ответа

Лучший ответ

Это определенно не O (log n). Это O (n), потому что число операций будет линейно варьироваться в зависимости от того, что вы установили n (конечно, при условии, что мы рассматриваем n как вход, который мы могли бы изменить в принципе). (Конечно, существует жесткое ограничение на количество «шагов», которые может выполнить цикл, то есть 2^31 шагов). (Кроме того, важный момент: это будет выполнять постоянное количество операций для любого конкретного значения n, поэтому @Bohemian приводил аргументы в комментариях об этом как O (1)) ,

Как указывали другие люди, инвариант цикла не может быть ложным (при условии, что вы установили n в положительное число); единственная причина, по которой он вообще остановится, заключается в том, что в конечном итоге вы получите целочисленное переполнение.

Для n> 0, кажется, работает более 1000 раз

Да, он будет запущен 2^31-n раз, а затем переполнен, поэтому для большинства значений n он будет выполняться намного более 1000 раз.

1
EJoshuaS - Reinstate Monica 19 Сен 2017 в 20:57

Обратите внимание, что ваш цикл for:

for (int j = n; j > 0; j++)
{
    /* code in block */
}

Функционально эквивалентно:

{
    int j = n;
    while (j > 0)
    {
        {
            /* code in block */
        }
        j++;
    } 
}

Так что, как уже говорили другие, он будет работать до тех пор, пока j не переполнится. И поскольку он линейно зависит от n, он равен O (n).

Я думаю, вы хотели сделать:

for (int j = n; j > 0; j--)

Тогда он будет работать n раз, при этом j будет уменьшаться с n до 1. Но даже тогда это O (n).

1
Rudy Velthuis 19 Сен 2017 в 21:07

Это О (1). Не O (войдите n). Не на).

По существу, оно имеет постоянное время, поскольку максимальное число итераций для любого значения n равно 2 31 (когда n = 0).

Будучи ограниченным, сложность времени "постоянна".

0
Bohemian 20 Сен 2017 в 04:47