Форум программистов, компьютерный форум, киберфорум
Java для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.93/15: Рейтинг темы: голосов - 15, средняя оценка - 4.93
0 / 0 / 0
Регистрация: 22.11.2019
Сообщений: 6

Применение интерфейса Multiset классом HashMultiset

06.12.2019, 18:15. Показов 3075. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте

Пытаюсь самообучаться через интернет(hyperskill.org)

Застопорился на задании:
Дан интерфейс Multiset, примените все его методы при помощи класса HashMultiset.
В классе одно единственное поле Map<E, Integer>.
Модификации интерфейса/класса, условиями задачи не возбранялись.


Собсно, интерфейс:
Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
interface Multiset<E> {
 
    /**
     * Add an element to the multiset.
     * It increases the multiplicity of the element by 1.
     */
    void add(E elem);
 
    /**
     * Remove an element from the multiset.
     * It decreases the multiplicity of the element by 1.
     */
    void remove(E elem);
 
    /**
     * Union this multiset with another one. The result is the modified multiset (this).
     * It will contain all elements that are present in at least one of the initial multisets.
     * The multiplicity of each element is equal to the maximum multiplicity of
     * the corresponding elements in both multisets.
     */
    void union(Multiset<E> other);
 
    /**
     * Intersect this multiset with another one. The result is the modified multiset (this).
     * It will contain all elements that are present in the both multisets.
     * The multiplicity of each element is equal to the minimum multiplicity of
     * the corresponding elements in the intersecting multisets.
     */
    void intersect(Multiset<E> other);
 
    /**
     * Returns multiplicity of the given element.
     * If the set doesn't contain it, the multiplicity is 0
     */
    int getMultiplicity(E elem);
 
    /**
     * Check the multiset contains an element,
     * i.e. the multiplicity > 0
     */
    boolean contains(E elem);
 
    /**
     * The number of unique elements
     */
    int numberOfUniqueElements();
 
    /**
     * The size of the multiset, including repeated elements
     */
    int size();
 
    /**
     * The set of unique elements (without repeating)
     */
    Set<E> toSet();
 
    /**
     * The list of all elements (with repetitions)
     */
    public List<E> toList();                  //добавлен от безысходности (дабы упростить применение union)
 
    /**
     * Secret method to get access to the map
     */
    public Map<E, Integer> giveMeMyMap();      //добавлен от безысходности (дабы упростить применение intersect)
}


Собсно, попытка его реализовать:
Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
class HashMultiset<E> implements Multiset<E> {
 
    private Map<E, Integer> map = new HashMap<>();
 
    @Override
    public List<E> toList() {
        ArrayList<E> arrayList = new ArrayList<>();
        for (Map.Entry<E, Integer> pair : map.entrySet()) {
            for (int i = 0; i < pair.getValue(); i++) {
                arrayList.add(pair.getKey());
            }
        }
        return arrayList;
    }
 
    @Override
    public Map<E, Integer> giveMeMyMap() {
        return map;
    }
 
    @Override
    public void add(E elem) {
        int multiplicity = 1;
 
        if (map.containsKey(elem)) {
            map.put(elem, getMultiplicity(elem) + 1);
            return;
        }
        map.put(elem, multiplicity);
    }
 
    @Override
    public void remove(E elem) {
        if (map.containsKey(elem)) {
            map.put(elem, getMultiplicity(elem) - 1);
            if (getMultiplicity(elem) == 0) {
                map.remove(elem, 0);
            }
        }
    }
 
    @Override
    public void union(Multiset<E> other) {
        for (E key : other.toList()) {
            add(key);
        }
    }
 
    @Override
    public void intersect(Multiset<E> other) {
        //Тут что-то сложно совсем
        for (Map.Entry<E, Integer> pair : map.entrySet()) {
            for (Map.Entry<E, Integer> pair2 : other.giveMeMyMap().entrySet()) {
                if (!pair.getKey().equals(pair2.getKey())) {
                    map.remove(pair.getKey());
                }
                else {
                    if (pair.getValue() > pair2.getValue()) {
                        pair.setValue(pair2.getValue());
                    }
                    break;
                }
            }
        }
    }
 
    @Override
    public int getMultiplicity(E elem) {
        return contains(elem) ? map.get(elem) : 0;
    }
 
    @Override
    public boolean contains(E elem) {
        return map.containsKey(elem);
    }
 
    @Override
    public int numberOfUniqueElements() {
        return map.size();
    }
 
    @Override
    public int size() {
        int size = 0;
        for (int i : map.values()) {
            size += i;
        }
        return size;
    }
 
    @Override
    public Set<E> toSet() {
        return map.keySet();
    }
}


В принципе все более-менее ясно:
В keys хранятся объекты, в values - их количество.
Однако есть одна проблема в дурацком intersect'e - он упорно отказывается работать.

На сколько я разобрал из описания:
Метод сравнивает две карты (мою, и ту, что спрятана в объекте "other") и оставляет только те пары ключ-значение, которые есть в обоих картах.
При этом значение берётся из той пары, в которой оно "меньшее".

Я тупой еще не шибко разбираюсь в коллекциях, но нагуглил метод retainAll(Collection<?> c),
однако танцы с ним ни к чему хорошему не привели. Так же попробовал перебор через Map.Entry и снова ничего не вышло.

Подскажите пожалуйста, в каком направлении копать?
Можно даже без кода, объяснение на пальцах тоже подойдет.
Спасибо.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
06.12.2019, 18:15
Ответы с готовыми решениями:

Наследование интерфейса INotifyPropertyChanged классом с 2 свойствами
Добрый вечер. Подскажите ,пожалуйста ,как при наследовании интерфейса INotifyPropertyChanged классом у которого есть 2 и более свойства...

Применение интерфейса
есть код public class Product { public int ProductID { get; set; } public string Name { get; set; } public string Description {...

Наследование интерфейса базовым классом и его наследниками
есть общий абстрактный класс и три наследника(наследуют по одному свойству, каждый наследник имеет еще одно индивидуальное свойство)....

8
Эксперт Java
3639 / 2971 / 918
Регистрация: 05.07.2013
Сообщений: 14,220
06.12.2019, 18:35
может надо взять готовый HashMultiset и потыкать методы оттуда, а не писать свою поделку?
1
485 / 411 / 126
Регистрация: 23.05.2016
Сообщений: 1,653
06.12.2019, 20:02
1. Не надо добавлять методы в интерфейс. Добавляйте вспомогательные методы прямо в класс. Имплементация интерфейса означает что нужно реализовать все методы интерфейса, ограничение на другие методы не накладывается.

2. Воспользуйтесь Яндекс-переводчиком и переведите описание метода union()
1
502 / 348 / 134
Регистрация: 14.06.2016
Сообщений: 669
06.12.2019, 21:47
Java
1
2
3
4
5
    public void intersect(Multiset<E> other) {
        for (E e : new HashSet<>(map.keySet()))
            if (other.map.containsKey(e)) map.put(e, Math.min(map.get(e), other.map.get(e)));
            else map.remove(e);
    }
1
0 / 0 / 0
Регистрация: 22.11.2019
Сообщений: 6
06.12.2019, 23:04  [ТС]
Цитата Сообщение от xoraxax Посмотреть сообщение
может надо взять готовый HashMultiset
В этом направлении я даже не подумал как-то. Но ведь тогда теряется изюминка процесса обучения:
скопирую кусок кода, вставлю не думая, а в голове не отложится.
Хочется понять "что", "куда", "зачем", "почему".

Цитата Сообщение от Sindbad_M Посмотреть сообщение
Не надо добавлять методы в интерфейс. Добавляйте вспомогательные методы прямо в класс.
В том-то все и дело: я добавил методы именно в интерфейс от безысходности. Мозгов не хватило придумать, как вытащить из объекта "other" саму карту, чтоб с ней производить сравнения, другим способом. Тут у меня даже мыслей никаких в голове не нашлось.

Цитата Сообщение от Sindbad_M Посмотреть сообщение
переведите описание метода union()
А я думал, что с этим методом у меня как раз-таки не было проблем..
Там и без переводчика вроде ясно, что "если нашлись одинаковые ключи при сравнении - сложить их значения,
иначе добавить к результату пару ключ-значение из объекта, с которым производится сравнение".

Поправьте, если ошибся, это же логика "объединения" и "пересечения":


Например две мапы

| а 5 | | a 9 | | а 14 |
| с 3 | и | b 1 | должно дать результат | b 1 |
| е 8 | | k 6 | при вызове union() | c 3 |
| e 8 |
| k 6 |

А с intersection надо наоборот, оставить только совпавшие ключи
с наименьшим значением из двух пар, остальное уничтожить т.е. :

| а 5 | | a 9 |
| с 3 | и | b 1 | должно дать результат | а 5 |
| е 8 | | k 6 | при вызове intersection()

Добавлено через 28 минут
vcrop, но доступ к map из other так просто не получить, даже IDE ругается.
(по этому я и добавил в интерфейс метод giveMeMyMap())


P.S.
прошу прощения, съехал текст примеров.
Две мапы:
| а 5 | | с 3 | | е 8 |
и
| a 9 | | b 1 | | k 6 |

должно дать результат при вызове union()
| а 14 | | b 1 | | c 3 | | e 8 | | k 6 |

А с intersection надо наоборот, оставить только совпавшие ключи
с наименьшим значением из двух пар, остальное уничтожить т.е. :
| а 5 | | с 3 | | е 8 |
и
| a 9 | | b 1 | | k 6 |

должно дать результат при вызове intersection()
| а 5 |
0
485 / 411 / 126
Регистрация: 23.05.2016
Сообщений: 1,653
06.12.2019, 23:54
Да, с описанием метода это я затупил, вместо intersection прочитал описание к union.

Как я понимаю, доступ ко всем элементам мультисета-параметра можно получить так:

Java
1
2
3
4
5
6
Set<E> set = other.toSet();
for (E e : set) {
    int value = other.getMultiplicity(e);
    //код, который обрабатывает пару (e,value)
    //т.е. ищет в map по ключу e и при необходимости что-то добавляет в итоговый map
}
через это обрабатываем и объединение и пересечение
0
502 / 348 / 134
Регистрация: 14.06.2016
Сообщений: 669
06.12.2019, 23:55
Лучший ответ Сообщение было отмечено Albert_Dzh как решение

Решение

Прости, невнимательно посмотрел
Java
1
2
3
4
5
6
    @Override
    public void intersect(Multiset<E> other) {
        for (E e : new HashSet<>(toSet()))
            if (other.getMultiplicity(e) != 0) map.put(e, Math.min(getMultiplicity(e), other.getMultiplicity(e)));
            else remove(e);
    }
0
Эксперт Java
3639 / 2971 / 918
Регистрация: 05.07.2013
Сообщений: 14,220
07.12.2019, 00:29
Albert_Dzh, ну вот не знаешь ты как написать intersect, открой нормальный код, посмотри как там сделает, разберись, сделай так же у себя. Это быстрее и проще, чем сидеть тут ждать пока тебе кто-то что-то объяснит
0
0 / 0 / 0
Регистрация: 22.11.2019
Сообщений: 6
07.12.2019, 19:41  [ТС]
vcrop, большое Вам спасибо за рабочий пример.

Sindbad_M, а Вам отдельное спасибо, за то, что уделили время и разжевали. Все гениальное, как обычно, просто, а мне не хватило фантазии.

xoraxax, Вам тоже спасибо за участие. Вот только я не сидел сложа руки, а искал способ разобраться самостоятельно, и довольно-таки длительное время, прежде чем решился задать вопрос тут.
В силу не важно каких обстоятельств, у меня справиться самому не вышло.
Не вижу в этом ничего постыдного, тем более, что я нахожусь в процессе обучения.
И уж тем более ничего постыдного не вижу в том, чтобы спросить у людей, которые разбираются в этом гораздо лучше меня.
Обещаю в будущем больше стараться решить задание самостоятельно.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
07.12.2019, 19:41
Помогаю со студенческими работами здесь

Реализация интерфейса классом, где объявлен этот интерфейс
Почему такой код не работает? Есть ли способ исправления без переноса интерфейса вне класса Listenable. class Listenable implements...

Можно ли ограничить вызов методов интерфейса определённым классом?
Привет. Есть интерфейс &quot;внутреннего&quot; сервиса. Под внутренним сервисом я понимаю интерфейс объекта с методами Start, Stop и свойство...

Применение графического интерфейса в Scilab
Что означает строчка:tet_in=uicontrol(frame,'style','text','string','$\tau=$','position',,'fontsize',18);в программе Scilab?

Выбор между абстрактным классом, интерфейсом и простым классом
Здравствуйте. Помогите определиться, что следует выбрать в следующей ситуации, а главное почему следует выбирать именно это. ...

Организовать связь между собственным классом и классом SpriteABC
Здравствуйте. Подскажите, пожалуйста, как можно было бы организовать связь(?) между собственным классом и классом SpriteABC? Или...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
Использование значений реквизитов справочника в документе, с определенными условиями и правами
Maks 07.04.2026
1. Контроль срока действия договора Алгоритм из решения ниже реализован на примере нетипового документа "ЗаявкаНаРаботу", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если. . .
Доступность команды формы по условию
Maks 07.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: сделать доступной кнопку (команда формы "ЗавершитьСписание") при. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru