Eficiência

11 respostas
T

aloha…

Eu tenho que implementar um método que conta o número de elementos de um array ordenado que se encontram no intervalo [b,c]. Por exemplo, o array [1,2,4,6,7,9] e o intervalo [2,8], o método retorna 4 . Mas preciso de o algoritmo o mais eficiente possível.
Eu fiz o seguinte :

public static int countInterval(int[]a,int b,int c){
		int i=a.length/2;
		int j=i;
		
		while(i>=0 && i<a.length){
			
			if(a[i]==b || (a[i+1]>b && a[i-1]<b)) break;
			else{
				if(a[i]>b){i=i/2;continue;}
				if(a[i]<b){i+=i/2;continue;}
			}
			
		}
		while(j>=0 && j<a.length){
			if(a[j]==c|| (a[j+1]>c && a[j-1]<c))break;
			else{
				if(a[j]>c){j=j/2; continue;}
				if(a[j]<c){j+=j/2; continue;}
			}
		}
		
		return j-i+1;
		
	}

Utilizando duas pesquisas binárias, penso que seja o mais eficiente…

Haverá alguma maneira mais eficiente de fazer isto ???

11 Respostas

von.juliano

Procure pelo algortimo dos métodos quicksort e mergesort. Me parece que o mergesort é o mais rápido, mais não sei como é sua implementação. O quick é um pouco mais lento, mas estou certo que vc vai encontrar o algoritmo dele na internet. Blz! :thumbup:

T

Mas o array de entrada já está ordenado, ela só quer achar o subintervalo. Eu também acho que duas buscas binárias são suficientes e eficientes para o caso dela.

ViniGodoy

Eu concordo com o Thingol.

No java, existe o método Arrays.binarySearch, que pode ser usado no lugar de seus whiles.

Outra coisa, esteja sempre preparada para o caso dos elementos passados como parâmetro não existirem. Nesse caso lance alguma exceção do tipo IllegalArgumentException ou ArrayIndexOutOfBoundsException.

Mantu

Parece que no Java 6 tem umas collections que já trabalham com “ranges”. Eu acho que vi isso num pdf do Luca, de uma palestra que ele ministrou certa feita…

kaabah

Isso depende dos casos… o tipo de entrada faz a diferença no pior e melhor caso de cada algoritmo de ordenação…

:idea:

louds

Se você tiver um histograma do array, ou sober que os valores são distribuidos de maneira uniforme, pode usar busca por interpolação, o pior caso dela é da mesma ordem que a busca-binária, porém o caso comum é muito melhor.

von.juliano

Foi mal gente, faltou de atenção pra responder :oops: .

sergiotaborda
public int count(int[] array , int a, int b ){

 if (a==b){
return 0;
} else if (a>b){
   throw new IllegalArgumentException("o inicio do intervalo é maior que o fim")
}
 Arrays.sort(array) // necessário apenas se array não está ordenado.

// supoe-se que a < b 
 int ka = Arrays.binarySearch(array,a);
 int kb = Arrays.binarySearch(array,b);
 
 // obtém posições onde o numero foi encontrado,ou deveria ser
 ka = ka <0 ?  Math.abs(ka)-1:ka;
 kb= kb <0 ?  Math.abs(kb)-1:kb;

 return kb-ka;

}
Mantu

Então, li novamente sobre o Java 6, e lá agora tem uma interface chamada NavigableSet que extend SortedSet. A classe TreeSet agora implementa esta NavigableSet.
Esta nova interface tem um método assim:

NavigableSet<E> subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) {...}
Ele parece que já faz todo o trabalho de que você tá preisando, Telma.
Ainda naum testei (To só com Java 5 na minha máquina) mas acho que isso aqui resolveria o problema:

public class Teste {
	public static void main(String[] args) {
		System.out.println(
			countInterval(new Integer[] {1,2,4,6,7,9}, 2, 8)
		);
	}
	
	public static int countInterval(Integer[] arr, int a, int b) {
		TreeSet<Integer> set = new TreeSet<Integer>(
			Arrays.asList(arr)
		);
		return set.subSet(a, true, b, true).size();
	}
}

Testem aí e vejam se dá certo, ok?

[color=darkblue][size=18]NOTAS DE EDIÇÃO[/size]:
:arrow: De fato, funciona mesmo o código acima. Acabo de testá-lo no meu recém instalado Mustang. Agora, não sei como é a performance dessa bagaça, teria que dar uma lida no javadoc da classe TreeSet ou então der uma olhada no código fonte.
:arrow: Infelizmente, teremos que fuçar o código fonte pra descobrir o algoritmo utilizado na classe TreeSet, uma vez que a documentação deste método no javadoc do Mustang simplesmente copia a especificação dste método lá da interface NavigableSet.
[/color]

kaabah

Nota de edição foi boa… heheheheheh!!! :lol:

T

Muito obrigada a todos… eu realmente não posso usar coisas já feitas… tenho que ser eu a implementar, pois isto é para a faculdade. Mas deu para ter uma ideia…

obrigadão !!

Criado 2 de março de 2007
Ultima resposta 2 de mar. de 2007
Respostas 11
Participantes 8