Home > Back-end >  How to find the second most frequent character in java?
How to find the second most frequent character in java?

Time:10-24

What I am trying to achieve is, when there is a given word, I need to find out the second most frequent character within that string.

In additions to that, there is some more options I want to achieve. For example,

  1. If a string, "ababababd" is given, there are four 'a's, four 'b's, and one 'd', so in this case, I need to printout 'd'.

  2. If a string is "ababababdc" is given, there are four 'a's, four 'b's, one 'd' and 'c', I need to printout 'dc'

    public class MemorizeWorld {
        public static void main(String[] args) {
        Solution solution = new Solution();
        String a = "ababababd";
        solution.solution(a);
     }
    }
    
    class Solution {
         public void solution(String a) {
             int[] array = new int[26];
             char[] char_array = a.toCharArray();
    
             for(int i = 0; i < char_array.length; i  ) {
                 int index = char_array[i] - 'a';
                 array[index]  ;
             }
             int max = 0;
             for(int i = 0; i < array.length; i  ) {
                 if(array[i] > max) {
                     max = array[i];
                 }
             }
         }
     }
    

This is what I have done so far and I am stuck on getting a solution. I know how to get the second most frequent character by following the post from geeksforgeeks, but I don't know how I should apply those two options above to that. Is there anyone who can help me with this problem?

CodePudding user response:

Find the second maximum just like you've found the maximum.

int max2 = 0;
for(int i = 0; i < array.length; i  ) {
    if(array[i] > max2 && array[i] < max) {
         max2 = array[i];
     }
}

Then get the result string whose frequency is same as the second maximum.

String result = "";
for(int i = 0; i < array.length; i  ) {
    if(array[i] == max2) {
         result  = (i   'a');
     }
}

CodePudding user response:

// most frequent character in a given string public class Example { static final int NO_OF_CHARS = 256;

static char getSecondMostFreq(String str)
{
    
    int[] count = new int[NO_OF_CHARS];
    int i;
    for (i=0; i< str.length(); i  )
        (count[str.charAt(i)])  ;
  
   
    int first = 0, second = 0;
    for (i = 0; i < NO_OF_CHARS; i  )
    {
       
        if (count[i] > count[first])
        {
            second = first;
            first = i;
        }
  
      
        else if (count[i] > count[second] &&
                 count[i] != count[first])
            second = i;
    }
  
    return (char)second;
}
  

public static void main(String args[])
{
  String str = "ababababd";
  char res = getSecondMostFreq(str);
  if (res != '\0')
     System.out.println("Second most frequent char" 
                                   " is "   res);
  else
     System.out.println("No second most frequent" 
                                   "character");
}

}

CodePudding user response:

Stream API may be used in this solution:

  1. create a frequency map using Collectors.groupingBy Collectors.summingInt / Collectors.counting()
  2. "invert" the frequency and character using Collectors.toMap or Collectors.groupingBy Collectors.joining to merge characters with the same frequency; use a TreeMap with the reversed key comparator
  3. skip the first value referring the max frequency, and return the next one:
public static String get2ndMostFrequent(String str) {
    if (null == str || str.length() < 2) {
        return null;
    }
    return Arrays.stream(str.split("")) // Stream<String> chars
        .collect(Collectors.groupingBy(
            s -> s, LinkedHashMap::new, Collectors.summingInt(s -> 1)
        ))
        .entrySet()
        .stream()
        .collect(Collectors.toMap(
            Map.Entry::getValue,
            Map.Entry::getKey,
            (s1, s2) -> s1   s2,
            () -> new TreeMap<Integer, String>(Comparator.reverseOrder())
        ))
        .values()
        .stream()
        .skip(1)
        .findFirst()
        .orElse(null);
}

Tests:

for (String s : Arrays.asList("ababababd", "ababdababc", "dabbcacd", "acbdagh")) {
    System.out.println(s   " -> "   get2ndMostFrequent(s));
}

Output

ababababd -> d
ababdababc -> dc
dabbcacd -> null  // no 2nd frequency
acbdagh -> cbdgh
  • Related