Oie gentem!!
Estou tentando arrumar esse programa que tenho que entregar até a meia-noite de hoje no site que a minha facul mandou, esse programa comentado, mas falta ordenar os dados, mas eu não sei como posso fazer isso.
Eis abaixo a descrição do problema:
1 Descri¸c˜ao do problema
Um campeonato de futebol foi disputado por n times identificados pelos seus
nomes. Para cada time s˜ao considerados os seguintes dados:
PontosGanhos – n´umero de pontos ganhos (3 por vit´oria, 1 por empate, 0
por derrota);
GolsMarcados – n´umero de gols marcados;
GolsSofridos – n´umero de gols sofridos (gols dif´ıceis de marcar :) );
SaldoDeGols – saldo de gols (GolsMarcados - GolsSofridos);
Vitorias – n´umero de vit´orias;
GolAverage – gol average (GolsMarcados / GolsSofridos, cuidado se Gols-
Sofridos = 0).
Escreva uma classe CampeonatoFutebol que possua os seguintes m´etodos:
1. Dados os resultados de m jogos, que podem ser entrados pelo teclado,
gere uma tabela com os resultados dos jogos. Cada resultado ´e representado
na forma (t1,t2,n1,n2) cuja interpreta¸c˜ao ´e a seguinte: no jogo
t1 × t2 o resultado foi n1 × n2.
Exemplo: (S˜ao Paulo, Milan, 3, 2) que foi o placar da vit´oria que
deu ao S˜ao Paulo o BICAMPEONATO MUNDIAL (exemplo inclu´ıdo,
infelizmente, pelo prof. Jos´e :( ).
2. Com a tabela anterior gerar uma tabela com todos os dados (Pontos-
Ganhos, GolsMarcados, GolsSofridos, SaldoDeGols, Vitorias, Gol-
Average, igual `aquela que sai no jornal) dos n times.
1
3. Com os mesmos dados do item 2, gere e imprima a classifica¸c˜ao dos
times no campeonato (do primeiro para o ´ultimo). A classifica¸c˜ao ´e
pelo n´umero de pontos ganhos (PontosGanhos) e em segundo lugar
pelo saldo de gols (SaldoDeGols). Se houver empate segundo os dois
crit´erios, classifique os times envolvidos como quiser.
4. Escreva um m´etodo que recebe como parˆametro o nome do time (uma
cadeia de caracteres) e retorna as informa¸c˜oes associadas a ele. Necessarimente
este m´etodo dever´a utilizar busca bin´aria.
5. N˜ao se esque¸ca de criar os testes para a classe CampeonatoFutebol e
tamb´em para as classes adicionais que vocˆe criar.
2 Programa Principal
Este exerc´ıcio-programa deve ser executado em linha de comando, ou seja,
a classe CampeonatoFutebol deve conter um m´etodo public static void
main(String [] args) que obt´em do teclado os dados dos times.
3 Seria¸c˜ao – parte extra
´E
poss´ıvel melhorar o programa um pouquinho mais. Por exemplo, voce
pode gravar o campeonato em um arquivo em disco e posteriormente lˆe-lo
deste arquivo. Se vocˆe implementar esta fun¸c˜ao adicional, o seu EP vale 12
(doze) pontos.
Para implementar isso, vocˆe deve utilizar um mecanismo poderoso da linguagem
Java chamado de seria¸c˜ao de objetos (object serialization). Atrav´es
deste mecanismo, ´e poss´ıvel transformar um objeto em uma s´erie de bytes,
armazenando-os em um arquivo. Posteriormente, ´e poss´ıvel desseriar o objeto,
ou seja, ler os bytes do arquivo e transform´a-los em objetos na mem´oria
do computador.
Como este processo ´e um pouco complicado, para facilitar vida de vocˆes,
criamos a classe SeriadorCampeonato o que est´a dispon´ıvel no arquivo
SeriadorCampeonato.java (n˜ao ´e preciso entender o c´odigo). Para utilizar
essa classe, copie o arquivo .java para o diret´orio onde est˜ao os seus
.java (e compile). O uso da classe ´e bem simples, ela cont´em apenas os dois
seguintes m´etodos.
/**
* Grava um objeto da classe ’CampeonatoFutebol’ num arquivo.
2
*
* Par^ametros:
* - meuCampeonato o ’CampeonatoFutebol’ que ser´a gravado
* no arquivo
* - nomeDoArquivo o nome do arquivo onde ser´a gravado o
* ’CampeonatoFutebol’
*/
void gravaCampeonato (CampeonatoFutebol meuCampeonato,
String nomeDoArquivo);
/**
* L^e um ’Campeonato’ de um arquivo.
*
* Par^ametros:
* - nomeDoArquivo o nome do arquivo de onde ser´a lido o
* ’CampeonatoFutebol’
* Valor de retorno: um objeto ’CampeonatoFutebol’ correspon-
* dente ao cat´alogo lido do arquivo
*/
CampeonatoFutebol carregaCampeonato (String nomeDoArquivo);
Veja a seguir um exemplo de uso, assumindo que a vari´avel campeonato
j´a armazena um objeto da classe CampeonatoFutebol.
> SeriadorCampeonato s = new SeriadorCampeonato();
> s.gravaCampeonato(campeonato, "campeonato.dat");
> Campeonato campeonato2 = s.carregaCampeonato("campeonato.dat");
> campeonato2.imprimeClassificacao()
S´o um pequeno detalhe: antes de usar a classe SeriadorDeCampeonato ´e
necess´ario explicitar ao compilador Java que as classes do nosso campeonato
ser˜ao seriadas. Para isso, basta inserir o texto implements java.io.Serializable
depois do nome das classes. Assim, o seu c´odigo dever´a ser semelhante
ao seguinte:
3
class CampeonatoFutebol implements java.io.Serializable
{
// blabla...
}
Quaisquer classes extras criadas para implementar o catálogo também devem
conter esse texto. Por exemplo, se vocˆe criou uma classe auxiliar Xyz usada
pela classe CampeonatoFutebol, a declara¸c˜ao dela dever´a ser parecida com
a seguinte.
class Xyz implements java.io.Serializable
Depois disso, crie o m´etodo testaSeriacao na classe TestaCampeonato
que testa a seria¸c˜ao. Este m´etodo n˜ao precisa ser muito complicado, vocˆe
pode, por exemplo, usar os m´etodos j´a implementados da classe TestaCampeonato.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Bem é isso, ficou com um probleminha de formatação... heheheh, abaixo segue o programa, mas falta colocar a ordenação, e ainda não sei como fazer... :cry:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[code]
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;
import javax.swing.JOptionPane;
/**
* Cria exception caso o formato do comando seja errado
*
*/
class FutebolException extends Exception{
private static final long serialVersionUID = 1L;
public FutebolException(String msg) {
super(msg); // construtor da superclasse Exception
}
}
/**
* Falta ordenar,
*
*
*/
abstract class Sortable {
public abstract int compareTo(Sortable b);
}
class ArrayAlg {
public static void shellSort(Sortable[] a) {
int n = a.length;
int incr = n / 2;
while (incr >= 1) {
for (int i = incr; i < n; i++) {
Sortable temp = a[i];
int j = i;
while (j >= incr && temp.compareTo(a[j - incr]) < 0) {
a[j] = a[j - incr];
j -= incr;
}
a[j] = temp;
}
incr /= 2;
}
}
}
/**
* Classe que representa um time de futebol
*
*/
class TimeFutebol extends Sortable {
private String nome;
private int PontosGanhos;
private int GolsMarcados;
private int GolsSofridos;
private int SaldoDeGols;
private int Vitorias;
private Double GolAverage;
public TimeFutebol(String nome1) {
this.nome = nome1;
this.PontosGanhos = 0;
this.GolsMarcados = 0;
this.GolsSofridos = 0;
this.SaldoDeGols = 0;
this.Vitorias = 0;
this.GolAverage = null; // considerar null se gols sofridos for 0
}
@Override
public String toString() {
return "Nome : " + this.nome
+ "\nPontos Ganhos: " + this.PontosGanhos
+ "\nGols Marcados: " + this.GolsMarcados
+ "\nGols Sofridos: " + this.GolsSofridos
+ "\nSaldo de Gols: " + this.SaldoDeGols
+ "\nVitorias : " + this.Vitorias
+ "\nGol Averages : " + ((this.GolAverage == null)? " -- " :
this.GolAverage);
}
public void setResult(int golsPro, int golsContra) {
this.GolsMarcados += golsPro;
this.GolsSofridos += golsContra;
this.SaldoDeGols = this.GolsMarcados - this.GolsSofridos;
if(this.GolsSofridos > 0)
this.GolAverage = Double.valueOf((double) this.GolsMarcados /
(double) this.GolsSofridos);
if(golsPro > golsContra) {
this.PontosGanhos += 3;
this.Vitorias++;
} else if (golsPro == golsContra) {
this.PontosGanhos++;
}
}
@Override
public int compareTo(Sortable o) {
TimeFutebol other = (TimeFutebol)o;
if (this.PontosGanhos > other.PontosGanhos)
return -1;
else if (this.PontosGanhos < other.PontosGanhos)
return 1;
if(this.SaldoDeGols > other.SaldoDeGols)
return -1;
else if (this.SaldoDeGols > other.SaldoDeGols)
return 1;
return 0;
}
}
/**
* Classe que retorna o resultado informado pelo usuário
* Devidamente validado
*/
class resultado{
int [] gols = new int[2];
String [] times = new String[2];
public resultado(String nome0, String nome1, int gol0, int gol1) {
this.gols[0] = gol0;
this.gols[1] = gol1;
this.times[0] = nome0;
this.times[1] = nome1;
}
@Override
public String toString() {
return this.times[0] + " " + this.gols[0] + " X " + this.gols[1] + "" + this.times[1];
}
}
/**
*
* Classe que realiza o campeonato de futebol
*
*/
public class CampeonatoFutebol {
private Hashtable times; // Hashtable com os times!
public CampeonatoFutebol() {
this.times = new Hashtable();
}
@SuppressWarnings("unchecked")
public void adicionaResultado(resultado r) {
Object o;
TimeFutebol tf;
if (!this.times.containsKey(r.times[0])) // Se não tiver o time 0, adiciona na hashtable
this.times.put(r.times[0],new TimeFutebol(r.times[0]));
if (!this.times.containsKey(r.times[1])) // Se não tiver o time 1, adiciona na hashtable
this.times.put(r.times[1],new TimeFutebol(r.times[1]));
o = this.times.get(r.times[0]); // Pega objeto da hashtable
tf = (TimeFutebol) o; // Converte no time de futebol novamente
tf.setResult(r.gols[0],r.gols[1]); // Adiciona o resultado
o = this.times.get(r.times[1]); // Mesma coisa com time adversario
tf = (TimeFutebol) o;
tf.setResult(r.gols[1],r.gols[0]); // Resultado invertido!
}
public void show() {
if(this.times.size() == 0) {
JOptionPane.showMessageDialog(null,"Nenhum time cadastrado.");
System.exit(0);
}
Enumeration nomes = this.times.keys();
while(nomes.hasMoreElements()) {
JOptionPane.showMessageDialog(null,this.times.get(nomes.nextElement().toString()));
}
}
public void sort() {
int x=this.times.size();
TimeFutebol [] varios_times = new TimeFutebol[x];
Enumeration nomes = this.times.keys();
for(int i=0;nomes.hasMoreElements();i++) {
varios_times[i] = (TimeFutebol) this.times.get(nomes.nextElement());
}
ArrayAlg.shellSort(varios_times);
for(int i=0;i<varios_times.length;i++) {
System.out.println(varios_times[i]);
}
}
/**
* Esta classe valida o comando do usuario, retorna exception caso o
formato seja invaludo
* @param opts
* @return resultado do jogo
* @throws FutebolException
*/
public static resultado validaCmd(String [] opts) throws
FutebolException {
int [] gols = {-1,-1};
if (opts.length >< 4) //devem haver 4 campos na informação
throw new FutebolException("O formato deve ser: time1, time2, gols1, gols2");
else if(opts[0].length() ==0 || opts[1].length() == 0)// nome do time não pode ser vazio
throw new FutebolException("Favor digitar os nomes dos 2 times");
else if(opts[0].trim().equalsIgnoreCase(opts[1].trim())) // o mesmo time jogando consigo mesmo?
throw new FutebolException("Favor digitar 2 times diferentes");
else if(opts[2].length() == 0 || opts[3].length() == 0) //não pode informar numero de gols vazio
throw new FutebolException("Favor digitar o numero de gols dos 2 times");
// valida formato
try {
gols[0] = Integer.parseInt(opts[2].trim());
gols[1] = Integer.parseInt(opts[3].trim());
} catch (Exception e) {
gols[0] = -1;
gols[1] = -1;
}
if(gols[0]< 0 || gols[1]<0) // analisa tanto o formato quanto o numero
throw new FutebolException("Numero incorreto de gols!");
// se tudo estiver ok...
return new resultado(opts[0].toLowerCase().trim(),
opts[1].toLowerCase().trim(),
gols[0],
gols[1]);
}
@SuppressWarnings("unchecked")
public static void main(String[] args) {
String cmd;
CampeonatoFutebol cf = new CampeonatoFutebol();
while(true) {
cmd = JOptionPane.showInputDialog ("Digite o resultado do jogo, quit para terminar: ");
if (cmd.trim().equalsIgnoreCase("quit"))
break; // para sair do loop
String [] opts = cmd.split(","); // 'splita' o resultado em torno de virgulas
try {
resultado r = validaCmd(opts); // valida resultado
JOptionPane.showMessageDialog(null,r.toString()); // DEBUG, pode comentar
cf.adicionaResultado(r);
} catch (FutebolException e) {
//JOptionPane.showMessageDialog(null,e.getMessage());
System.err.println(e.getMessage());
}
}
cf.sort();
//cf.show(); faltaaaaaaaaaa
// cf.imprime(); faltaaaaaa
System.exit(0);
}
}[/code]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~