[Resolvido] Comando if aninhado no comando for

5 respostas
L
Estou com dúvida na compreensão desse programa que funciona perfeitamente. Até onde já aprendi, após ambas avaliações possíveis da expressão do if ele iria retornar true ou false para o método e terminaria a execução do método. Mas, parece que há um retorno para o for novamente e o reinicio da avaliação até alcançar o último índice do arranjo onde a avaliação do if será true e retornará ao método o false. O que faz o if não fazer uma única e definitiva seleção? Seria pelo fato de ele está aninhado dentro do for?
class exercicio4{
	public static void main(String[] args){
	int [] arranjo= new int[] {2,2,2,2,2,3};
	//iguais(arranjo);
	System.out.println(iguais(arranjo));
	}
	
	static boolean iguais(int[] ai){
    if(ai==null| ai.length<=1 )return true;
    for(int i=0; i<ai.length-1; i++)
      if(ai[i]!=ai[i+1]) return false; //como entender a interação?
    return true;
  } 
  }

Att,

5 Respostas

davidbuzatto

return para é retornar de um método.
break é para parar uma estrutura de repetição
continue é para pular para a próxima iteração em uma estrutura de repetição.

O que o seu código faz é verificar se todos os elementos de um array são iguais correto?
Ele compara cada par adjacente de elementos.

Se algum par (ai[i] e ai[i+1]) forem diferentes, quer dizer que o array não tem pelo menos um par de elementos iguais (em toda sua extensão), sendo assim a execução do método é finalizada e é então retornado false. Perceba que o for não continua executando, pois o método terminou, sendo assim, vc economiza tempo. Caso todo o for tenha executado e nenhuma diferença tenha sido encontrada, o método retorna true.

O return no caso, como disse, é para terminar a execução do método, retornando um valor (ou não caso o método seja void).

Existem algumas soluções diferentes para seu algoritmo, sendo menos “performáticas”.

Por exemplo, percorrendo todo o for:

boolean diferente = false; for(int i=0; i<ai.length-1; i++) if(ai[i]!=ai[i+1]) diferente = true; return diferente;

Parando o for e continuando a execução do método até a última linha:

boolean diferente = false; for(int i=0; i<ai.length-1; i++) { if(ai[i]!=ai[i+1]) { diferente = true; break; } } return diferente;

Perceba que a solução que vc fez é mais rápida, pois ao encontrar o problema já retorna direto.

Entendeu?

[]´s

L

Muito obrigado pelo retorno.

Desculpa não ter informado o que o método faz, é realmente o que vc disse.

Ainda tenho a mesma dúvida, vou tentar me expressar melhor dessa vez.

class exercicio4{
	public static void main(String[] args){
	int [] arranjo= new int[] {2,2,2,2,2,3};
	System.out.println(iguais(arranjo));
	}
	
	static boolean iguais(int[] ai){
        if(ai==null| ai.length<=1 )return true;
        for(int i=0; i<ai.length-1; i++)

a primeira interação do for será avaliada como true, e passará para o comando if

if(ai[i]!=ai[i+1]) return false;
a avaliação do if será false, pois possuem valores iguais ambos índices (ai[i]!=ai[i+1]). Então ele retornará o return true, que está logo aqui embaixo:
return true;
  } 
  }

aqui surge a dúvida: Por que o programa não termina já na primeira avaliação do if, já que já temos um return? Não entendo por que após a primeira avaliação o for será executado novamente, uma vez alcançado o primeiro return dentro de um método o fluxo de controle não retorna para o main e finaliza o programa? Ou se trata de algum método recursivo e não me dei conta ainda?

davidbuzatto

Não não não!

Está vendo como faz falta usar as chaves? Dificulta o entendimento do código.
Vc pode ter um for e um if sem chaves, sendo assim, apenas a primeira instrução é considerada do bloco.

O return true do seu código não faz parte do for! Ele está fora do for.

Seu código é equivamente a

static boolean iguais(int[] ai){  
    if(ai==null | ai.length<=1 ) { 
        return true;
    }
    for(int i=0; i<ai.length-1; i++)  {
        if(ai[i]!=ai[i+1]) {
            return false;
        }
    }
    return true;  // está vendo? o return true não está dentro do for, apenas o if.
}

Sugiro que use o operador de curto circuito or ( || ) ao invés de apenas |, pois seu código usando o | pode diparar uma NullPointerException. O "|" força a avaliação dos dois lados da expressão, mesmo que a primeira retorne true. Usando ||, assim que a primeira parte for avaliada como true, o bloco do if é executado. No seu código, tente passar um null como parâmetro para o método para vc ver o que vai acontecer.

Seu código não é recursivo (recursão é quando um método chama a ele mesmo ou a outro método que chama o primeiro, etc).
Agora só apenas como curiosidade, vc consegue algo parecido usando recursão que vc mencionou. Nesse algoritmo é algo totalmente "inútil" pois a solução pode ser alcançada de forma fácil através de um algoritmo iterativo (que é o quê vc fez).

public static void main( String[] args ) {

    System.out.println( igual( new Integer[]{ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }) );

}

public static boolean igual( Integer[] array ) {	

    if ( array.length == 1 ) {
        return true;
    } else if ( array[0] != array[1] ) {
        return false;
    } else {
        List<Integer> lista = Arrays.asList( array );
        /* poderia ter feito lista.remove(0) ao invés de criar uma sublista, 
         * mas a implementação de lista retornada pelo método asList de 
         * Arrays não suporta o método remove() (que é opcional pelo 
         * contrato da interface List)
         */
        return igual( lista.subList( 1, lista.size() ).toArray( new Integer[0] ) );
    }

}

Use sempre chaves para delimitar seus blocos, a leitura fica mais fácil.
Mesmo quando vc fica experiente e consegue bater o olho no código e ver o quê faz parte do quê, é legal usar as chaves para alguém com menos experiencia entender tbm.

[]´s

L

Finalmente entendi =)

static boolean iguais(int[] ai){    
    if(ai==null || ai.length<=1 )  {   
       return true;  
		 }  
    
	for(int i=0; i<ai.length-1; i++){ //quando o if é avaliado false ele retorna novamente ao for, 
           if(ai[i]!=ai[i+1]){        //dentro do qual está aninhado, e reiinicia a iteração, e quando o for                        
            return false;             //estiver avaliado como false o fluxo vai finalmente para o return true.
         }  
     
	 }  
     return true;    
 } 
  }

Fiz o teste do operador ||, e realmente saiu um NullPointerException. Já fiz a alteração sugerida.

Muito obrigado!

davidbuzatto

De nada Luciano.

Só tome cuidado com a identação do seu código, está um pouco bagunçada. Boa identação também ajuda compreenção :wink:

[]´s

Criado 25 de outubro de 2009
Ultima resposta 25 de out. de 2009
Respostas 5
Participantes 2