Найти режим списка строк или целых чисел, используя HashMap в Java? - PullRequest
0 голосов
/ 18 ноября 2018

Я застрял в этом коде уже несколько дней и не могу понять.Метод getMedian работает нормально и выводит медиану как списка строк, так и списка целых чисел.Я знаю, что функция getMode близка к правильной, но я не могу заставить ее работать должным образом, и я пытаюсь использовать HashMap, чтобы заставить ее работать.В настоящее время он не будет печатать режим, если я не изменю метод getMode на «int».Большая проблема состоит в том, чтобы заставить его выводить как режим списка строк, так и список целых чисел, как медиана.Я мог бы действительно помочь с этим.

/*
 * Accepts Array of String or Integer and provides methods to return the mode and median
*
*/

package stats;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ModeNMedianProblem<E>
{

 private final List<E> elements;

public ModeNMedianProblem(E[] items)
{
    elements = new ArrayList<>();
    elements.addAll(Arrays.asList(items));
}

private class GenericComparator implements Comparator<E>
{


    @Override
    public int compare(E o1, E o2)
    {
        if (o1.getClass() == Integer.class)
        {
            Integer v1 = (Integer)o1;
            Integer v2 = (Integer)o2;
            return v1.compareTo(v2);
        }
        else if (o1.getClass() == String.class)
        {
            String v1 = (String)o1;
            String v2 = (String)o2;
            return v1.compareTo(v2);
        }
        else 
        {
            throw new IllegalArgumentException("Classes of type " + o1.getClass().toGenericString() + " are not supported.");
        }
    }
}


/**
 *
 * @param args
 * @return
 */
public List<E> getSortedList() 
{ 
    Collections.sort(elements,new GenericComparator());
    return elements;
}

public E getMedian() {

    int half = elements.size() / 2;
    return elements.get(half);        
}

public E getMode() {

    Map<E,Integer> freq = new HashMap<>();


    int mode = 0, maxCount = 0;
    int length = freq.size();

    for (int i = 0; i < length; ++i) 
    {
        int count = 0;
        for (int j = 0; j < length; ++j) 
        {
            if (freq.get(i) == freq.get(j)) 
                ++count;

            if (count > maxCount) 
            {
            maxCount = count;
            mode = freq.get(i);
            }
        }           
    }
    return mode;
}


/**
 * @param args the command line arguments
 */
public static void main(String[] args)
{
    String[] s = {"and","an","the","my","but","may","an","the","the"};
    Integer[] x = {1,5,9,2,4,3,7,100,2};

    ModeNMedianProblem mn1 = new ModeNMedianProblem(s);
    System.out.println("List: " + mn1.getSortedList());
    System.out.println("Median: " + mn1.getMedian());
    System.out.println("Mode: " + mn1.getMode());

    mn1 = new ModeNMedianProblem(x);
    System.out.println("List: " + mn1.getSortedList());
    System.out.println("Median: " + mn1.getMedian());
    System.out.println("Mode: " + mn1.getMode());

}

}

1 Ответ

0 голосов
/ 18 ноября 2018

Вы должны изменить свой метод getMode, чтобы использовать исходную коллекцию elements и вычислить режим.Одна из таких реализаций с использованием Java8 приведена ниже.

public E getMode() {
    Map<E, Long> elementToCount = elements.stream()
            .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
    return elementToCount.entrySet().stream().max(Map.Entry.comparingByValue()).map(Map.Entry::getKey)
            .orElseThrow(IllegalArgumentException::new);
}

Еще один момент, на который следует обратить внимание, заключается в том, что вы использовали необработанные типы в своем основном методе.Предпочитайте универсальные типы необработанным типам, поскольку это обеспечивает безопасность типов времени компиляции.Я бы посоветовал вам изменить основной метод следующим образом, чтобы использовать универсальные типы.

public static void main(String[] args) {
    String[] s = { "and", "an", "the", "my", "but", "may", "an", "the", "the" };
    Integer[] x = { 1, 5, 9, 2, 4, 3, 7, 100, 2 };

    ModeNMedianProblem<String> mn1 = new ModeNMedianProblem<>(s);
    System.out.println("List: " + mn1.getSortedList());
    System.out.println("Median: " + mn1.getMedian());
    System.out.println("Mode: " + mn1.getMode());

    ModeNMedianProblem<Integer> mn2 = new ModeNMedianProblem<>(x);
    System.out.println("List: " + mn2.getSortedList());
    System.out.println("Median: " + mn2.getMedian());
    System.out.println("Mode: " + mn2.getMode());

}

После внесения предложенных изменений вы получите следующий результат.

List: [an, an, and, but, may, my, the, the, the]
Median: may
Mode: the
List: [1, 2, 2, 3, 4, 5, 7, 9, 100]
Median: 4
Mode: 2
...