Rivers31334
Rivers31334

Reputation: 654

Printing information from arrays, without using duplicate values

I am writing a program that takes in Olympic medals data, and prints out various information. This particular part is proving a bit difficult in terms of logic and structure. I am trying to take a String array and an int array (which were both created in the main method), pass them to a new method, and print out information regarding them.

My arrays are as follows (please note that String array is in alphabetical order):

        String[] country = {"Afghanistan", "Afghanistan", "Canada", "China", "Italy", "Mexico"};
        int[] totalMedals = {1, 2, 1, 1, 3, 2};

I would like to print out to be as follows:

Afghanistan, 3 medal(s)
Canada, 1 medal(s)
China, 1 medal(s)
Italy, 3 medal(s)
Mexico, 2 medal(s)

I can easily write the program that lists out in this format, but countries that appear more than once (in this sample example...Afghanistan) is listed as many times as it comes up in the array. As written, my output is:

Afghanistan, 1 medal(s)
Afghanistan, 2 medal(s)
Canada, 1 medal(s)
China, 1 medal(s)
Italy, 3 medal(s)
Mexico, 2 medal(s)

Afghanistan is listed twice (to give a big of context, this is a smaller part of the program. The program actually houses athletes names as well, but that is taken care of in different methods).

Can anyone provide me a bit of help regarding the best way to print out my desired output?

import java.util.*;
import java.io.*;

public class Project {

public static void main(String[] args) {
    String[] country = {"Afghanistan", "Afghanistan", "Canada", "China", "Italy", "Mexico"};
    int[] totalMedals = {1, 2, 1, 1, 3, 2};

    listCountryMedals(country, totalMedals);

}

    //List the grand total of medals for each country...display name only once
public static void listCountryMedals(String[] country, int[] totalMedals) {

    for (int i = 0; i < country.length; i++) {
        System.out.println(country[i] + ", " + totalMedals[i] + " medal(s)");            
    }
}

Upvotes: 0

Views: 302

Answers (6)

sendon1982
sendon1982

Reputation: 11234

You can use map to store these information, country as key and medal count as value.

public static void listCountryMedals(String[] country, int[] totalMedals) 
{
    Map<String, Integer> countryMedalMap = new LinkedHashMap<String, Integer>();
    for (int i = 0; i < country.length; i++) 
    {
        String countryName = country[i];
        /**
         * If the country is already in the map, get the number of medal and add it up with value 
         * from totalMedals array for that country. Then put it back to map with the new medal count.
         */
        if(countryMedalMap.containsKey(countryName))
        {
            int medalCount = countryMedalMap.get(countryName) + totalMedals[i];
            countryMedalMap.put(countryName, medalCount);
        }
        /**
         * If the country is not in the map, put it into map with its medal count.
         */
        else
        {
            countryMedalMap.put(countryName, totalMedals[i]);
        }
    }

    printMap(countryMedalMap);
}

/**
 * Print the map
 * 
 * @param map
 */
public static void printMap(Map<String, Integer> map)
{
    for (String countryName : map.keySet())
    {
        System.out.println(String.format("%s, %s medal(s)", countryName, map.get(countryName)));
    }
}

Upvotes: 0

newuser
newuser

Reputation: 8466

Try this,

public static void listCountryMedals(String[] country, int[] totalMedals)
    {
        Map<String, Integer> countryMap = new HashMap<String, Integer>();

        for (int i = 0; i < country.length; i++)
        {
            Integer medals = countryMap.get(country[i]);
            Integer sum = (medals == null) ? totalMedals[i] : (totalMedals[i] + medals);
            countryMap.put(country[i], sum);
        }

        for (Map.Entry<String, Integer> countryMedals : countryMap.entrySet())
        {
            System.out.println(countryMedals.getKey() + ", " + countryMedals.getValue() + " medal(s)");
        }
    }

Upvotes: 1

Vallabh Patade
Vallabh Patade

Reputation: 5110

Change your method as follows.

public static void listCountryMedals(String[] country, int[] totalMedals) {

     //Map to hold the conuntry anme and medal count pair
     Map<String,Integer> countryNameToMedalCountMap= new HashMap<String,Integer>();

      for (int i = 0; i < country.length; i++) {           
         if(countryNameToMedalCountMap.get(country[i]) == null) {
             countryNameToMedalCountMap.put(country[i],totalMedals[i]);
         } else {
             int count = map.get(country[i]);
             countryNameToMedalCountMap.put(country[i],count+totalMedals[i];
        }
     }

      //Print the map
      for(String counrty : countryNameToMedalCountMap.keySet()) {
          System.out.println(country+" "+ countryNameToMedalCountMap.get(country)+" medal(s).");
      }
}

Note : With this approach, Country names will be case sensitive. You have to device some mechanism if you want case insensitive. Like converting the map keys always to the lower case and doing same while looking up

Upvotes: 0

Florent Bayle
Florent Bayle

Reputation: 11890

I would use a LinkedHashMap to sum the medals by country:

//List the grand total of medals for each country...display name only once
public static void listCountryMedals(String[] country, int[] totalMedals) {
    final Map<String, Integer> map = new LinkedHashMap<String, Integer>();


    for (int i = 0; i < country.length; i++) {
        if (!map.containsKey(country[i]))
            map.put(country[i], 0);
        map.put(country[i], map.get(country[i]) + totalMedals[i]); 
    }

    for (final Entry<String, Integer> entry : map.entrySet()) {
        System.out.println(entry.getKey() + ", " + entry.getValue() + " medal(s)");           
    }
}

Contrary to the classical HashMap, the LinkedHashMap will preserve the key order when iterating. It seems that your countries are currently sorted, so you may want to keep them in this order when you print them.

Upvotes: 0

Thresh
Thresh

Reputation: 470

Assuming you only want to use arrays and loops you can do the following:

public static void listCountryMedals(String[] country, int[] totalMedals) {
  boolean[]seen = new boolean[country.length];
  for (int i = 0; i < country.length - 1; i++) {
      int medals = totalMedals[i];
      if (!seen[i]) {
          for(int j = i + 1; j < country.length; j++) {
             if (country[i].equals(country[j])) {
                 medals += totalMedals[j];
                 seen[j] = true; //I already took this country
             }
          }
          System.out.println(country[i] + ", " + medals + " medal(s)");
      }
      seen[i] = true;
  }
}

Upvotes: 1

Rogue
Rogue

Reputation: 11483

You should take an object-orientated approach:

public class Country {

    private String name;
    private int medals;

    //getters/setters/constructors

}

Then it becomes easy:

List<Country> countries = new ArrayList<>();

//when you want to reference/print those:
for (Country c : countries) {
    System.out.println(String.format("%s, %d medals(s)", c.getName(), c.getMedals()));
}

Upvotes: 0

Related Questions