Олимпиада по java-кодированию

#java #arrays #class #object #instance

#java #массивы #класс #объект #экземпляр

Вопрос:

Я пишу программу, в которой мне нужно подсчитать золотые медали для каждой страны. Входные данные будут поступать из файла, и я должен обработать файл. Первая строка — это код страны, вторая строка — тип события, а третья — событие. Входные данные выглядят следующим образом:

 CHN 
Diving 
Women's 10m Platform 
CAN 
Rowing 
Men's Eight 
CHN
Rowing
Women's Quadruple Sculls
  

Ожидаемый результат должен быть таким:

 Count of gold medallists by country:
CHN - 2
CAN - 1

Count of gold medallists by event type:
Diving - 1
Rowing - 2
  

Итак, я создал класс золотых медалей, в котором он создаст новый объект экземпляра для каждой страны в соответствии с типом события. Мой код здесь:

 class GoldMedals {
  private String country;
  private String eventType;
  private String event;
  private int medalCount;

 public GoldMedals(String name, String type, String event) {
   this.country = name;
   this.eventType = type;
   this.event = event;
   medalCount = 1;
}

public boolean matchDetails(String countryName, String type){
return (country.equals(countryName) amp;amp; eventType.equals(type));
}
  

Мой основной метод здесь:

 try {
  input = new BufferedReader(new FileReader ("textfile.txt"));
  country = input.readLine();
  while(country!=null) {
    eventType = input.readLine();
    event = input.readLine();
    match = findMatch(winners, size, country, eventType);
    if(match == null) {
    winners[size] = new GoldMedals(country, eventType, event);
    size  ;
      //match.addMedal();
    } //else {

        //match.addMedal();          
    //}
    //match.addMedal();
    country = input.readLine();
  }

  input.close();
} catch (IOException ioe) {
  System.out.println(ioe.getMessage());
  

Я также добавил статический метод, который гарантирует, что мы не создаем объекты, которые уже существуют. (избыточные объекты)

 public static GoldMedals findMatch(GoldMedals[] winners, int size, String country, String type) {
  GoldMedals result = null;
  int pos;

  pos = 0;
  while (pos < size amp;amp; result == null) {
    if (winners[pos].matchDetails(country, type)) {
     result = winners[pos];
  } else {
     pos  ;
  }
 }
  return resu<
}
  

Что я хочу знать, так это как я могу получить требуемый результат. Потому что прямо сейчас я получаю этот вывод:

 ITA- 1- Fencing- Women's Individual Foil
POL- 1- Rowing- Men's Quadruple Sculls
KEN- 1- Athletics- Men's Marathon 
CHN- 1- Diving- Men's 3m Springboard
TUN- 1- Swimming- Men's 1500m Freestyle
CHN- 1- Canoe/Kayak - Flatwater- Canoe Double (C2) 500m Men
CHN- 1- Diving- Men's Synchronised 3m Springboard 
USA- 1- Gymnastics Artistic- Women's Individual All-Around
RUS- 1- Synchronized Swimming- Duet
  

это то, что я запрограммировал. Мне нужна помощь в том, как я могу получить общее количество золотых медалей для каждой страны, а также золотые медали в зависимости от типа события. Короче говоря, как я могу получить желаемый результат, который указан выше.
Я могу подробнее объяснить, если вам нужна помощь с моим вопросом. Подсказки будут оценены по достоинству.

Комментарии:

1. Самый простой способ — иметь 2 карты. Первый, у которого есть строка типа страны в качестве ключа и целое число для подсчета медалей в качестве значения. Вторая карта должна содержать строку события для ключа и целочисленный счетчик для значения. Чем зацикливать файл, вы будете суммировать медали по стране и событию. В конце цикла на 2 картах будут напечатаны ваши выходные данные.

2. Спасибо вам за ответ. Проблема в том, что я еще не слишком углубился в карты (что является моей следующей целью). Мне придется изучить карты, чтобы решить эту проблему. Что я хочу знать, так это то, как я могу это сделать, если я не использую карты. @Мариоалександросантини

3. Без карт вы должны создать класс MedalCounter , который содержит 2 атрибута, строку для имени и счетчик, чем создать 2 массива MedalCounter , один для стран и один для событий.

4. итак, я переберу массив победителей типа GoldMedals, а затем сделаю что-то вроде этого: countryMedalCounter[start] = new MedalCounter(winners[i].country, 1) я все еще не понимаю, нравится ли мне это, не потребуется ли странам с разными событиями дважды. Это сведет на нет всю цель, если только я не понял вашу идею неправильно. @Мариоалександросантини

Ответ №1:

Удалите это medalCount поле. Ваш класс должен просто представлять входящие данные.

Затем вы хотите создать два Map<String, Long> объекта, где ключ — это код страны или тип события, а значение — это количество для ключа.

С потоками Java 8 это довольно просто:

 List<GoldMedals> allMedals = loadMedalsFromFile();

Map<String, Long> byCountry = allMedals.stream()
        .collect(Collectors.groupingBy(GoldMedals::getCountry,
                                       Collectors.counting()));

Map<String, Long> byEventType = allMedals.stream()
        .collect(Collectors.groupingBy(GoldMedals::getEventType,
                                       Collectors.counting()));
  

Комментарии:

1. Спасибо за потраченное время. Как я ответил другому парню, я не очень много знаю о картах. Мне нужно сделать это без maps. (я буду изучать карты для своего следующего проекта) Есть ли другой способ, которым я могу это решить?

2. Не могли бы вы мне помочь. мне действительно нужна помощь. я пытался самостоятельно последние 2 часа.

3. Я не знаю, чему вы научились, а чему нет. Они не дали бы вам задание, которое невозможно выполнить с помощью того, что вы узнали, поэтому вы должны быть в состоянии найти решение с помощью того, что вы знаете. Перечитайте свой материал еще раз. Может быть, это напомнит вам о чем-то, о чем вы не думаете.

4. все это время я кодировал самостоятельно, но получаю исключение нулевого указателя. for (int i = 0; i < size; i ) { String name = winners[i].getCountryName(); if(!name.equals(countryArray[count].getName())) countryArray[count] = new MedalCounter(name, 1); else countryArray[count].updateCount();

5. я создал новый класс под названием MedalCounter и создал два экземпляра массива этого класса. я перебираю экземпляры GoldMedal и создаю новые экземпляры MedalCounter, если его там нет, в противном случае я просто увеличиваю счетчик. MedalCounter имеет две переменные экземпляра, называемые name и counter.

Ответ №2:

В случае, если вы не можете использовать Map. Вы можете попробовать следующий код:

—GoldMedals

 public class GoldMedals {
    private String country;
    private String eventType;
    private String event;
    private int medalCount;

    public GoldMedals(String name, String type, String event) {
        this.country = name;
        this.eventType = type;
        this.event = event;
        medalCount = 1;
    }

    /**
     * @return the country
     */
    public String getCountry() {
        return country;
    }

    /**
     * @param country the country to set
     */
    public void setCountry(String country) {
        this.country = country;
    }

    /**
     * @return the eventType
     */
    public String getEventType() {
        return eventType;
    }

    /**
     * @param eventType the eventType to set
     */
    public void setEventType(String eventType) {
        this.eventType = eventType;
    }

    /**
     * @return the event
     */
    public String getEvent() {
        return event;
    }

    /**
     * @param event the event to set
     */
    public void setEvent(String event) {
        this.event = event;
    }

    /**
     * @return the medalCount
     */
    public int getMedalCount() {
        return medalCount;
    }

    /**
     * @param medalCount the medalCount to set
     */
    public void setMedalCount(int medalCount) {
        this.medalCount = medalCount;
    }

    public boolean matchDetails(String countryName, String type){
        return (country.equals(countryName) amp;amp; eventType.equals(type));
    }

}
  

—Критерий GoldByCriteria

 public class GoldByCriteria {

    private String country;
    private int goldMedals;

    public GoldByCriteria() {}

    public GoldByCriteria(String country, int goldMedals) {
        this.country = country;
        this.goldMedals = goldMedals;
    }

    /**
     * @return the country
     */
    public String getCountry() {
        return country;
    }
    /**
     * @param country the country to set
     */
    public void setCountry(String country) {
        this.country = country;
    }
    /**
     * @return the goldMedals
     */
    public int getGoldMedals() {
        return goldMedals;
    }
    /**
     * @param goldMedals the goldMedals to set
     */
    public void setGoldMedals(int goldMedals) {
        this.goldMedals = goldMedals;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result   ((country == null) ? 0 : country.hashCode());
        return resu<
    }

    /* (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        GoldByCriteria other = (GoldByCriteria) obj;
        if (country == null) {
            if (other.country != null)
                return false;
        } else if (!country.equals(other.country))
            return false;
        return true;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return country   " - "   goldMedals;
    }

}
  

—Использование

 import java.util.ArrayList;
import java.util.List;

public class Util {

    /**
     * base on the criteria to get the number of gold
     * 
     * */
    public static final GoldByCriteria getGoldByCriteria(List<GoldByCriteria> list, String criteria) {
        for (GoldByCriteria goldByCriteria : list) {
            if(goldByCriteria.getCountry().equals(criteria)) {
                return goldByCriteria;
            }
        }
        return null;
    }

    /**
     * group by Country
     * */
    public static final List<GoldByCriteria> getGoldMedalsByCountry(List<GoldMedals> goldMedals) {
        List<GoldByCriteria> result = new ArrayList<GoldByCriteria>();
        for (GoldMedals e : goldMedals) {
            GoldByCriteria goldByCountry = Util.getGoldByCriteria(result, e.getCountry());
            if( goldByCountry != null) {
                goldByCountry.setGoldMedals(goldByCountry.getGoldMedals()   1);
            } else {
                GoldByCriteria oneGold = new GoldByCriteria();
                oneGold.setCountry(e.getCountry());
                oneGold.setGoldMedals(e.getMedalCount());
                result.add(oneGold);
            }
        }
        return resu<
    }


    /**
     * group by type
     * */
    public static final List<GoldByCriteria> getGoldMedalsByType(List<GoldMedals> goldMedals) {
        List<GoldByCriteria> result = new ArrayList<GoldByCriteria>();
        for (GoldMedals e : goldMedals) {
            GoldByCriteria goldByCountry = Util.getGoldByCriteria(result, e.getEventType());
            if( goldByCountry != null) {
                goldByCountry.setGoldMedals(goldByCountry.getGoldMedals()   1);
            } else {
                GoldByCriteria oneGold = new GoldByCriteria();
                oneGold.setCountry(e.getEventType());
                oneGold.setGoldMedals(e.getMedalCount());
                result.add(oneGold);
            }
        }
        return resu<
    }

}
  

—Основной

 import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<GoldMedals> goldMedals = new ArrayList<GoldMedals>();

        GoldMedals one = new GoldMedals("ITA", "Fencing", "Women's Individual Foil");
        GoldMedals two = new GoldMedals("POL", "Rowing", "Men's Quadruple Sculls");
        GoldMedals three = new GoldMedals("CHN", "Diving", "Men's 3m Springboard");
        GoldMedals four = new GoldMedals("CHN", "Diving", "Men's Synchronised 3m Springboard");

        goldMedals.add(one);
        goldMedals.add(three);
        goldMedals.add(two);
        goldMedals.add(four);

        //by country 
        List<GoldByCriteria> byCountries = Util.getGoldMedalsByCountry(goldMedals);

        for (GoldByCriteria goldByCountry : byCountries) {
            System.out.println(goldByCountry);
        }

        System.out.println("------------");
        //by Type

        List<GoldByCriteria> byType = Util.getGoldMedalsByType(goldMedals);

        for (GoldByCriteria goldByType : byType) {
            System.out.println(goldByType);
        }
    }
}
  

Вы должны изменить свойство «country» в GoldByCriteria на лучшее имя, например «criteria». Для быстрого кода я протестировал его со страной.

Надеюсь, это поможет.