Home > Back-end >  Count the most occuring character
Count the most occuring character

Time:06-23

At a user entered string, I am having a tough time with the counter. The code locates the most occurring character but where can I put counter that it counts the most occurring character. In Java, with the current code please. It's the last method.

import java.util.*;

public class newTest {
    public static void main(String[] args) {
        Scanner scnr = new Scanner(System.in);

        System.out.println("Please enter a one line sentence:");
        String words = scnr.nextLine();

        findAlphabetMode(words);

    }

    public static void findAlphabetMode(String input){
        int[] freq = new int[input.length()];
        char mode = input.charAt(0);
        boolean noMode = true;
        int counter = 0;
        int steadyCount = 0;

        char string[] = input.toCharArray();

    for (int i = 0; i < string.length; i  ){
     freq[i] = 1;
        for(int j = i   1; j < string.length; j  ){
          if(string[i] == string[j] && string[i] != ' ' && string[i] != 0){
            freq[i]  ;
            //counter  ;
          }
          if(counter > 1){
              if(counter > steadyCount){
                  steadyCount = counter   1;
                  counter = 0;
              }
          }
          if(string[i] == string[j]){
            noMode = false;
            string[j] = 0;
            counter  ;
          }
        }
    }
    int max = freq[0];

    for(int i = 0; i < freq.length; i  ){
      if(max < freq[i]){
        max = freq[i];
        mode = string[i];
        noMode = false;
      }
    }

        if (noMode) {
            System.out.println("Mode: No Mode");
        }
        else {
            System.out.println("The letter "   mode   " occurs "   steadyCount   " times");
        }
    }
}
`

CodePudding user response:

You don't need a nested for loop. That makes your algorithm O(N^2) i.e. when your input string length doubles, the time taken increases fourfold.

You can put each letter in the input string into a Map<Character, Integer>, increasing the value each time you add an existing character, and then at the end find the key with the largest value. A succinct way of doing this is to use streams:

public static void findAlphabetMode(String input) {
    input.chars()
        .boxed()
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
        .entrySet()
        .stream()
        .max(Map.Entry.comparingByValue())
        .ifPresentOrElse(
                e -> System.out.printf("The letter %c occurs %d times%n", e.getKey(), e.getValue()),
                () -> System.out.println("No mode"));
}

CodePudding user response:

Must not be that complicated, even without streams:

public static void findAlphabetMode(String input) {
    var freq = new int['z'-'a' 1];
    for (var ch : input.toLowerCase().toCharArray()) {
        if (ch >= 'a' && ch <= 'z') {
            freq[ch-'a']  = 1;
        }
    }
    var max = 0;  // index to maximum freq
    for (var i = 1; i < freq.length; i  ) {
        if (freq[i] > freq[max]) {
            max = i;
        }
    }
    var ch = (char) ('a'   max);
    System.out.printf("found %d times %c%n", freq[max], ch);
}

Not to hard to combine second loop into first loop:

public static void findAlphabetMode(String input) {
    var freq = new int['z'-'a' 1];
    var max = 0;  // index to maximum freq
    for (var ch : input.toLowerCase().toCharArray()) {
        if (ch >= 'a' && ch <= 'z') {
            if (   freq[ch-'a'] > max) {
                max = ch - 'a';
            }
        }
    }
    var ch = (char) ('a'   max);
    System.out.printf("found %d times %c%n", freq[max], ch);
}

Note: this only counts letters a-z after converting to lower case.

CodePudding user response:

You don't need to separately increment counter, since you are already calculating frequency for each character, in an array, you can simply loop, over the array and find your maximum occuring character. Here is a simplified version of your code:

import java.util.*;

public class newTest {
    public static void main(String[] args) {
        Scanner scnr = new Scanner(System.in);
        System.out.println("Please enter a one line sentence:");
        String words = scnr.nextLine();
        findAlphabetMode(words);
    }

    public static void findAlphabetMode(String input){
        int[] freq = new int[input.length()];
        char mode = input.charAt(0);
        char string[] = input.toCharArray();
        for (int i = 0; i < string.length; i  ){
         freq[i] = 1;
         for(int j = i   1; j < string.length; j  ){
            if(string[i] == string[j]){
              freq[i]  ;
            }
         }
      }
      int max = freq[0];

      for(int i = 0; i < freq.length; i  ){
        if(max < freq[i]) {
         max = freq[i];
         mode = string[i];
       }
     }
     System.out.println("The letter "   mode   " occurs "   max   " times");
    }
}

CodePudding user response:

If you still prefer loops you can do it like so.

  • iterate across the string, checking only letters
  • use map.merge to compute the frequency.
String s =
        "To be or not to be, that is the question.";

Map<Character, Integer> map = new HashMap<>();
for (Character c : s.toCharArray()) {
    if (Character.isLetter(c)) {
        map.merge(c, 1, Integer::sum);
    }
}

Now that the frequency is counted, just find the largest

  • first, make certain characters exist
  • otherwise, iterate across the entry set finding the maximum value and saving the associated character.
if (map.isEmpty()) {
    System.out.println("Mode: No Mode");
} else {

    Entry<Character, Integer> result = null;
    char chr = ' ';
    int count = 0;
    for (Entry<Character, Integer> e : map.entrySet()) {
        int val = e.getValue();
        if (val > count) {
            count = val;
            chr = e.getKey();
        }
    }
    System.out.printf("The letter `%c` occurs %d times.%n", chr, count );
}

prints

The letter `t` occurs 6 times.

If you want to ignore case, you can do the following in the first loop.

for (Character c : s.toLowerCase().toCharArray()) {
...
}
  •  Tags:  
  • java
  • Related