String Matlab,根据第一个字符串对字符串单元格进行排序
我有2个字符串单元格,我想根据第一个字符串对它们进行排序String Matlab,根据第一个字符串对字符串单元格进行排序,string,matlab,cell,cell-array,String,Matlab,Cell,Cell Array,我有2个字符串单元格,我想根据第一个字符串对它们进行排序 A = {'a';'b';'c'} B = {'b';'a';'c'} idx = [2,1,3] % TO FIND B=B(idx); 我想找到一种方法来查找idx…使用的第二个输出ismember告诉您第一组中的值是否在第二组中的任何位置。第二个输出告诉您,如果我们发现任何东西,这些值位于何处。因此: A = {'a';'b';'c'} B = {'b';'a';'c'} [~,idx] = ismember(A, B);
A = {'a';'b';'c'}
B = {'b';'a';'c'}
idx = [2,1,3] % TO FIND
B=B(idx);
我想找到一种方法来查找idx
…使用的第二个输出ismember
告诉您第一组中的值是否在第二组中的任何位置。第二个输出告诉您,如果我们发现任何东西,这些值位于何处。因此:
A = {'a';'b';'c'}
B = {'b';'a';'c'}
[~,idx] = ismember(A, B);
请注意,在声明单元格数组时有一个小的输入错误。对于a
,在b
和c
之间有一个冒号;对于b
,在a
和c
之间有一个冒号。为了正确起见,我在那里放了一个分号
因此,我们得到:
idx =
2
1
3
标杆管理 我们这里有三个非常好的算法。因此,让我们通过进行基准测试来了解它的性能。我要做的是生成一个10000 x 1的随机字符数组,由小写字母组成。然后将其封装到一个10000 x 1单元数组中,其中每个单元都是一个单字符数组。我这样构造
A
,而B
是A
中元素的随机排列。这是我为我们编写的代码:
letters = char(97 + (0:25));
rng(123); %// Set seed for reproducibility
ind = randi(26, [10000, 1]);
lettersMat = letters(ind);
A = mat2cell(lettersMat, ones(10000,1), 1);
B = A(randperm(10000));
现在。。。下面是测试代码:
clear all;
close all;
letters = char(97 + (0:25));
rng(123); %// Set seed for reproducibility
ind = randi(26, [10000, 1]);
lettersMat = letters(ind);
A = mat2cell(lettersMat, 1, ones(10000,1));
B = A(randperm(10000));
tic;
[~,idx] = ismember(A,B);
t = toc;
fprintf('ismember: %f\n', t);
clear idx; %// Make sure test is unbiased
tic;
[~,idx] = max(bsxfun(@eq,char(A),char(B)'));
t = toc;
fprintf('bsxfun: %f\n', t);
clear idx; %// Make sure test is unbiased
tic;
[~, indA] = sort(A);
[~, indB] = sort(B);
idx = indB(indA);
t = toc;
fprintf('sort: %f\n', t);
这是我从计时中得到的:
ismember: 0.058947
bsxfun: 0.110809
sort: 0.006054
路易斯·门多的方法最快,其次是
ismember
,最后是bsxfun
。对于代码紧凑性,ismember
是首选,但是对于性能,sort
更好。就我个人而言,我认为bsxfun
应该会赢,因为它是一个非常好用的函数;) 这似乎比使用ismember
要快得多(尽管无可否认,这比使用ismember的速度要慢得多)。感谢@Divakar对这个答案的更正
[~, indA] = sort(A);
[~, indB] = sort(B);
idx = indA(indB);
我不得不插嘴,因为运行时性能似乎可以成为这里的一个标准:)
假设您处理的是标量字符串(每个单元格中有一个字符),那么即使在A
和B
之间没有commmon元素,并且使用非常强大的bsxfun
时,我仍然希望这能提高运行效率-
[v,idx] = max(bsxfun(@eq,char(A),char(B)'));
idx = v.*idx
范例-
A =
'a' 'b' 'c' 'd'
B =
'b' 'a' 'c' 'e'
idx =
2 1 3 0
A =
'a' 'b' 'c'
B =
'b' 'a' 'c'
idx =
2 1 3
对于特定情况,当a
和B
之间没有非公共元素时,它将成为一个单行程序-
[~,idx] = max(bsxfun(@eq,char(A),char(B)'))
范例-
A =
'a' 'b' 'c' 'd'
B =
'b' 'a' 'c' 'e'
idx =
2 1 3 0
A =
'a' 'b' 'c'
B =
'b' 'a' 'c'
idx =
2 1 3
那只是我的一句懒话!;)+1当然。@Divakar-ahaha谢谢:)当我看到你的评论时,我正准备按下post按钮。如果我早点看到你的评论,我就不会发了。我真的很高兴你发了!有解释总是很棒的。哈哈,非常好,更重要的是公平的基准测试!看起来像是bsxfun
迷失了方向,但它很可爱顺便说一句,路易斯的解决方案需要修正,但我认为这不会对基准测试产生太大影响。另外,我认为针对[~,idx]=max(bsxfun(@eq,char(A),char(B))
进行基准测试会更公平,因为我们不考虑非公共元素的情况。你确实需要这个“
用于bsxfun
。哦。很好地使用排序
。我想使用排序
,但我不知道如何使用另一个数组B
。做得很好+1。@rayryeng谢谢!实际上,使用嵌套排序很容易混淆。有时我只是尝试组合(没有那么多),直到我发现哪种组合有效:-)(顺便说一下,已经+1了)如果A和B之间的某些元素不常见,或者如果这些单元数组中的每个元素都有重复,该怎么办?像这样的东西可能-A={'A';'b';'c';'d'},b={'b';'A';'c';'A'}
。我想OP可能不关心重复情况,但至少不能处理公共元素情况。@Divakar-这是一个很好的观点。我的猜测是OP只涉及a
和B
之间排序的排列。我想我们可以假设A
中的元素将在B
中,并且是唯一的。如果是这种情况,那么这种方法将非常有效。顺便说一句,路易斯·门多,谢谢你的+1:)哈哈哈,我告诉自己Divakar很可能会带来一个bsxfun
解决方案。我不认为我是对的+1.我实际上要生成一堆随机的唯一字符@rayryeng说吧!让我们看看你有什么!;)另见