我想要实现的具体任务很难描述,所以这里有一个例子:给定A和x
A = [1 2;
3 0;
3 5;
4 0];
x = [1 2 3];
我希望算法输出
output: [1 2]
意味着A中第1行和第2行中的所有非零元素都在x。
中我使用单元格数组和循环完成了这项工作;然而,A和x非常大,我的方法根本没有效率。此外,我似乎无法弄清楚如何返工ismember给我我想要的。什么是最快/最少内存密集型方法?
编辑:道歉,我原来的例子太简单了。现在已经纠正了。
答案 0 :(得分:4)
第一个答案很好,但我建议使用List<Integer> unavTimesConv = new ArrayList<Integer>();
List<String> unavDays = new ArrayList<String>();
String[] unavDaysTemp = request.getParameterValues("days");
if(request.getParameterValues("days") != null)
{
for(int i = 0; i < (unavTimesConv.size() / 2); i++)
{
for(int j = (7*i); j < (7*(i+1)); j++)
{
if(unavDaysTemp[j].equals("M"))
{
unavDays.add("M");
}
else if(unavDaysTemp[j].equals("T"))
{
for(int k = 0; k < 1; k++) {unavDays.add(null);}
unavDays.add("T");
}
else if(unavDaysTemp[j].equals("W"))
{
for(int k = 0; k < 2; k++) {unavDays.add(null);}
unavDays.add("W");
}
else if(unavDaysTemp[j].equals("TH"))
{
for(int k = 0; k < 3; k++) {unavDays.add(null);}
unavDays.add("TH");
}
else if(unavDaysTemp[j].equals("F"))
{
for(int k = 0; k < 4; k++) {unavDays.add(null);}
unavDays.add("F");
}
else if(unavDaysTemp[j].equals("S"))
{
for(int k = 0; k < 5; k++) {unavDays.add(null);}
unavDays.add("S");
}
else {unavDays.add("Something busted");}
}
}
}
不。有更多雄辩的方法可以做你所要求的。将ismember
与all
结合使用,然后在完成后将矩阵arrayfun
编入索引。基本上,您的问题是确定行是否具有A
中找到的所有值并忽略零值。在这种情况下,我们可以找到矩阵x
中实际为零的所有值,然后使用它来增加我们的结果。
使用A
作为第一个输入,A
作为第二个输入,将返回与x
大小相同的矩阵,告诉您A
中的元素是否为A
在x
中找到。如果您想检查A
中是否可以找到某行的矩阵x
中的所有元素,请检查行中所有元素是否为1
。除此之外,找到所有零的元素,然后使用ismember
的输出将这些设置为1.这可以使用logical
OR来完成。之后,您可以使用all
并使用ismember
的输出作为all
的第一个输入并将第二个参数设置为2来独立检查每一行。这将返回所有矩阵A
中的行,x
忽略 A
中{0}}行的任何值为零的任何列寻找:
A = [1 2; 3 0; 4 0];
x = [1 2 3];
mask = ismember(A, x);
ind = all(mask | A == 0, 2);
我也支持单行。我们可以将其合并为一行代码:
ind = all(ismember(A, x) | A == 0, 2);
更短的是简单地反转A
。否则所有零元素都会变为true
和false
:
ind = all(ismember(A, x) | ~A, 2);
因此 ind
将是:
>> ind
ind =
3×1 logical array
1
1
0
由于您需要实际的行索引,因此您可以在此基础上使用find
:
>> find(ind)
ans =
1
2
要验证,请在评论中使用您的第二个示例:
>> A = [1 2;3 5;4 0];
>> x = [1 2 3];
>> ind = all(ismember(A, x) | ~A, 2)
ind =
3×1 logical array
1
0
0
>> find(ind)
ans =
1
答案 1 :(得分:3)
我认为返工的最佳方式是成员是通过检查A中的非零元素来确保没有“没有成员”。 arrayfun可以快速完成工作。它为您的特定机器使用最有效的并行计算。以下行应返回正确的输出:
find(arrayfun(@(a) sum(~ismember(A(a,A(a,:)>0),x)),1:size(A,1))==0)
这是你在找什么?
但是,如果您的问题与内存有关,那么您可能必须将arrayfun操作分解为多个部分(1:floor(size(A,1)/ 2),floor(size(A,1)/ 2) :size(A,1)或更小的块),因为MATLAB让一大堆工作人员完成任务,并且可以使用你所有可用的RAM内存......