tl; dr , если вы не уверены, как он учитывает время выполнения big-o, создайте суммирование для l oop, а затем выполните преобразование это суммирование в функцию n
Иногда вы будете сталкиваться с такими вопросами, как «сколько раз строка внутри самой внутренней l oop выполнялась в терминах n Это не совсем анализ времени выполнения, но, тем не менее, это анализ. Он поможет вам получить более полное представление о времени выполнения big-o.
Может быть полезно поместить счетчик во внутренний l oop и посмотрите, сколько раз он выполняется.
Также может быть полезно нарисовать сетку и раскрасить квадраты, где i <= j
и j
- индекс строки (так как это первый l oop ' переменная s), а i
- индекс столбца). Когда вы это сделаете, вы увидите, что все цветные квадраты разбивают квадратную сетку на 2 треугольника по диагонали от верхнего левого до нижнего правого. линия все еще имеет значение (потому что ты сказал <=
, а не <
). Цветные квадраты будут нижним / левым треугольником.
Это просто изображение того, где самый внутренний l oop действительно что-то сделает .
Внешние 2 цикла теперь будут повторяться по каждому месту в сетке. Мы назовем это текущее местоположение . Строка кода во внутреннем l oop теперь будет выполняться один раз для каждого цветного квадрата выше текущего местоположения в этом столбце сетки (и один раз для текущего местоположения , если это каждый раз новое местоположение определяется внешними 2 петлями.
После визуализации вы можете легче увидеть, сколько раз это будет выполнено. Первый столбец сетки имеет n цветных квадратов. При первом подсчете этого столбца будет выбран верхний левый квадрат (j = 0, i = 0). Второй раз будет, когда (j = 1, i = 0). Итак, давайте заполним сетку, где значение в каждом месте - это число раз, которое подсчитывается каждая ячейка. Это будет так:
[n, 0 , 0, 0, ... ]
[n-1, n-1, 0, 0, ... ]
[n-2, n-2, n-2, 0, ...]
Теперь вы можете видеть картинку. Суммируя все в , эта сетка теперь скажет вам, сколько раз ваш самый внутренний l oop был выполнен.
- В первом ряду 1 n
- Во втором ряду 2 (n-1) '
- Третий строка имеет 3 (n-2) * s
Вы можете увидеть шаблон (nj) * (j + 1) как сумму для каждой строки.
Суммируйте по строкам, чтобы получить сумму.
В итоге вы получите такую сумму:
for(int i = 0; i < n; i++)
sum += (n-i)*(i+1);
return sum;
Это только для количества раз, которое внутренний большинство л oop выполнено. Теперь для времен исполняется самый внутренний l oop 1070 * not . Эта часть намного проще. Это просто количество неокрашенных квадратов в сетке из предыдущих.
Поскольку это сетка n на n , n 2 / 2 может показаться правильным ответом. НО основные диагональные квадраты все цветные. n 2 / 2 уже считает половину этой строки, поэтому мы должны удалить другую половину: n / 2.
Таким образом, общее количество выполнений будет равно for
l oop сумма выше, плюс половина квадрата n (неокрашенные квадраты), минус половина n (потому что вы только что добавили половину диагонали, которая уже была окрашена в предыдущем плюс термин).
В конечном итоге это выглядит как
Значение первых двух слагаемых - это количество раз, которое делал самый внутренний для-l oop НЕ выполнить.
Когда я запускаю этот код, мои результаты следующие:
- n = 10
- inner-l oop выполнения: 220
- Всего казней: 265
- 220 + 10 2 / 2 - 10/2 (220 + 50 - 5 = 265)
- n = 100
- inner-l oop исполнений: 171700
- всего исполнений: 176650
- n = 1000
- inner-l oop казни: 167167000
- всего выполнений: 167666500
- n = 10000
- inner-l oop исполнений: 166716670000
- всего исполнений: 166766665000
- n = 100000
- inner-l oop исполнений: 166671666700000
- всего исполнений: 166676666650000
- n = 100000000 (сделал это только для lolz, вы уже можете видеть шаблон)
- inner-l oop исполнений: 166666671666666700000000
- всего выполнений: 166666676666666650000000
И ДЛЯ МОЕГО ПОСЛЕДНЕГО РАСКРЫТИЯ, ПОЧЕМУ ВЫ ПРОЧИТАЛИ ЭТО ДАЛЬШЕ Это функция O (n 3 ).
Я не буду вдаваться в подробности, но сумма для количества выполнений самого внутреннего для -l oop упрощается до
Добавляя в 2 терминах, которые подсчитывают, сколько раз выполнялся самый внутренний l oop, который выполнял NOT , сгруппируйте подобные термины для более простого упрощения, и вы получите следующее:
Вы можете использовать эти последние 2 формулы для проверки данных, которыми я поделился выше. Вы также можете эмпирически проверить, добавив счетчики в свои циклы и запустив их, чтобы увидеть, сколько раз они выполняются, и сравнить их со значениями, приведенными в этих формулах (для значений, таких как предоставленные мною, вам нужно будет использовать BigInteger
s). или какой-либо другой формат произвольно большого числа). Если вы не доверяете ни мне, ни своему компьютеру, вы также можете попробовать добавить эту информацию в онлайн-инструмент, который решает уравнения, такие как вольфрам альфа. Наконец, если это из экзаменационного вопроса, вы можете передать его своему профессору и продемонстрировать природу этой проблемы, и точное число for-loop
выполнений, заданных n
, равно длине массива A
. Если все это не так, я, по крайней мере, показал, что это верно для степеней 10. Надеюсь, это поможет каким-то образом.