Clash
Clash

Reputation: 23

Find most occurred character in a String

I have this code:

public char charCounter(String input){
ArrayList<Character> list = new ArrayList<Character>();
for (Character c : input.toCharArray()) {
list.add(c);

There is a way to find a character most frequent in input String without to use the HashMap?

I tried to use:

int max = Collections.max(list.values())

but I can't.

Could help me someone? Thanks

Upvotes: 0

Views: 1614

Answers (5)

Vadim
Vadim

Reputation: 4120

If ArrayList is a requirement: After you built your ArrayList make a loop again over characters from input and use

Collections.frequency(list, c)

to get a number of each character occurrences which you will put into max if max is smaller.

PS. to make it more "smart" :-) you can create a Set<Character> in parallel with your list to have distinct characters from your input, and then loop through that set to get Collections.frequency(list, c).

Or you can remove tested character from list by using removeAll method only, if you do not need your list anymore - at the end it will be empty.

UPDATED - working code - there are 2 variations with removeAll usage - one for first most character and second for last if there are more than 2 characters with the same number of occurrences. As long as you created your list inside the method and need only most Character returned there is no reason to keep list unchanged. It is gone at the end of method anyway.

note: (I made them static only because for testing I used main - you do not need to do that) - pick one :

    public static void main(String... args) {

    String input = "This is a simple test string+++++";

    System.out.println("charCounterV1First: first most Character: "
            + charCounterV1First(input));
    System.out.println("charCounterV1Last: last most Character: "
            + charCounterV1Last(input));

}

public static char charCounterV1First(String input) {
    ArrayList<Character> list = new ArrayList<Character>();
    for (Character c : input.toCharArray()) {
        list.add(c);
    }

    int max = 0;
    Character mostChar = null;
    ArrayList<Character> remList = new ArrayList<Character>();
    while (list.size() > 0) {
        Character nextChar = list.get(0);
        int count = Collections.frequency(list, nextChar);
        if (count > max) {
            max = count;
            mostChar = nextChar;
        }
        remList.clear();
        remList.add(nextChar);
        list.removeAll(remList);
    }
    return mostChar;
}

public static char charCounterV1Last(String input) {
    ArrayList<Character> list = new ArrayList<Character>();
    for (Character c : input.toCharArray()) {
        list.add(c);
    }

    int max = 0;
    Character mostChar = null;
    ArrayList<Character> remList = new ArrayList<Character>();
    while (list.size() > 0) {
        Character nextChar = list.get(0);
        int count = Collections.frequency(list, nextChar);
        if (count >= max) {
            max = count;
            mostChar = nextChar;
        }
        remList.clear();
        remList.add(nextChar);
        list.removeAll(remList);
    }
    return mostChar;
}

Upvotes: 0

Mordechai
Mordechai

Reputation: 16184

Here you go:

public char charCounter(String input){
    input = input.toLowerCase();
    int max = 0;
    int diff;
    char maxChar = '\0'; // in case it's an empty string, ignore if you don't understand
    for(char c = 'a'; c <= 'z'; c++) {
         diff = input.length() - input.replace("" + c, "").length();
        if(diff > max) {
            maxChar = c;
            max = diff;
        }
    }
    return maxChar;
}

This is case insensitive. You can tweak it a little to make it case sensitive.

Upvotes: 1

ruakh
ruakh

Reputation: 183211

Another approach is to sort the character-array, and then iterate over it to find the longest stretch of consecutive duplicates:

final char[] charArray = input.toCharArray();
java.util.Arrays.sort(charArray);

int maxCount = -1;
char charWithMaxCount = '\0';
int i = 0;
while (i < charArray.length) {
    int j = i;
    while (j < charArray.length && charArray[j] == charArray[i]) {
        ++j;
    }
    if (j - i > maxCount) {
        maxCount = j - i;
        charWithMaxCount = charArray[i];
    }
    i = j;
}

// now charWithMaxCount is the desired result

Upvotes: 0

Anton Dovzhenko
Anton Dovzhenko

Reputation: 2569

In case character set is limited with ANSI, the next approach can be used.

  1. Create int array if symbol occurrences
  2. Increment the array value on every character occurrence using the fact, that character can be casted to integer

Please, see the code below:

public static char getMaxFrequencyCharacter(String str) {
    int[] occurrences = new int[255];
    for (int i = 0; i < str.length(); i++) {
        occurrences[str.charAt(i)]++;
    }
    int max = 0;
    char symbol = 0;
    for (int i = 0; i < occurrences.length; i++) {
        if (occurrences[i] > max) {
            max = occurrences[i];
            symbol = (char) i;
        }
    }
    return symbol;
}

Also note, that there can be several characters with the same max frequency. In this case you should

  1. Find max occurrences number
  2. Collect all characters where occurrences[i] == max

Upvotes: 1

Scary Wombat
Scary Wombat

Reputation: 44813

here is a case-sensitive version

    String word = "hello my name is wombat";
    int size = word.length();
    int max = 0;
    char maxChar = 'a';
    for (char x = 'A'; x <= 'z'; x++) {
        word = word.replace(String.valueOf(x), "");
        int newSize = word.length();
        if (size - newSize > max) {
            maxChar = x;
            max = size - newSize;
        }
        size = newSize;
    }

    System.out.println("maxchar is " + maxChar);

Upvotes: 0

Related Questions