Entiendo que para comparar dos cadenas para la igualdad, el intérprete tiene que recorrer ambas cadenas y comparar cada carácter.
Eso haría que la complejidad del tiempo 0(n)
, donde n
es la longitud de la cadena más corta.
Sin embargo, comparar dos números para igualdad es 0(1)
.
¿Porqué es eso? ¿No tendría que interpretar el intérprete cada número para verificar la igualdad?
javascript
computer-science
equality
Nick Akey
fuente
fuente
2
por ejemplo, no lo es3
. Eso es. Del mismo modo123
no lo es124
. Una cadena es una colección de caracteres"abc"
diferente"abd"
pero tiene que verificar cada carácter.Respuestas:
Los números en las computadoras generalmente se manejan en unidades de tamaño fijo. Un
int
puede ser de 32 o 64 bits en cualquier combinación de idioma y / o compilador / plataforma, pero nunca será de longitud variable.Por lo tanto, tiene un número fijo de bits para comparar al comparar números. Es muy fácil construir un circuito de hardware que compare tantos bits a la vez (es decir, como "una acción").
Las cadenas, por otro lado, tienen longitudes inherentemente variables, por lo que solo decir "cadena" no le dice cuántos bits tendrá que comparar.
Sin embargo, hay excepciones, ya que hay números de longitud variable, generalmente llamados algo así
BigInteger
oBigDecimal
que se comportarán de manera muy similar a laString
comparación, ya que podría terminar siendo O (n) para comparar dosBigDecimal
valores de igualdad (donde n es la longitud de laBigDecimal
s , ninguno de sus valores numéricos).fuente
===
y==
, donde el==
operador permite hacer algo como lo1 == '1'
que se evaluará como verdadero, pero los documentos son muy vagos en cuanto a qué se convierten cada uno de los operandos antes de que se haga la comparación. Entonces, en este caso, si se convierten en una cadena, la comparación puede no ser una comparación de enteros, sino una comparación de cadenasO(n)
y ese es mi punto con mencionar esto especialmente cuando se trata de JavaScript.JavaScript uses a single numberic type
eso no es correcto. BigInt ahora es un tipo incorporado en JavaScriptPor lo general, los programas representan números como estructuras de datos de tamaño fijo (valores binarios, por lo que puede ver sus tamaños descritos en bits). Al ser de tamaño fijo, las comparaciones tomarían una cantidad constante de tiempo y serían O (1), que es uno de los beneficios de dicha representación. Una desventaja sería un límite en el rango de valores que se pueden representar.
Una representación alternativa que levanta esta restricción, permitiendo un rango de números arbitrariamente grande, por lo tanto, ya no sería de tamaño fijo, y ya no sería O (1) para comparar.
fuente
Cuerda
Las comparaciones de cadenas suelen ser una exploración lineal de los caracteres, que devuelve falso en el primer índice donde los caracteres no coinciden.
La complejidad del tiempo es O (N) y el tiempo real que se necesita depende de cuántos caracteres deben escanearse antes de que surjan diferencias estadísticamente. No hay una respuesta simple, pero la respuesta es obvia ;-)
Números
Si dos enteros son iguales, es imposible saberlo sin comparar todos sus bits. Entonces, en caso de igualdad, el tiempo necesario es proporcional al número de bits (que es proporcional al log (abs (N)) si N es uno de los comparables).
Si de hecho no son iguales, hay muchos casos, todos relevantes para la implementación interna. Las entradas largas se almacenan como un vector de "dígitos" en una base de potencia de 2. Si los vectores no tienen las mismas longitudes, entonces las entradas no son iguales, y eso lleva un tiempo constante.
Pero si tienen la misma longitud, entonces los "dígitos" deben compararse hasta encontrar el primer par (si lo hay) que no coinciden. Eso lleva un tiempo proporcional al número de dígitos que deben compararse.
fuente
En general, solo usamos la notación big-O cuando n puede elevarse a valores obscenamente grandes, porque la notación big-O describe cómo crece el tiempo de ejecución a medida que crece la entrada. Por ejemplo, al ordenar una lista, la mayoría de los mejores algoritmos se ordenan
O(n log n)
, lo que significa, y solo significa, que cuando la lista es lo suficientemente larga, el tiempo que lleva ordenarla es proporcionaln log n
. Cuando la lista no es lo suficientemente larga, otros factores (por ejemplo, en cualquier momento que su algoritmo pueda tomar para asignar espacio adicional), se vuelven significativos e incluso pueden tomar el tiempo de ejecución.Con las cadenas de JavaScript, de
n
hecho puede ser arbitrariamente grande *, por lo que decimos que la comparación llevaO(n)
tiempo. Pero con los números de JavaScript (que son números de coma flotante de precisión doble IEEE 754 ),n
tiene un límite máximo de 64-1 para un bit de signo, 11 para un exponente y 53 para dígitos significativos **. Debido a esto, sabemos exactamente cuánto tiempo tomará una comparación de números, y los mejores sistemas que tenemos para comparar números de ese tamaño exacto funcionan más o menos independientemente de cuántos de esos 64 dígitos cada número realmente tiene, por lo tanto, se considera comparar estos números en JavaScriptO(1)
.* Técnicamente, hay un límite superior porque la memoria RAM puede agotarse. Sin embargo, el idioma no especifica un tamaño máximo para las cadenas, y el
O(n)
parte de la comparación de cadenas domina el tiempo de ejecución mucho antes de que eso suceda.** Por cierto, esto significa que los números en JavaScript no pueden aumentar infinitamente. Más allá de cierto punto, comienzan a tirar dígitos más pequeños (por ejemplo, los números superiores a 2 ^ 53 solo pueden ser pares, y los números superiores a 2 ^ 54 solo pueden ser divisibles por 4), y cuando el número se hace lo suficientemente grande, se redondea hasta el infinito. Por el contrario, si divide un número una y otra vez para hacerlo infinitamente pequeño, eventualmente se redondeará a cero.
fuente