Количество вычислений / шагов в каждой строке алгоритма

#c #algorithm #performance #big-o

#c #алгоритм #Производительность #big-o

Вопрос:

У меня здесь есть функция, которую я вижу, это O (N ^ 2). Тем не менее, я пытаюсь точно определить, сколько шагов / вычислений использует каждая строка.

 void hi(int n){
  for (int i=1; i <= n; i  ) {        //line 1
    for (int k = i; k <= n; k  ) {    //line 2
      puts("hi");                     //line 3
    }
  }
}
  

Для строки 1 я считаю, что это 1 (N 1) 1.

Строки 2 и 3 предположительно являются суммой (i = от 1 до n) (3i 2), но я не понимаю, как это сделать. Откуда взялось это суммирование?

Ответ №1:

Внешняя for инструкция выполняется один раз … хотя это повторяется n несколько раз (из-за начального условия, конечного условия и частей обновления). Это «строка 1».

Внутренний for оператор будет выполняться один раз для каждой итерации внешнего цикла. Внешний цикл повторяется n несколько раз, поэтому внутренний for оператор выполняется n несколько раз. Это «строка 2».

"hi" будет записываться один раз для каждой итерации внутреннего цикла. Внутренний цикл будет повторять n-i 1 время для каждой итерации внешнего цикла (который выдает значение i ). Это означает, что количество раз "hi" , которое печатается, равно n (для i == 1 ) n-1 (для i == 2 ) …. 1 (для i==n ). Суммируя их, это приравнивается к n*(n 1)/2 временам. Это «строка 3».

Комментарии:

1. Я должен включать инициализатор, условие и приращения циклов for . Поскольку строка 1 выполняется только один раз, это должно быть просто 1 (N 1) 1. Для второй строки, поскольку она выполняется N раз, означает ли это, что общее количество шагов будет равно N * (1 (N 1) 1), поскольку весь цикл for сбрасывается для каждого N?

2. Вы упускаете из виду тот факт, что переменная, управляющая внешним циклом, также управляет количеством итераций внутреннего цикла.

Ответ №2:

Строка 1 выполняется 1 раз. Однако он выполняет 1 инициализацию, n сравнений и приращений.

Строка 2 выполняется n раз. Однако он выполняет n инициализаций, n*(n 1)/2 сравнений и приращений.

Строка 3 выполняется n*(n 1)/2 раза. Из-за http://mathcentral.uregina.ca/qq/database/qq.02.06/jo1.html

Таким образом, общее количество операций равно 1 3n 3n *(n 1) / 2.

Комментарии:

1. Почему строка 1 выполняется один раз??

2. Обычно вы подсчитываете for-элемент, а не приращение, поэтому for выполняется только 1 раз при каждом вызове hi .

3. Я должен включать все части цикла for. Будет ли строка 2 тогда N * (1 (N 1) 1)?

4. Нет, все именно так, как указано. Наибольшее внутреннее значение определит вашу нотацию Big-O, которая, как вы сами заявили, равна O (n ^ 2). Общее количество выполненных операций равно сумме строк (1) (n) (n*(n 1)/2).

5. Верно, но я думаю, что мы рассматриваем разные уровни детализации. Например, вы упомянули, что обычно вы считаете цикл for только как один, но в моем случае я должен также включить инициализацию, проверку условий и приращение, поэтому у меня есть 1 (n 1) 1.