Laços de repetição com 2 vetores

Galera, desde já agradeço a ajuda de vocês!

Estou com um problema, é simples porém sou novo na área e não entendo muito, tenho um laço de repetição que funciona com 2 vetores, veja:

int[] temp = { 1, 2, 5, 4, 3, 5, 2, 1, 3, 3, 6, 4, 3, 3, 3, 2, 3, 3, 2, 1 };
int oc[] = new int[6];

	for (int i = 0; i < temp.length; i++) {
		++oc[temp[i]];

	}

O que eu queria entender é como ele funciona e como a variável i vai até 10!!, sei que no final ele retorna um error, ArrayIndexOutOfBoundsException, porém só queria entender principalmente isso " ++oc[temp[i]]; ", usei o debug do eclipse porém não entendi a ideia por trás do laço

O length retorna o tamanho, já quando você usa um array você utiliza a posição e as posições começam em 0, acho que resolveria ser vc botasse ++oc[temp[i -1]];

++alguma_coisa faz com que o valor de alguma_coisa aumente em 1. Por exemplo:

int x = 4;
++x; // aumenta o valor de x em 1
System.out.println(x); // 5

Então ++oc[temp[i]] aumenta o valor de oc[temp[i]].


O for está pegando todos os elementos de temp e usando eles como índice do array oc, e incrementando o valor deles em 1 (lembrando que ao inicializar o array, os valores dele são setados para zero).

E o que acontece quando i é igual a 10? O valor de temp[i] será 6, e você tentará pegar oc[6].

Mas oc é um array com 6 números (new int[6]), e os índices de um array começam em zero (ou seja, os índices dele vão de zero a 5). Então ao tentar acessar oc[6], ocorre o ArrayIndexOutOfBoundsException (você está tentando acessar uma posição que não existe).

Nesse caso específico sim, mas e se temp tivesse 10, 1000, ou qualquer outro número maior?

Não sei, e agora fiquei com uma pulga atrás da orelha, pq realmente me falta conhecimento pois não vejo problema nisso. O que daria de errado? A melhor forma seria diminuir -1 no temp.length então?

A “melhor forma” depende do que ele precisa (o código é quase aleatório e não dá dicas sobre quais são as regras, me parece aqueles exemplos para demonstrar algum mecanismo, sem aplicação prática de fato).

Mas uma forma de evitar o erro é verificar se o valor está entre zero e o tamanho do array:

for (int i = 0; i < temp.length; i++) {
    int n = temp[i];
    if (0 <= n && n < oc.length) {
        ++oc[n];
    }
}

Mas como eu já disse, como não tem requisitos, não dá pra afirmar se essa era intenção (mas pelo menos não dará ArrayIndexOutOfBoundsException).

1 curtida

Parece-me que o objectivo é contar quantos elementos existem no primeiro array e guardar no segundo array os valores.

// array temp tem valores aleatórios entre 1 e 6
int[] temp = { 1, 2, 5, 4, 3, 5, 2, 1, 3, 3, 6, 4, 3, 3, 3, 2, 3, 3, 2, 1 };  
// array oc vai contar quantos existem de cada 
int oc[] = new int[6];

O que é importante perceber é que os arrays começam na posição 0, então ao aceder à posição 6 (é o 11º elemento do array inicial, daí funcionar bem até i = 10) vai dar esse erro de ArrayIndexOutOfBoundsException.
Então, precisas de guardar sempre na posição -1 do array oc, o que dá (atenção que não é o que foi colocado acima!)

    for (int i = 0; i < temp.length; i++) {
	++oc[temp[i] - 1];

}

Explicando: se o elemento na posição i do array temp é 2, vamos incrementar a posição 2-1, ou seja 1, do array oc.

Ao chegar ao fim sabemos quantos elementos existem para cada número:

  for (int i = 0; i < oc.length; i++) {
 	System.out.println("Existem " + oc[i] + " ocorrências do digito " + (i+1)); // aqui teremos de somar 1 a i já que guardamos na posição i-1
  }

Galera obrigado pela ajuda! esse é um pequeno pedaço de uma questão de concurso! vou deixar aqui ela completa!! Se poderem deixar uma explicação da questão também ajudaria, eu peguei o trecho do código da questão que não entendi!

Capturar|262x500 Capturar2