Alguem me ajuda a simplificar isto?

14 respostas
M

,

14 Respostas

F

O que exatamente isso deveria fazer ?

M

este metodo recebe um array com 10 valores e encontra o numero ou os numeros que se repetem mais vezes

victorwss

meninuuuuu:
public static void moda( int[] entrados){ int posR = 0, valorAnt = 0, count = 0, countAux = 0; int[] r = new int[10]; for (int x = 0; x < entrados.length; x++) { if (x == 0) { valorAnt = entrados[x]; count++; countAux++; r[posR] = entrados[x]; posR++; } else { if (entrados[x] == valorAnt) { countAux++; if (countAux > count) { Arrays.fill(r, 0); count = countAux; r[0] = entrados[x]; } else if (countAux == count) { r[posR] = entrados[x]; posR++; } } else if (entrados[x] != valorAnt && count == 1) { countAux = 1; valorAnt = entrados[x]; r[posR] = entrados[x]; posR++; } else { countAux = 1; valorAnt = entrados[x]; } } }
este metodo encontra a moda num dado arrey foi o melhor que soube fazer alguem me ajuda a simplificar isto?

  1. Retirando o excesso de endentação:public static void moda(int[] entrados) { int posR = 0, valorAnt = 0, count = 0, countAux = 0; int[] r = new int[10]; for (int x = 0; x < entrados.length; x++) { if (x == 0) { valorAnt = entrados[x]; count++; countAux++; r[posR] = entrados[x]; posR++; } else { if (entrados[x] == valorAnt) { countAux++; if (countAux > count) { Arrays.fill(r, 0); count = countAux; r[0] = entrados[x]; } else if (countAux == count) { r[posR] = entrados[x]; posR++; } } else if (entrados[x] != valorAnt && count == 1) { countAux = 1; valorAnt = entrados[x]; r[posR] = entrados[x]; posR++; } else { countAux = 1; valorAnt = entrados[x]; } } } } // Estava faltando este fecha chave!2. O for é uma estrutura de repetição. Não faz sentido você repetir desde o primeiro elemento se esse tem um tratamento especial. Neste caso começamos iterando do segundo elemento. Para o caso especial de o array estar vazio (e neste caso não termos nenhuma iteração no for), basta usar um if no começo.public static void moda(int[] entrados) { if (entrados.length == 0) return; int posR = 0, valorAnt = 0, count = 0, countAux = 0; int[] r = new int[10]; valorAnt = entrados[0]; count++; countAux++; r[posR] = entrados[0]; posR++; for (int x = 1; x < entrados.length; x++) { if (entrados[x] == valorAnt) { countAux++; if (countAux > count) { Arrays.fill(r, 0); count = countAux; r[0] = entrados[x]; } else if (countAux == count) { r[posR] = entrados[x]; posR++; } } else if (entrados[x] != valorAnt && count == 1) { countAux = 1; valorAnt = entrados[x]; r[posR] = entrados[x]; posR++; } else { countAux = 1; valorAnt = entrados[x]; } } }3. Simplificando a inicialização das variáveis, simplificando a condição no else if, já que lá entrados[x] != valorAnt sempre é verdadeiro e simplificado os blocos em comum nos ifs e elses:public static void moda(int[] entrados) { if (entrados.length == 0) return; int posR = 1, valorAnt = entrados[0], count = 1, countAux = 1; int[] r = new int[10]; r[0] = entrados[0]; for (int x = 1; x < entrados.length; x++) { if (entrados[x] == valorAnt) { countAux++; if (countAux > count) { Arrays.fill(r, 0); count = countAux; r[0] = entrados[x]; } else if (countAux == count) { r[posR] = entrados[x]; posR++; } } else { countAux = 1; valorAnt = entrados[x]; if (count == 1) { r[posR] = entrados[x]; posR++; } } } }Agora, eu não entendi o que é r, porque que o tamanho é 10 e como fica o array entrados no final.
victorwss

Ei, vi agora que você apenas lê os valores de entrados, mas não os modifica.

Ou seja, na forma em que está, este método não faz nada que seja útil!

M

m

M

.

victorwss

O return é porque se o array entrados tiver tamanho zero, o método não faz nada.

Mas, ainda não entendi o que o método tem que fazer. Explica aí.

B

Moda

Basicamente retornar um array que possua o valor ou valores mais frequentes, onde a frequencia do elemento(s) é maior que a média dos elementos, em outras palavras, se todos os elementos tiverem a mesma frequencia, não há moda.

victorwss
Reidentando o código:
import java.util.*;
public class ModaMedia {
    public static int[] teclado() {
        int b;
        int[] a = new int[10];
        Scanner teclado = new Scanner(System.in);
        for (int i = 0; i < a.length; i++) {
            b = teclado.nextInt();
            a[i] = b;
        }
        return a;
    }

    public static double media(int[] entrados) {
        double soma = 0;
        for (int i = 0; i < entrados.length; i++) {
            soma = entrados[i] + soma;
        }
        soma /= entrados.length;
        return soma;
    }

    public static void moda(int[] entrados) {
        if (entrados.length == 0) return;
        int posR = 1, valorAnt = entrados[0], count = 1, countAux = 1;
        int[] r = new int[10];
        r[0] = entrados[0];
        for (int x = 0; x < entrados.length; x++) {
            if (entrados[x] == valorAnt) {
                countAux++;
                if (countAux > count) {
                    Arrays.fill(r, 0);
                    count = countAux;
                    r[0] = entrados[x];
                } else if (countAux == count) {
                    r[posR] = entrados[x];
                    posR++;
                }
            } else {
                countAux = 1;
                valorAnt = entrados[x];
                if (count == 1) {
                    r[posR] = entrados[x];
                    posR++;
                }
            }
        }

        System.out.print("Moda: ");
        for (int i = r.length - 1; i >= 0; i--) {
            if (r[i] != 0) {
                System.out.print(r[i] + " ");
            }
        }
    }

    public static void main(String[] args) {
        int[] a = ModaMedia.teclado();
        System.out.println("Media: " + ModaMedia.media(a));
        ModaMedia.moda(a);
    }
}
Assim fica mais fácil entender! Agora sim. Você estava usando um martelo para cortar cana! Estava usando a ferramenta errada. Vou usar um Map para relacionar os elementos com as respectivas freqüências. Vou aproveitar e otimizar os demais métodos com o enhanced-for e com simplificações nas operações. Também coloquei os métodos como privados (não há porque serem públicos). Por fim, eu tirei os System.out de dentro do método moda para não misturar lógica de negócio (cálculo) com apresentação.
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class ModaMedia {
    private static final int TAMANHO = 10;

    private static int[] teclado() {
        int[] a = new int[TAMANHO];
        Scanner teclado = new Scanner(System.in);
        for (int i = 0; i < a.length; i++) {
            System.out.print("Digite o " + (i + 1) + "o número: ");
            a[i] = teclado.nextInt();
        }
        return a;
    }

    private static double media(int[] entrados) {
        int soma = 0;
        for (int i : entrados) {
            soma += i;
        }
        return ((double) soma) / entrados.length;
    }

    public static Collection<Integer> moda(int[] entrados) {
        // Cria um mapa relacionando o elemento ao número de ocorrências.
        Map<Integer, Integer> frequencias = new HashMap<Integer, Integer>();
        int maiorFrequencia = 0;
        for (int e : entrados) {
            Integer valor = frequencias.get(e);
            valor = (valor == null ? 1 : valor + 1);
            if (valor > maiorFrequencia) maiorFrequencia = valor;
            frequencias.put(e, valor);
        }

        // Filtra o mapa, deixando apenas os elementos com a maior freqüência (ou seja, a moda).
        frequencias.values().retainAll(Collections.singleton(maiorFrequencia));

        return frequencias.keySet();
    }

    public static void main(String[] args) {
        int[] a = ModaMedia.teclado();
        System.out.println("Média: " + ModaMedia.media(a));
  
        Collection<Integer> moda = ModaMedia.moda(a);
        System.out.print("Moda:");
        for (Integer i : moda) {
            System.out.print(" " + i);
        }
    }
}
M

j

victorwss

Você leu o minha mensagem anterior por inteira e cuidadosamente?

M

como tinha dito isto e mesmo trabalho de escolinha :S não posso usar ainda o teu exmplo aintrior

victorwss
meninuuuuu:
como tinha dito isto e mesmo trabalho de escolinha :S não posso usar ainda o teu exmplo aintrior
public static int[] moda(int[] entrados) {
    // Cria dois arrays de tamanho igual relacionando o elemento ao número de ocorrências.
    int[] frequencias = new int[entrados.length];
    int[] valores = new int[entrados.length];
    int tamanho = 0;
    int maiorFrequencia = 0;

    for (int e : entrados) {
        // Descobre aonde está o elemento no array ou aonde colocar se ele não estiver .
        boolean jaTem = false;
        int indice = 0;
        for ( ; indice < tamanho; indice++) {
            if (valores[indice] != e) continue;
            jaTem = true;
            break;
        }

        // Conta o elemento.
        frequencias[indice]++;
        if (!jaTem) {
            valores[indice] = e;
            tamanho++;
        }
        if (maiorFrequencia < frequencias[indice]) maiorFrequencia = frequencias[indice];
    }    

    // Cria um array com os valores filtrados, deixando apenas os elementos com a maior freqüência (ou seja, a moda).  
    int tamanhoModa = 0;
    int[] rascunhoModa = new int[tamanho];
    for (int i = 0; i < tamanho; i++) {
        if (frequencias[i] != maiorFrequencia) continue;
        rascunhoModa[tamanhoModa] = valores[i];
        tamanhoModa++;
    }

    // Cria o array definitivo e retorna.
    int[] moda = new int[tamanhoModa];
    for (int i = 0; i < tamanhoModa; i++) {
        moda[i] = rascunhoModa[i];
    }
    return moda;
}
int[] moda = ModaMedia.moda(a);
     System.out.print("Moda:");
     for (int i : moda) {
         System.out.print(" " + i);
     }
M

muitooooo obrigado se poderes adicona-me no msn para poder ir trocando alguma ideias abraço
nuno
[email removido]

Criado 8 de novembro de 2008
Ultima resposta 9 de nov. de 2008
Respostas 14
Participantes 4