Хорошо, позвольте мне объяснить концепцию очень простыми словами.
Во-первых, с более широкой точки зрения у нас есть коллекции, а hashmap является одной из данных в коллекциях.
To понять, почему мы должны переопределять оба метода equals и hashcode, если вам нужно сначала понять, что такое hashmap и что делает.
Хеш-карта - это структура данных, в которой хранятся пары значений ключа в массиве. Давайте скажем [], где каждый элемент в 'a' является парой значений ключа.
Также каждый индекс в указанном выше массиве может быть связанным списком, тем самым имея более одного значения по одному индексу.
Теперь почему используется хэшмап? Если нам нужно искать среди большого массива, то поиск по каждому из них, если они не будут эффективными, так что хэш-метод говорит нам, что позволяет предварительно обрабатывать массив с некоторой логикой и группировать элементы на основе этой логики, т. Е. Hashing
, например: у нас есть массив 1,2,3,4,5,6,7,8,9,10,11, и мы применяем хеш-функцию mod 10, поэтому 1,11 будут сгруппированы вместе. Поэтому, если бы нам пришлось искать 11 в предыдущем массиве, нам пришлось бы перебирать полный массив, но когда мы группируем его, мы ограничиваем объем итераций, тем самым улучшая скорость. Эта структура данных, используемая для хранения всей вышеприведенной информации, может рассматриваться как 2d-массив для простоты
. Теперь помимо вышеизложенного hashmap также говорит, что он не добавит в него никаких дубликатов. И это главная причина, по которой мы должны переопределить значения equals и hashcode
. Поэтому, когда в его объяснении объясняется внутренняя работа hashmap, нам нужно найти, какие методы имеет hashmap, и как это следует за приведенным выше правила, которые я объяснил выше
, поэтому в hashmap есть метод, называемый put (K, V), и в соответствии с hashmap он должен следовать приведенным выше правилам эффективного распределения массива и не добавлять никаких дубликатов
, так что put put is состоит в том, что он сначала сгенерирует хэш-код для данного ключа, чтобы решить, какой индекс должен иметь значение. Если в этом индексе ничего не присутствует, тогда добавляется новое значение, если что-то уже присутствует там, тогда новое значение должно быть добавлено после окончания связанного списка по этому индексу. но не помните, что дубликаты не должны добавляться в соответствии с желаемым поведением хэш-карты. поэтому давайте предположим, что у вас есть два объекта Integer aa = 11, bb = 11. как каждый объект, полученный из класса объекта, реализация по умолчанию для сравнения двух объектов заключается в том, что она сравнивает ссылку, а не значения внутри объекта. Таким образом, в приведенном выше случае оба семантически равных будут терпеть неудачу в тесте равенства и возможность того, что будут существовать два объекта, один и тот же хэш-код и одинаковые значения, что создает дубликаты. Если мы переопределим, мы могли бы избежать добавления дубликатов. Вы также можете обратиться к Подробности работы
import java.util.HashMap;
public class Employee {
String name;
String mobile;
public Employee(String name,String mobile) {
this.name=name;
this.mobile=mobile;
}
@Override
public int hashCode() {
System.out.println("calling hascode method of Employee");
String str=this.name;
Integer sum=0;
for(int i=0;i h=new HashMap<>();
//for (int i=0;i<5;i++){
h.put(emp, emp);
h.put(emp2, emp2);
//}
System.out.println("----------------");
System.out.println("size of hashmap: "+h.size());
}
}
Вычислить область пересечения, которая также является прямоугольником:
SI = Max(0, Min(XA2, XB2) - Max(XA1, XB1)) * Max(0, Min(YA2, YB2) - Max(YA1, YB1))
Оттуда вы вычислите область объединения:
SU = SA + SB - SI
И вы можете рассмотреть отношение
SI / SU
(100% в случае идеального перекрытия, до 0%).
Просто фиксируйте предыдущие ответы так, чтобы соотношение находилось между 0 и 1 (с использованием Python):
# (x1,y1) top-left coord, (x2,y2) bottom-right coord, (w,h) size
A = {'x1': 0, 'y1': 0, 'x2': 99, 'y2': 99, 'w': 100, 'h': 100}
B = {'x1': 0, 'y1': 0, 'x2': 49, 'y2': 49, 'w': 50, 'h': 50}
# overlap between A and B
SA = A['w']*A['h']
SB = B['w']*B['h']
SI = np.max([ 0, 1 + np.min([A['x2'],B['x2']]) - np.max([A['x1'],B['x1']]) ]) * np.max([ 0, 1 + np.min([A['y2'],B['y2']]) - np.max([A['y1'],B['y1']]) ])
SU = SA + SB - SI
overlap_AB = float(SI) / float(SU)
print 'overlap between A and B: %f' % overlap_AB
# overlap between A and A
B = A
SB = B['w']*B['h']
SI = np.max([ 0, 1 + np.min([A['x2'],B['x2']]) - np.max([A['x1'],B['x1']]) ]) * np.max([ 0, 1 + np.min([A['y2'],B['y2']]) - np.max([A['y1'],B['y1']]) ])
SU = SA + SB - SI
overlap_AA = float(SI) / float(SU)
print 'overlap between A and A: %f' % overlap_AA
Выход будет:
overlap between A and B: 0.250000
overlap between A and A: 1.000000
@ User3025064 является правильным и является самым простым решением, однако исключительность должна быть проверена сначала для прямоугольников, которые не пересекаются, например, для прямоугольников A & amp; B (в Visual Basic):
If A.Top =< B.Bottom or A.Bottom => B.Top or A.Right =< B.Left or A.Left => B.Right then
Exit sub 'No intersection
else
width = ABS(Min(XA2, XB2) - Max(XA1, XB1))
height = ABS(Min(YA2, YB2) - Max(YA1, YB1))
Area = width * height 'Total intersection area.
End if
[ymin_a, xmin_a, ymax_a, xmax_a] = list(bbox_a)
[ymin_b, xmin_b, ymax_b, xmax_b] = list(bbox_b)
x_intersection = min(xmax_a, xmax_b) - max(xmin_a, xmin_b) + 1
y_intersection = min(ymax_a, ymax_b) - max(ymin_a, ymin_b) + 1
if x_intersection <= 0 or y_intersection <= 0:
return 0
else:
return x_intersection * y_intersection
Формула для пересечения будет
SI= Max(0, Min(XA2, XB2) - Max(XA1, XB1)) * Max(0, Min(YA2, YB2) - Max(YA1, YB1))
, тогда объединение будет S=SA+SB-SI
И, наконец, отношение будет SI / S
.
Ответ @ user3025064 - правильный ответ. Принятый ответ непреднамеренно переворачивает внутренние MAX и MIN звонки. Нам также не нужно сначала проверять, пересекаются они или нет, если мы используем представленную формулу MAX (0, x) в отличие от ABS (x). Если они не пересекаются, MAX (0, x) возвращает ноль, что делает область пересечения 0 (то есть непересекающейся).
Я предлагаю, чтобы @Yves Daoust исправил его ответ, потому что он принят, который появляется любому, кто ищет эту проблему. Еще раз, вот правильная формула для пересечения:
SI = Max(0, Min(XA2, XB2) - Max(XA1, XB1)) * Max(0, Min(YA2, YB2) - Max(YA1, YB1))
Остальное как обычно. Союз:
SU = SA + SB - SI
и соотношение:
SI/SU
Недавно я столкнулся с этой проблемой и применил ответ Ив, но почему-то это привело к неправильному размеру области, поэтому я переписал ее.
Предполагая два прямоугольника A и B, узнайте, сколько они перекрываются, и если да, верните размер области:
IF A.right < B.left OR A.left > B.right
OR A.bottom < B.top OR A.top > B.bottom THEN RETURN 0
width := IF A.right > B.right THEN B.right - A.left ELSE A.right - B.left
height := IF A.bottom > B.bottom THEN B.bottom - A.top ELSE A.bottom - B.top
RETURN width * height
Предполагая, что прямоугольник должен быть параллелен оси x
и y
, поскольку это похоже на ситуацию из предыдущих комментариев и ответов.
Я еще не могу оставлять комментарии, но я хотел бы что оба предыдущих ответа, похоже, игнорируют случай, когда один боковой прямоугольник полностью находится в стороне от другого прямоугольника. Пожалуйста, исправьте меня, если я ошибаюсь.
Рассмотрим случай
a: (1,1), (4,4)
b: (2,2), (5,3)
. В этом случае мы видим, что для пересечения высота должна быть bTop - bBottom
, поскольку вертикальная часть b
полностью содержится в a
.
Нам просто нужно добавить еще несколько случаев следующим образом: (Код можно закоротить, если вы обрабатываете верх и низ как то же самое, что и правое и левое, поэтому что вам не нужно дважды дублировать условный фрагмент, но это должно делать.)
if aRight <= bLeft or bRight <= aLeft or aTop <= bBottom or bTop <= aBottom:
# There is no intersection in these cases
return 0
else:
# There is some intersection
if aRight >= bRight and aLeft <= bLeft:
# From x axis point of view, b is wholly contained in a
width = bRight - bLeft
elif bRight >= aRight and bLeft <= aLeft:
# From x axis point of view, a is wholly contained in b
width = aRight - aLeft
elif aRight >= bRight:
width = bRight - aLeft
else:
width = aRight - bLeft
if aTop >= bTop and aBottom <= bBottom:
# From y axis point of view, b is wholly contained in a
height = bTop - bBottom
elif bTop >= aTop and bBottom <= aBottom:
# From y axis point of view, a is wholly contained in b
height = aTop - aBottom
elif aTop >= bTop:
height = bTop - aBottom
else:
height = aTop - bBottom
return width * height