MATLAB: сравнение массивов ячеек строки
у меня есть два массива ячеек строк, и я хочу проверить, содержат ли они те же строки (они не должны быть в том же порядке, и мы не знаем, имеют ли они одинаковую длину).
например:
a = {'2' '4' '1' '3'};
b = {'1' '2' '4' '3'};
или
a = {'2' '4' '1' '3' '5'};
b = {'1' '2' '4' '3'};
сначала я думал о strcmp
но для этого потребуется цикл над содержимым одной ячейки и сравнение с другим. Я также рассмотрел ismember
используя что-то вроде:
ismember(a,b) & ismember(b,a)
но тогда мы не знаем в заранее, что они имеют одинаковую длину (очевидный случай неравных). Итак, как бы вы выполнили это сравнение наиболее эффективным способом, не записывая слишком много случаев if/else.
3 ответов
вы можете использовать функцию SETXOR, который вернет значения, которые не находятся в пересечении двух массивов ячеек. Если он возвращает пустой массив, то два массива ячеек содержат одинаковые значения:
arraysAreEqual = isempty(setxor(a,b));
EDIT: некоторые показатели эффективности...
поскольку вам было интересно узнать о показателях производительности, я подумал, что проверю скорость моего решения против двух перечисленных решений by Амро (который использовать для ismember и чего strcmp/CELLFUN). Сначала я создал два больших массива ячеек:
a = cellstr(num2str((1:10000).')); %'# A cell array with 10,000 strings
b = cellstr(num2str((1:10001).')); %'# A cell array with 10,001 strings
затем я запускал каждое решение 100 раз, чтобы получить среднее время выполнения. Затем я поменялся a
и b
и повторите его. Вот результаты:
Method | Time | a and b swapped
---------------+---------------+------------------
Using SETXOR | 0.0549 sec | 0.0578 sec
Using ISMEMBER | 0.0856 sec | 0.0426 sec
Using STRCMP | too long to bother ;)
заметил, что SETXOR решение имеет последовательно быстрое время. The для ismember решение на самом деле работать немного быстрее, если a
имеет элементы, которые не находятся в b
. Это связано с короткое замыкание &&
который пропускает вторую половину расчета (потому что мы уже знаем a
и b
не содержат одинаковых значений). Однако, если все значения в a
также в b
, the для ismember решение значительно медленнее.
вы все еще можете использовать функцию ISMEMBER, как и с небольшой модификацией:
arraysAreEqual = all(ismember(a,b)) && all(ismember(b,a))
кроме того, вы можете написать версию цикла с STRCMP как одну строку:
arraysAreEqual = all( cellfun(@(s)any(strcmp(s,b)), a) )
EDIT: я добавляю третье решение, адаптированное из другого поэтому вопрос:
g = grp2idx([a;b]);
v = all( unique(g(1:numel(a))) == unique(g(numel(a)+1:end)) );
в том же духе Im выполнил сравнение времени (используя TIMEIT
взгляните на функцию intersect
что говорит справка MATLAB:
[c, ia, ib] = intersect(a, b)
также возвращает векторы индекса столбцаia
иib
такой, чтоc = a(ia)
иb(ib)
(илиc =
a(ia,:)
иb(ib,:)).