Entendo que, para comparar duas seqüências de caracteres para a igualdade, o intérprete precisa iterar as duas e comparar cada caractere.
Isso tornaria a complexidade do tempo 0(n)
onde n
está o comprimento da string mais curta.
No entanto, comparar dois números para igualdade é 0(1)
.
Por que é que? O intérprete não precisaria percorrer todos os números para verificar a igualdade?
javascript
computer-science
equality
Nick Akey
fonte
fonte
2
por exemplo, não é3
. É isso aí. Da mesma forma123
não é124
. Uma string é uma coleção de caracteres"abc"
diferente,"abd"
mas você deve verificar cada caractere.Respostas:
Os números nos computadores geralmente são tratados em unidades de tamanho fixo. A
int
pode ter 32 ou 64 bits em qualquer combinação de idioma e / ou compilador / plataforma, mas nunca terá comprimento variável.Portanto, você tem um número fixo de bits para comparar ao comparar números. É muito fácil criar um circuito de hardware que compare muitos bits de uma vez (ou seja, como "uma ação").
As strings, por outro lado, têm comprimentos inerentemente variáveis; portanto, você apenas dizendo "string" não diz quantos bits você terá que comparar.
Porém, existem exceções, pois existem números de comprimento variável, geralmente chamados de algo como
BigInteger
ouBigDecimal
que se comportam muito semelhantes àString
comparação, pois pode acabar sendo O (n) comparar doisBigDecimal
valores de igualdade (onde n é o comprimento deBigDecimal
s , nenhum dos valores numéricos).fonte
===
e==
operadores, onde o==
operador permite a fazer algo como1 == '1'
o que irá avaliar a verdade, mas os docs são muito vagos sobre o que cada um dos operandos são convertidos em diante a comparação é feita. Portanto, neste caso, se eles são convertidos em string, a comparação pode não estar fazendo inteiro comparar, mas sim String de comparaçãoO(n)
e esse é o meu ponto de trazer isso à tona, especialmente quando está envolvido em javascript.JavaScript uses a single numberic type
não está correto. BigInt agora é um tipoGeralmente, os programas representam números como estruturas de dados de tamanho fixo (valores binários, e é por isso que você pode ver seus tamanhos descritos em bits). Sendo de tamanho fixo, as comparações levariam um tempo constante e seriam O (1), que é um dos benefícios de tal representação. Uma desvantagem seria um limite no intervalo de valores que podem ser representados.
Uma representação alternativa que elimine essa restrição, permitindo um intervalo arbitrariamente grande de números, não seria mais fixada em tamanho e não seria mais O (1) para comparação.
fonte
Corda
As comparações de cadeia de caracteres geralmente são uma varredura linear dos caracteres, retornando false no primeiro índice em que os caracteres não coincidem.
A complexidade do tempo é O (N) e o tempo real depende de quantos caracteres precisam ser verificados antes que as diferenças apareçam estatisticamente. Não há uma resposta simples, mas a resposta é óbvia ;-)
Números
se dois números inteiros são iguais, é impossível saber sem comparar todos os seus bits. Portanto, em caso de igualdade, o tempo necessário é proporcional ao número de bits (que é proporcional ao log (abs (N)) se N for um dos comparandos).
Se eles não são iguais, existem muitos casos, todos relevantes para a implementação interna. Ints longos são armazenados como um vetor de "dígitos" em uma base de potência de 2. Se os vetores não tiverem o mesmo comprimento, as entradas não serão iguais, e isso leva tempo constante.
Mas se tiverem o mesmo comprimento, os "dígitos" deverão ser comparados até encontrar o primeiro (se houver) par incompatível. Isso leva um tempo proporcional ao número de dígitos que precisam ser comparados.
fonte
Em geral, usamos a notação big-O somente quando n pode subir para valores obscenamente grandes, porque a notação big-O descreve como o tempo de execução aumenta à medida que a entrada aumenta. Por exemplo, ao classificar uma lista, a maioria dos melhores algoritmos é classificada
O(n log n)
- o que significa, e somente significa, que quando a lista é longa o suficiente, o tempo que leva para classificá-la é proporcional an log n
. Quando a lista não é longa o suficiente, outros fatores (por exemplo, a qualquer momento que seu algoritmo leve para alocar espaço extra) tornam-se significativos e podem potencialmente levar o tempo de execução.Com seqüências de JavaScript,
n
pode realmente ficar arbitrariamente grande *, por isso dizemos que a comparação levaO(n)
tempo. Porém, com números JavaScript (que são números de ponto flutuante de precisão dupla IEEE 754 ),n
tem um limite máximo de 64-1 para um bit de sinal, 11 para um expoente e 53 para dígitos significativos **. Por isso, sabemos exatamente quanto tempo levará para que uma comparação de números ocorra, e os melhores sistemas que temos para comparar números desse tamanho exato funcionam mais ou menos da mesma forma, independentemente de quantos desses 64 dígitos cada número realmente Portanto, a comparação desses números no JavaScript é consideradaO(1)
.* Tecnicamente, há um limite superior porque a RAM pode acabar. No entanto, o idioma não especifica um tamanho máximo para seqüências de caracteres, e o
O(n)
parte da comparação de cadeias domina o tempo de execução muito antes disso.** A propósito, isso significa que os números no JavaScript não podem aumentar infinitamente. Depois de um certo ponto, eles começam a jogar fora dígitos menores (por exemplo, números acima de 2 ^ 53 só podem ser pares e números acima de 2 ^ 54 só podem ser divisíveis por 4) e, quando o número fica grande o suficiente, ele arredonda para cima ao infinito. Por outro lado, se você dividir um número repetidamente para torná-lo infinitesimalmente pequeno, ele acabará arredondando para zero.
fonte