Страницы

Поиск по вопросам

вторник, 28 января 2020 г.

Нужен алгоритм сравнения кастомных объектов

#java #c_sharp #python #c #алгоритм


Понадобилось сделать сравнение. Есть 2 листа объектов одного типа (field1 и field2
в примере). У объекта есть 3 строковых параметра (имя, фамилия, отчество). В первом
объекте есть записи о 3-х людях со всеми заполненными полями, т.е. он выглядит примерно так:


Имя        Фамилия      Отчество
Юрий       Карамазин     Александрович
Виктор      Сушко         Григорьевич
Саша        Князев        Альбертович


И второй объект, в котором записи о тех же 3-х людях, но хранятся только имена:


Имя
Юрий
Виктор
Саша


Мне необходимо сравнивать только параметр объекта "имя". Пытаюсь сравнивать как-то так:

for (FieldOfTest x : field1) {
    for (FieldOfTest y : field2) {
        Assert.assertTrue(x.getName().equals(y.getName()),
                "First value: " + x.getName() + " , second value: " + y.getName());
    }
}


Второй for прокручивает полный список. Как мне сравнивать 1 объект из первого списка
с одним объектом второго списка?
    


Ответы

Ответ 1



Если сравнивать нужно только элементы, находящиеся на одинаковых индексах, то достаточно использовать один for, предварительно убедившись, что массивы равной длины: public static void main(String[] args) { List field1 = new ArrayList<>(); field1.add(new FieldOfTest("Юрий", "Карамазин Александрович")); field1.add(new FieldOfTest("Виктор", "Сушко Григорьевич")); field1.add(new FieldOfTest("Саша", "Князев Альбертович")); List field2 = new ArrayList<>(); field2.add(new FieldOfTest("Юрий", null)); field2.add(new FieldOfTest("Виктор", null)); field2.add(new FieldOfTest("Саша", null)); System.out.println("Data is correct: " + isCorrectData(field1, field2)); } private static boolean isCorrectData(List field1, List field2) { if (field1.size() != field2.size()) { return false; } boolean isCorrect = true; for (int i = 0; i < field1.size(); i++) { if (!field1.get(i).getName().equals(field2.get(i).getName())) { isCorrect = false; break; } } return isCorrect; } Реализация на Java.

Ответ 2



Ну как то так наверное: HashMap hashFields=new HashMap(); for(FieldOfTest x:field1) hashFields.put(x.getName(), x); //теперь находим в первом списке по именам со второго списка for(FieldOfTest y:field2) //y содержит только имена if(hashFields.get(y)!=null) //bingo! P.S. @VladD опередил. P.P.S. код для Java

Ответ 3



Вам в любом случае нужно искать по всему контейнеру. Но я бы перешёл к структуре данных с более эффективным поиском. Например, положил бы имена в HashSet или аналогичную структуру данных в вашем языке, с поиском O(1).

Ответ 4



необходимо сравнивать только поле "имя" первого объекта в листе1 с полем "имя" первого объекта в листе2; поле "имя" второго объекта в листе1 с полем "имя" второго объекта в листе2, и т.д. до конца листа В Питоне: all(a.name == b.name for a, b in zip(list1, list2)) Полный пример: #!/usr/bin/env python from collections import namedtuple Person = namedtuple('Person', 'name lastname patronymic') list1 = [Person(*s.split()) for s in """\ Юрий Карамазин Александрович Виктор Сушко Григорьевич Саша Князев Альбертович""".split('\n')] list2 = [Person(name, None, None) for name in """ Юрий Виктор Саша""".split()] if all(a.name == b.name for a, b in zip(list1, list2)): print('equal')

Ответ 5



Вариант для java. Сложность O(n) private static class A { String name; @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof A)) return false; A a = (A) o; return name.equals(a.name); } @Override public int hashCode() { return name.hashCode(); } } private static class B extends A { String surname; String middleName; } private static boolean isEquals(List firstList, List secondList) { if (firstList.size() != secondList.size()) return false; Set buffer = new HashSet<>(secondList); for (A obj : firstList) if (!buffer.contains(obj)) return false; return true; }

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

Отправить комментарий