Как сделать набор разницы, кроме как без устранения повторяющихся элементов - PullRequest
2 голосов
/ 23 февраля 2012

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

Пример: A = [1 1 2 4]; B = [1 2 4];

Желаемый результат будет A-B = C = [1]

Или, другой пример, E = [3 3 5 5]; F = [3 3 5];

Желаемый результат будет E-F = G = [5]

Хотелось бы сделать это, используя операции множеств Matlab, но их функция setdiff не учитывает повторяющиеся элементы в матрицах. Я ценю, что это правильно с точки зрения теории множеств, но тем не менее хотел бы заняться такими проблемами, как: «У меня есть 3 яблока и 4 апельсина, а вы берете 2 яблока и 1 апельсин, сколько у меня осталось каждого». Мой диапазон возможных значений в этих наборах исчисляется тысячами, поэтому создание большой матрицы для подсчета элементов и последующего вычитания матриц не представляется возможным по соображениям скорости. Мне придется выполнить тысячи этих вычислений с тысячами заданных элементов во время работы с меню графического интерфейса.

Пример того, чего я хотел бы избежать для рассмотрения второго примера выше: E = [0 0 2 0 2]; F = [0 0 2 0 1];

G = E-F = [0 0 0 0 1];

Спасибо за вашу помощь!

Ответы [ 2 ]

2 голосов
/ 23 февраля 2012

Это можно сделать с помощью команды accumarray.

A = [1 1 2 4]';
B = [1 2 4]';  % <-make these column vectors

X = accumarray(A, 1);
Y = accumarray(B, 1); 

Это приведет к выводу

X = [2 1 0 1]'

и

Y = [1 1 0 1]'

Где X (i)представляет число инцидентов числа i в векторе A, а Y (i) представляет количество инцидентов числа i в векторе B.

Тогда вы можете просто взять X - Y.

Одно предостережение: если максимальные значения A и B различны, выходные данные множества будут иметь различную длину.Если это так, вы можете просто назначить вывод как подмножество вектора нулей, которое является размером большего вектора.

1 голос
/ 23 февраля 2012

Я просто хочу улучшить ответ Prototoast.

Чтобы избежать ошибок с неположительными числами в A или B , используйте hist:

A = [-10 0 1 1 2 4];
B = [1 2 4];

Нам нужны минимальные и максимальные значения в объединении A и B :

U = [A,B];
range_ = min(U):max(U);

, чтобы мы могли использовать hist чтобы дать нам векторы одинаковой длины:

a = hist(A,range_)
b = hist(B,range_)

Теперь вам нужно вычесть гистограммы:

r = a-b

Если вы хотите, чтобы оператор разности множеств был симметричным, используйте:

r = abs(a-b)

Следующее даст вам информацию о том, какие предметы находятся в A \ B (\ вот ваша измененная разница набора):

C = range_(logical(r))

Надеждаэто помогает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...