subodh
subodh

Reputation: 6158

How to find out the most appear numbers from the String?

I have a String which contains numbers in a comma separated form. and I want to extract the most appears numbers from the String. For example I have a String like..

String str="1,2,3,4,5,6,7,19,18,4";

from the above str i need 4 because 4 is two times in str.

same as

String str2="1,2,3,4,6,4,3,9";

from the above str2 i need 3,4

In case of all numbers are unique then i need first one.

suggest me better approach.

Upvotes: 2

Views: 358

Answers (6)

Arend von Reinersdorff
Arend von Reinersdorff

Reputation: 4233

Here's a solution using java.util and Guava collect.

Outline:

  1. Split String into list of words
  2. Count the frequency of each word and create a map Word -> Count
  3. Invert to create a Multimap Count -> Words
  4. Convert to a sorted NavigableMap
  5. Get Words with highest count
  6. Return Words with hightest count

Code:

public class HighestCountFinder {


    public static ImmutableSet<String> findWordsWithGreatestCount(String wordsString) {
        List<String> words = split(wordsString, ",");

        Map<String, Integer> wordsToCounts = toMapWithCounts(words);

        Multimap<Integer, String> countsToWords = toInverseMultimap(wordsToCounts);

        NavigableMap<Integer, Collection<String>> countsToWordsSorted = toNavigableMap(countsToWords);

        Collection<String> wordsWithHighestCount = lastValue(countsToWordsSorted);

        return ImmutableSet.copyOf(wordsWithHighestCount);
    }


    public static ImmutableList<String> split(String wordsString, String separator) {
        Iterable<String> parts = Splitter.on(separator).split(wordsString);
        return ImmutableList.copyOf(parts);
    }


    public static ImmutableMap<String, Integer> toMapWithCounts(Iterable<String> entries) {
        Multiset<String> entriesWithCounts = HashMultiset.create(entries);
        return toMap(entriesWithCounts);
    }


    public static <E> ImmutableMap<E, Integer> toMap(Multiset<E> multiset) {
        ImmutableMap.Builder<E, Integer> immutableMapBuilder = ImmutableMap.builder();
        for (Multiset.Entry<E> entry : multiset.entrySet()) {
            immutableMapBuilder.put(entry.getElement(), entry.getCount());
        }
        return immutableMapBuilder.build();
    }


    public static <K, V> ImmutableMultimap<V, K> toInverseMultimap(Map<K, V> map) {
        Multimap<K, V> multimap = Multimaps.forMap(map);
        return ImmutableMultimap.copyOf(multimap).inverse();
    }


    public static <K, V> NavigableMap<K, Collection<V>> toNavigableMap(Multimap<K, V> multimap) {
        return new TreeMap<>(multimap.asMap());
    }


    public static <V> V lastValue(NavigableMap<?, V> navigableMap) {
        return navigableMap.lastEntry().getValue();
    }
}

Upvotes: 0

sje397
sje397

Reputation: 41802

I would have an array of map of integers to count each number, and variable to store the number with the highest count.

Split the string into a list of numbers, and loop over the list.

Each time you look at a new number, increment its counter in the map, and if that count is greater than the current highest count, change the current highest to the current. At the end of the string, return the current highest.

Note that, if you also store the number with the second biggest count, you can optimise slightly by exiting the loop early, when there are not enough numbers left to allow the second highest count to exceed the highest.

Upvotes: 2

Fahim Parkar
Fahim Parkar

Reputation: 31627

Try Below Code

public class StringCheck {
    public static void main(String args[]) {
        String input = "1,2,3,4,5,6,2,3,4,1,4,33,33,33";
        String result = "";
        String[] arr1 = input.split(",");

        System.out.println("Input is : " + input);

        for (int i = 0; i < arr1.length; i++) {
            int k = 0;
            for (int j = 0; j < arr1.length; j++) {
                if (arr1[i].equals(arr1[j])) {
                    k++;
                    if (k == 2) {
                        if (result.contains(arr1[i])) {
                            break;
                        }
                        result = result + arr1[i] + ",";
                        break;
                    }
                }
            }
        }

        System.out.println("Result is " + result);
    }
}    

Below will be output

Input is : 1,2,3,4,5,6,2,3,4,1,4,33,33,33
Result is 1,2,3,4,33,

Let me know if there are any queries...

Cheers!!!

Upvotes: 0

JB Nizet
JB Nizet

Reputation: 691635

Transform your String into a list of numbers.

Remember what the first number of the list is.

Sort the list of numbers.

Iterate over the list and keep

  • the number of occurrences of the current number.
  • the current max number of occurrences of a number
  • the number of distinct numbers you met
  • the set of numbers that have a number of occurrences equals to the max

At each iteration, if the current number is equal to the current max, add the current number to the result. If it's greater than the current max, clear the set of results and add the current number to the results.

At the end of the loop, if the size of the result set is equal to the number of distinct numbers, return the first number you remembered before sorting the list.

Upvotes: 1

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726479

Assuming that this is a homework, I'll suggest a general idea without the code:

  • Start by splitting the string on the ',' characters
  • Create an initially empty map of Integer to Integer with the counts
  • Go through the parts you've got back from the split, and parse them as int values
  • For each value, see if there is a corresponding item in the map; if there is a number there, increment it; otherwise, add an entry with the new number and 1.
  • Once you're done with the tokens, go through the map and find the max value
  • If the max is 1, return the first token
  • If the max is not 1, go through the map again, and collect all keys where the value is equal to max

This approach lets you work with very large numbers, and it does not discriminate between numbers with and without leading zeros. In other words, it will identify 3 in 1,2,03,3,3,2 sequence as a unique winner, not as a tie with 2.

Upvotes: 2

Sufian Latif
Sufian Latif

Reputation: 13356

You can tokenize the string using java.util.StringTokenizer using , as the separator, then strip off the leading and trailing spaces from each token using String.trim(), then store them into an array of ints using Integer.parseInt() function. Then you can count them easily.

For counting:

If you have a small range of numbers, then you can simply create a counter array and use each number as an index to that array. If not, then you can use HashMap or something like that.

Upvotes: 2

Related Questions