Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

285
Vistas
¿Cuál es la complejidad temporal de la exponenciación por elevación al cuadrado?

Aquí hay un código para exponenciar un número a una potencia dada:

 #include <stdio.h> int foo(int m, int k) { if (k == 0) { return 1; } else if (k % 2 != 0) { return m * foo(m, k - 1); } else { int p = foo(m, k / 2); return p * p; } } int main() { int m, k; while (scanf("%d %d", &m, &k) == 2) { printf("%d\n", foo(m, k)); } return 0; }

¿Cómo calculo la complejidad temporal de la función foo ?

He podido deducir que si k es una potencia de 2 , la complejidad temporal es O(log k) .

Pero me resulta difícil calcular otros valores de k . Cualquier ayuda sería muy apreciada.

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

¿Cómo calculo la complejidad temporal de la función foo()?

He podido deducir que si k es una potencia de 2, la complejidad temporal es O(logk).

Primero, asumo que el tiempo necesario para cada llamada de función es constante (este no sería el caso, por ejemplo, si el tiempo necesario para una multiplicación depende de los números que se multiplican, como es el caso en algunas computadoras).

También asumimos que k>=1 (de lo contrario, la función se ejecutará sin fin a menos que haya un desbordamiento).

Pensemos el valor k como un número binario:

Si el bit más a la derecha es 0 ( k%2!=0 es falso), el número se desplaza un bit a la derecha ( foo(m,k/2) ) y la función se llama recursivamente.

Si el bit más a la derecha es 1 ( k%2!=0 es verdadero), el bit se cambia a 0 ( foo(m,k-1) ) y la función se llama recursivamente. (Aún no miramos el caso k=1 ).

Esto significa que la función se llama una vez por cada bit y se llama una vez por cada 1 bit. O, en otras palabras: se llama una vez por cada bit 0 en el número y dos veces por cada bit 1 .

Si N es el número de llamadas a funciones, n1 es el número de 1 bits y n0 es el número de 0 bits, obtenemos la siguiente fórmula:

 N = n0 + 2*n1 + C

La constante C ( C=(-1) , si no me equivoqué) representa el caso k=1 que ignoramos hasta ahora.

Esto significa:

 N = (n0 + n1) + n1 + C

Y - porque n0 + n1 = floor(log2(k)) + 1 :

 floor(log2(k)) + C <= N <= 2*floor(log2(k)) + C

Como puede ver, la complejidad del tiempo siempre es O(log(k))

over 4 years ago · Santiago Trujillo Denunciar

0

O(registro(k))

Se agregó alguna modificación para generar estadísticas para el gráfico de hoja de cálculo.

 #include <stdio.h> #include <math.h> #ifndef TEST_NUM #define TEST_NUM (100) #endif static size_t iter_count; int foo(int m, int k) { iter_count++; if (k == 0) { return 1; } else if(k == 1) { return m; } else if (k % 2 != 0) { return m * foo(m, k - 1); } else { int p = foo(m, k / 2); return p * p; } } int main() { for (int i = 1; i < TEST_NUM; ++i) { iter_count = 0; int dummy_result = foo(1, i); printf("%d, %zu, %f\n", i, iter_count, log2(i)); } return 0; }

Constrúyelo.

 gcc t1.c -DTEST_NUM=10000 ./a > output.csv

Ahora abra el archivo de salida con un programa de hoja de cálculo y trace las últimas dos columnas de salida. ingrese la descripción de la imagen aquí

over 4 years ago · Santiago Trujillo Denunciar

0

Para k positivo, la función foo se autodenomina recursivamente p veces si k es la p -ésima potencia de 2. Si k no es una potencia de 2 , el número de llamadas recursivas es estrictamente inferior a 2 * p donde p es el exponente de la mayor potencia de 2 inferior a k .

Aquí hay una demostración:

expandamos la llamada recursiva en el caso k % 2 != 0 :

 int foo(int m, int k) { if (k == 1) { return m; } else if (k % 2 != 0) { /* 2 recursive calls */ // return m * foo(m, k - 1); int p = foo(m, k / 2); return m * p * p; } else { /* 1 recursive call */ int p = foo(m, k / 2); return p * p; } }

El número total de llamadas es floor(log2(k)) + bitcount(k) , y bitcount(k) es por construcción <= ceil(log2(k)) .

No hay bucles en el código y el tiempo de cada llamada individual está limitado por una constante, de ahí la complejidad de tiempo general de O(log k) .

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda