Найдите второй наиболее часто встречающийся символ в строке, используя HashMap - PullRequest
0 голосов
/ 12 июня 2019

Я пытаюсь найти второй по частоте символ в строке. ниже мой код

public class secondCommonAlpha {

    public Character secondCommon(String str)
    {
        Character ans = null;
        int first = 0, second = 0;
        HashMap<Character,Integer> counter = new HashMap<>();
        for(char c: str.toCharArray())
        {
            if(!counter.containsKey(c))
            {
                counter.put(c,1);
            }
            else
            {
                counter.put(c,counter.get(c) + 1);
            }
        }
        System.out.println(counter);
       for (char c: counter.keySet())
       {
           if(counter.get(c) > first)
           {
               second = first;

               first = counter.get(c);
           }
           else
               if(counter.get(c) > second && counter.get(c) < first)
           {
               second = counter.get(c);
               ans = c;
           }
       }
        return ans;
    }

    public static void main(String[] args) {
        secondCommonAlpha o = new secondCommonAlpha();
        System.out.println(o.secondCommon("bananassss"));
    }
}

не работает в третьей итерации. Как я могу исправить и оптимизировать этот код?

EDIT

Я использовал две символьные переменные, чтобы выполнить работу.

public Character secondCommon(String str)
    {
        Character ans = null;
        int first = 0, second = 0;
        Character firstChar = null,secondChar = null;
        HashMap<Character,Integer> counter = new HashMap<>();
        for(char c: str.toCharArray())
        {
            if(!counter.containsKey(c))
            {
                counter.put(c,1);
            }
            else
            {
                counter.put(c,counter.get(c) + 1);
            }
        }
        System.out.println(counter);
       for (char c: counter.keySet())
       {
           if(counter.get(c) > first)
           {

               second = first;
               secondChar = firstChar;
               firstChar = c;

               first = counter.get(c);
           }
           else
               if(counter.get(c) > second && counter.get(c) < first)
           {
               second = counter.get(c);

               secondChar = c;
           }
       }
        return secondChar;
    }

сейчас работает нормально, но я думаю, этот код можно оптимизировать.

1 Ответ

1 голос
/ 12 июня 2019

Здесь я написал обобщенную реализацию, которая даст вам n наиболее распространенных символов.В вашем случае вы можете указать 2, как показано в примере main.

Ответ достигается путем сортировки набора записей карты в порядке убывания по количеству вхождений (значение записи) и затем выбора n-1 (начиная с базового нуля) индексы с начала списка.

public static char nMostCommon(String str, int n) {
    Map<Character, Long> counter = str.chars()
        .mapToObj(c -> (char) c)
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
    if (counter.size() < n) {
        throw new IllegalArgumentException("Not enough different characters.");
    }
    return counter.entrySet().stream()
        .sorted(Comparator.comparing(Map.Entry::getValue, Comparator.reverseOrder()))
        .map(Map.Entry::getKey)
        .collect(Collectors.toList())
        .get(n - 1);
}

public static void main(String[] args) {
    System.out.println(nMostCommon("bananassss", 2));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...