Menor valor e unico de um arraylist

13 respostas
F

Boa noite pessoal , estou com um problema gostaria de saber…
Como faço p retornar de um arraylist o menor valor e unico ?

13 Respostas

M

Bom, pelo visto o que você precisa não é um ArrayList. Se você detalhar melhor poderíamos ajudar de uma maneira mais adequada.

F
public class Carro implements Produto {
private String descricao;
Cotains 
List<Lance>lances=new ArrayList <Lance>();

public Carro(String descricao) {
	this.descricao = descricao;
}



@Override
public boolean Oferta(Lance lance) {
  return lances.add(lance);
	
}



//retorna lance vencedor = menor valor e unico 
// nao consigo retornar valor unico aq
@Override
public Lance finalizar() {
	double menor = lances.size(); 
for (Lance lance : lances) {
	if(lance.getValor() < menor){ 
	    menor = lance.getValor();
            System.out.println(menor); 
  return lance;
    }
 } 
	
 return null;
}



@Override
public String getDescricao() {
	return descricao;
}




//deve receber um lance e informar se o lance já foi efetuado
public boolean lanceJaFeito(Lance lance) {
	if (lances.contains(lance)) {
		System.out.println("Lance ja efetuado  : " +lance);
		return true;
		
	} else {
		System.out.println("Lance disponivel : " +lance);
		return false;
	}
}


}
P

Acho que isso deve resolver seu problema:

public int finalizar(int[] lances) {
		int ganhador = Integer.MAX_VALUE;
		
		for (int lance : lances) {
			if (ehUnico(lances, lance)) {
				if (lance < ganhador) {
					ganhador = lance;
				}
			} 
		}

		return ganhador;
	}
		
	protected boolean ehUnico(int[] valores, int v) {
		boolean visitouProprio = false;
		for (int x : valores) {
			if (!visitouProprio && v == x) {
				visitouProprio = true;
				continue;
			}
			if (v == x)
				return false;
		}
		
		return true;
	}

Adapte para sua situação… é um problema de lógica interessante que exige realmente um grande raciocínio. Fiz testes de unidade para conseguir resolver esse problema mais rapidamente e aparentemente ele resolve. Faça muitos testes para ter certeza que o código está legal :smiley:

Abraços

M

Outra alternativa(um tanto diferente do habitual):

HashMap<Integer, Integer> lances = new HashMap<Integer, Integer>();
	HashMap<Integer, Set<Integer>> numLances = new HashMap<Integer, Set<Integer>>();
	
	public void addLance(int valor) {
		if(lances.get(valor) == null) { 
			lances.put(valor, 1);
			addNumLance(1, valor);
		} else {
			int valorAntigo = lances.get(valor);
			removeNumLance(valorAntigo, valor);
			lances.put(valor, valorAntigo++);
			addNumLance(valorAntigo++, valor);
		}
	}
	
	private void addNumLance(int valor, int el) {
		Set<Integer> valores = numLances.get(valor);
		if(valores == null) {
			valores = new HashSet<Integer>();
			numLances.put(valor, valores);
		}
		valores.add(el);
	}
	
	private void removeNumLance(int valor, int el) {
		Set<Integer> valores = numLances.get(valor);
		if(valores != null) {
			valores.remove(el);
		}
	}
	
	public int getMenorLance() {
		Set<Integer> conjunto = numLances.get(1);
		int val = Collections.min(conjunto);
		return val;
	}
V

Você poderia ainda usar um SortedSet (TreeSet) no lugar de um hashset, pois isso já deixaria os lances ordenados. Isso evita o uso do Collections.min, que é muito mais custoso.

P

Me parece, como sugere uma parte do código que vc postou, que o seu aplicativo deve impedir a entrada de um lance já existente.
Isto simplificaria a solução do seu problema, pois é bem mais fácil obter o menor valor do que o menor e único.
E, só por curiosidade… não é o maior lance que ganha a parada?

M

pinto:
Me parece, como sugere uma parte do código que vc postou, que o seu aplicativo deve impedir a entrada de um lance já existente.
Isto simplificaria a solução do seu problema, pois é bem mais fácil obter o menor valor do que o menor e único.
E, só por curiosidade… não é o maior lance que ganha a parada?

Acho que ele está tentando implementar aqueles leilões de tv, onde o menor lance único leva o produto.

M
ViniGodoy:
Você poderia ainda usar um SortedSet (TreeSet) no lugar de um hashset, pois isso já deixaria os lances ordenados. Isso evita o uso do Collections.min, que é muito mais custoso.

Muito bem lembrado. Código reformulado:

HashMap<Integer, Integer> lances = new HashMap<Integer, Integer>();
	SortedSet<Integer> lancesUnicos = new TreeSet<Integer>();
	
	public void addLance(int valor) {
		if(lances.get(valor) == null) { 
			lances.put(valor, 1);
			lancesUnicos.add(valor);
		} else {
			int valorAntigo = lances.get(valor);
			lances.put(valor, valorAntigo++);
			lancesUnicos.remove(valor);
		}
	}
	
	public int getMenorLance() {
		return lancesUnicos.first();
	}
P

marcio_gs:
pinto:
Me parece, como sugere uma parte do código que vc postou, que o seu aplicativo deve impedir a entrada de um lance já existente.
Isto simplificaria a solução do seu problema, pois é bem mais fácil obter o menor valor do que o menor e único.
E, só por curiosidade… não é o maior lance que ganha a parada?

Acho que ele está tentando implementar aqueles leilões de tv, onde o menor lance único leva o produto.


Ok, faz sentido.
E neste caso realmente todo lance é bem-vindo. :wink:

V
pinto:
Me parece, como sugere uma parte do código que vc postou, que o seu aplicativo deve impedir a entrada de um lance já existente. Isto simplificaria a solução do seu problema, pois é bem mais fácil obter o menor valor do que o menor e único. E, só por curiosidade... não é o maior lance que ganha a parada?

Ele poderia controlar na entrada através de 2 Sets. Um para lances não únicos já realizados, e outro para lances únicos.

Set<Integer> lancesNaoUnicos = new HashSet<Integer>();
SortedSet<Integer> lancesUnicos = new TreeSet<Integer>();

public void darLance(int valor) {
   if (lancesNaoUnicos.contains(valor)) //Já foi dado
      return;
   if (lancesUnicos.remove(valor)) { //Se conseguiu remover dos lances únicos
      lancesNaoUnicos.add(valor);  //É pq é um lance duplicado.
   } else {
      lancesUnicos.add(valor); //Senão é um lance único.
   }
}

public int menorLance() {
   return lancesUnicos.first();
}

Uma classezinha para o lance que una o valor e a pessoa que deu o lance pode ser bastante útil nesse caso.

M

Concordo que para resolver o problema dois Sets são o suficiente, porém dessa maneira se perde informações que podem ser necessárias no futuro. Com dois Sets você sabe que o lance foi ofertado 1 vez ou mais de 1.

Digamos que ninguém dê um lance único e, consequentemente, não haja ganhador. Para evitar problemas, a organização resolve dividir o prêmio com quem deu o menor lance, sendo que ele não é mais único e pode ser divido por 2 pessoas ou mais. Teria que ser refeito parte do código já criado para atender os novos requisitos.

V

marcio_gs:
Concordo que para resolver o problema dois Sets são o suficiente, porém dessa maneira se perde informações que podem ser necessárias no futuro. Com dois Sets você sabe que o lance foi ofertado 1 vez ou mais de 1.

Digamos que ninguém dê um lance único e, consequentemente, não haja ganhador. Para evitar problemas, a organização resolve dividir o prêmio com quem deu o menor lance, sendo que ele não é mais único e pode ser divido por 2 pessoas ou mais. Teria que ser refeito parte do código já criado para atender os novos requisitos.

Basta daí trocar o Set de lances não únicos por um List, mas haverá perda de performance.
Entretanto, também acho sua solução melhor. É como eu faria.

F

Correto isso mm .

Acho que ele está tentando implementar aqueles leilões de tv, onde o menor lance único leva o produto.

Bom sou novato em Java e a partir de suas ideia , apliquei da seguinte forma :Qq coisa corrigem-me plisss =]
Muito Obrigado !! :D

public class Carro implements Produto {
private String descricao;

 Set<Lance> lancesNaoUnicos = new HashSet<Lance>();  
 SortedSet<Double> lancesUnicos = new TreeSet<Double>();  
 
public Carro(String descricao) {
	this.descricao = descricao;
}

//

@Override
public boolean Oferta(Lance lance) {
	
	if(lancesNaoUnicos.contains(lance.getValor()) )
	return false;
	if(lancesUnicos.remove(lance.getValor())){
		lancesNaoUnicos.add(lance);
	}else{
		  lancesUnicos.add(lance.getValor());		  
	}

	return true;
}

//

@Override
public Lance finalizar() {
	System.out.println("Lance Menor e Unico : "+lancesUnicos.first());  	
		return null;
}

//


@Override
public String getDescricao() {
	return descricao;
}


}
Criado 29 de novembro de 2009
Ultima resposta 30 de nov. de 2009
Respostas 13
Participantes 5