Take the 2-minute tour ×

Note: The source codes include multiple classes, so for the sake of your time, I will not post it, but will give you context. Please forgive if I can't explain well. I have been working on this a lot and my explanation makes sense to me but may not make sense to others.

I have a task to determine what category user input belongs into. For example, if a user inputs: I love dogs and cats. The program will output that the top 2 categories: dogs, cats

If the user only inputs: "I love dogs", the program will output the top 2 categories as "dogs, no other category found"

"no category" is the default response if there is only one category found or none at all.

I have created arrays lists for the following categories: dogs, cats, birds. These arraylists contain keywords that will trigger the program to recognize what category the user input will be in.

I basically need to get the highest likelihood and second highest likelihood (if applicable) and 'link' them to a string that will output what the category is.

This is my code, which attempts to take the top 2 highest likelihoods and get them to output on the console. my issue is getting the categories to link to their respective string to ensure the categories with highest likelihood are outputted.

    //Create prioritization
    int topDouble = 0;
    String topString = "no category"; //default response
    int secondDouble = 0;
    String secondString = "no category"; // default response

    ArrayList<Double> likelyDouble = new ArrayList<Double>();

    ArrayList<String> likelyString = new ArrayList<String>();
    likelyString.add("you talked about cats"); 
                  //to parallel likelyDouble cats category
    likelyString.add("you talked about dogs");
                  //to parallel likelyDouble dogs category
    likelyString.add("you talked about birds");
                  //to parallel likelyDouble cats category

    int count = 0;
    for (double d : likelyDouble){
        if((d>0) && (d > topDouble)){
            topDouble = (int) d;
            topString = likelyString.get(count);
        else if((d>0) && (d > secondDouble)){
            secondDouble = (int) d;
            secondString = likelyString.get(count);

    System.out.print(topString + "\n");

The output I get defaults to:

User input: I like dogs and cats.


no category

FYI The program determines what the likelihood that the user is talking about a certain category based on position in the sentence and number of times that category is referenced. The likelihood is a value that is calculated. so if the category is not mentioned at all, the likelihood is 0.

Thanks for all of your help!

share|improve this question
count is never incremented, so you will always get the first element in likelyString which should be "you talked about cats" according to your program but you output merely says "Dogs" –  Hunter McMillen Mar 2 '12 at 21:09
Why only two? Really, you should be returning a list of the categories found, which could be of any size. You could certainly stop looking after two elements, but you may find this limiting in the future. Oh... and you're going to want to basically create a thesaurus - I mean, what happens if I put in just 'dog'? So, look at doing things with multiple hashmaps, at minimum. –  Clockwork-Muse Mar 2 '12 at 21:09
add comment

2 Answers

I don't clearly understand what you are after, but I suspect it has something to do with your cast:

topDouble = (int) d;

You always set topDouble to 0 - assuming likelyhood is in the range [0,1].
Same goes to secondDouble.

Probably you wanted to declare topDouble and secondDouble as double, and remove the cast to an int - to get a double of the max/second value.

In addition - I cannot see you increase count, so you always get() the first element in the ArrayList.

Just a design thaught for a better approach [in my opinion]:
Create a new class: LikelyhoodStringDouble with 2 fields, one is a String and the other is a double. Make it implement Comparable [based on the double's value.

All you will have to do now is use Collections.sort() to sort the list, and get the top k elements you want [in your case k=2]

share|improve this answer
add comment

If I get you right, you can give a try to use a Map to store the likelyhood of your categories for every input any user can enter.

Sample given:

List<String> categories = new ArrayList<String>();
Map<String, Double> counterMap = new HashMap<String, Double>
for(String s : categories) {
    counterMap.put(s, 0);
List<String> inputString = new ArrayList<String>();
inputString.add("you talked about cats");
inputString.add("you talked about dogs");
inputString.add("you talked about birds");
for(String s : inputString) {
    for(String s2 : categories) {
        //get the likelyhood of the category in the sentence
        Double d = getLikelyhood(s2, s);
        //add the likelyhood in your map
        map.put(s2, map.get(s2) + d);

//after setting the likelyhood of the categories with the user input
//you just need to get the 2 major values in the map
//I'll let you a small algorithm for this
int x = 0;
String[] arrS = new String[m.size()];
for(Object o : m.keySet().toArray()) {
    arrS[x++] = (String)o;
x = 0;
Double[] arrI = new Double[m.size()];
for(Object o : m.values().toArray()) {
    arrI[x++] = (Double)o;
int max1, max2, posMax1, posMax2;
max1 = arrI[0];
max2 = arrI[0];
posMax1 = 0;
posMax2 = 0;
for(int i=1; i < arrI.length; i++) {
    if (arrI[i] >= max1) {
        max2 = max1;
        max1 = arrI[i];
        posMax2 = posMax1;
        posMax1 = i;
    } else if (arrI[i] > max2) {
        max2 = arrI[i];
        posMax2 = i;
System.out.println("Max category: " + arrS[posMax1]);
System.out.println("Second Max category: " + arrS[posMax2]);

Hope this helps you.

share|improve this answer
we haven't gotten to HashMap yet, so I don't feel comfortable using it. But thank you! –  user1245957 Mar 3 '12 at 4:37
add comment

Your Answer


