tags:

views:

200

answers:

4

Hi, I was wondering how I could search an ArrayList of Strings to find the most commonly occurring 'destination' in an 'Itinerary' object I've created (which contains a list of different destinations.)

So far I have:

public static String commonName(ArrayList<Itinerary> itinerary){

    int count = 0;
    int total = 0;

    ArrayList<String> names = new ArrayList<String>();
    Iterator<String>itr2 = names.iterator();

    while(itr.hasNext()){ 

        Itinerary temp = itr.next();  

        if(temp.iterator().hasNext()){ //if its has destinations

                // Destination object in itinerary object 
                Destination temp2 = temp.iterator().next(); 
                String name = temp2.getDestination().toLowerCase().replace(" ", "");

                if(names.contains(name)){
                    count = count + 1;
                    //do something with counting the occurence of string name here
                }

I'm having problems making an algorithm to search the array for the most commonly occurring string, or strings if there is a tie; and then displaying the number of the 'Itinerary object' (the parameter value) the string is found in. Any help would be great, thank you!!

A: 

Count the occurrences first and then sort by counters in a separate pass

mfeingold
why sort if you are just looking for a maximum?
Kevin Day
+5  A: 

I would make a HashMap<String,Integer>. Then I would go through each itinerary, and if the destination wans't in the Map I would create an entry with put(destination, 1), otherwise I would increment the count that was there with put(destination, get(destination)+1). Afterwards I'd go through the Map entries and look for the one with the highest count.

Paul Tomblin
It's probably not the most efficient (based on CPU cycles), but it's definitely the first to mind as the least amount of code that gets the job done. +1.
Dean J
you could skip the last step (running through the map entries and look for the highest count) if you kept a 'max' value as you incrmented the get(destingation)+1 step. If the new value was larger than any seen yet then store off a pointer to that entry. (I think this is the fastest solution as it is O(n). Certainly faster than sorting which is nLogn )
Greg Smith
My solution is O(N) - you're traversing the list of itineraries once, then you're traversing the list of destinations found once.
Paul Tomblin
A: 

If you don't mind using an external jar, you could use HashBag from apache commons to do this easily.

public static String commonName(ArrayList<Itinerary> itinerary){

int count = 0;
int total = 0;
Bag names = new HashBag();

while(itr.hasNext()){ //while array of Itinerary object has next
    Itinerary temp = itr.next();  //temp = 1st itineray object
    if(temp.iterator().hasNext()){ //if its has destinations
            Destination temp2 = temp.iterator().next(); //n Destination object in itinerary object 
            String name = temp2.getDestination().toLowerCase().replace(" ", "");
            names.add(name, 1);
    }
}

And then later you can call names.getCount("destination1") to get the number of occurrences of destination1

See http://commons.apache.org/collections/userguide.html#Bags

royalsampler
Thank you all for the extremely quick and helpful answers! I just started learning Java and although I haven't used HashBag before Ill be sure to look it up in the java API! Thank you again!
LeighA
A: 

Try the group feature of the lambdaj library. To solve your problem you could group the Itenarary objects on the destination property and then find the group with the biggest size as in the following example:

Group<Sale> group = selectMax(group(itineraries, 
    by(on(Itenarary.class).getDestination())).subgroups(), on(Group.class).getSize());
Mario Fusco