Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Meu código trava meu navegador. Onde está o erro?

A ideia é gerar uma sequencia de números aleatórios e inserir no array. Na função inserirNoArray() tentei fazer que não houvesse números repetidos.

<meta charset="UTF-8">

<script>
    function pulaLinha(){
        document.write("<br>");
    }
    function mostra(x){
        document.write(x)
        pulaLinha()
    }
//---------------------------------------------------

var sequencia = [];
function geraUm(){
    return Math.round(Math.random()*10);
}

function inserirNoArray(x){
    for(calc=1;calc<=x;calc++){
        var numero = geraUm();
        for(posicao=0;posicao<=sequencia.length;posicao++){
            if(numero == sequencia[posicao]){
            break;
            }else{
                sequencia.push(numero);
                calc++;
            }
        }
    }
}

inserirNoArray(5);
mostra(sequencia);
</script>

Estou no início da Lógica de programação. Gostaria que me ajudassem a verificar se há erro de lógica e/ou de linguagem

2 respostas

Olá Patrick, tudo bem com você?

Então, realmente existe um erro de lógica no seu código que cria um loop infinito até que o navegador trave, mas vou te explicar com calma :)

Temos um exemplo até bem parecido em nosso curso de lógica, mas o problema esta nessa verificação:

            if(numero == sequencia[posicao]){
                break;
            }else{
                sequencia.push(numero);
                calc++;
            }

Vamos fazer o que chamamos de teste de mesa, que é testar o nosso código em uma folha de papel:

Vamos supor que chamamos a função inserirNoArray(3), temos o primeiro for e logo criamos o nosso:

numero = geraUm();

Vamos supor que o número aleatório sorteado foi 8, então temos o segundo for e começa as verificações:

for(posicao=0;posicao<=sequencia.length;posicao++){

numero é igual a sequência na posição 0 ?

Não, então adicionamos o número o número 8, agora temos:

  • Sequência: [ 8 ]

Voltamos para o for agora com posição = 1 e sequencia.length = 1 e vamos para a verificação:

numero é igual sequência na posição 1 ?

Não, então adicionamos o número 8, agora temos:

  • Sequência: [ 8, 8 ]

Voltamos para o for agora com posição = 2 e sequencia.length = 2 e vamos para a verificação:

numero é igual sequência na posição 2 ?

Não, então adicionamos o número 8

Bem, acredito que já entendeu o que está acontecendo, na verdade precisamos que a posição seja menor que sequencia.length e não menor igual :)

Mas temos um outro problema:

Imagine que começamos o nosso array de sequencia da seguinte maneira e corrigimos o problema acima:

  • Sequência = [ 1, 3]

E vamos utilizar a mesma lógica:

'número é igual a posicao[0] ?

Não, 8 é diferente de 1, então insere

número é igual a posicao[1] ?

Não, 8 é diferente de 3, então insere

numero é igual a posicao[2] ?

Sim, então quebra o loop!

Isto é, inserimos duas vezes o número secreto e só paramos porque encontramos o primeiro 8 inserido pelo nosso loop, então não estamos realmente evitando números repetidos, pelo contrário, estamos vários repetidos

E a razão disso é que na verdade não temos uma relação de if- else, na verdade temos uma condição de 2 if's, basicamente o nosso programa precisa funcionar da seguinte maneira:

  • Olha percorrer todos elementos do array e veja se tem algum repetido, se existir me avisar
  • Então, existe repetido?

O que você fez foi basicamente:

  • Olha percorre todos elementos e se o elemento não for diferente então insere na lista

E para termos o comportamento que queremos é bem simples, precisamos criar uma variável de controle, por exemplo: var existe = false depois do primeiro for

E deixaremos nosso for da seguinte maneira:

        for(posicao=0;posicao < sequencia.length;posicao++){
            if(numero == sequencia[posicao]){
                existe = true;
                break;
            }

Ou seja percorre todos elementos e me diz se tem alguém repetido, E após acabar esse for teremos:

            if(existe == false){
                sequencia.push(numero);
            }

Ou seja, se existe terminou como false então pode inserir que não é repetido

E uma última mudança que precisamos fazer:

O for sempre que termina a execução acrescenta uma unidade em calc, então da maneira que você fez, sem loop infinito e sem inserir repetido ainda temos um problema, que é se inserimos repetido no final ele acaba fazendo o calc++, então não vamos ter a quantidade que queremos

Para corrigir isso precisamos trocar o for por um while que ai temos controle de quando queremos que aumente :)

Então no final teremos algo parecido com isso:

        var sequencia = [];
        var contador = 0;
        function geraUm() {
            return Math.round(Math.random() * 10);
        }

        function inserirNoArray(x) {
            while (contador < x) {
                var existe = false;
                var numero = geraUm();
                for (posicao = 0; posicao < sequencia.length; posicao++) {
                    if (numero == sequencia[posicao]) {
                        existe = true;
                        break;
                    }
                }
                if (existe == false) {
                    sequencia.push(numero);
                    contador++;
                }
            }
        }

        inserirNoArray(5);
        mostra(sequencia);

Abraços e Bons Estudos!

solução!

Obrigado pela dedicação, entendi perfeitamente.