求教 2个二维矩阵取交集的精简算法

shilei831115 2012-08-01 02:32:22
描述如下:

有2类矩阵,维度各不同:(N,M,x,y均为大于3的自然数)
1、矩阵A 大小为N*M。
2、矩阵B1,B2,B3 大小为(N-x)*(M-y)

如何能快速找出 A交B1=B1 或者A交B2=B2 或者A交B3=空呢?

给出思路就行,如果.net里面集成有函数,请指出函数名称。谢谢。
...全文
687 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
yang2948443 2012-08-03
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
只判断存在性。 只要能判断出A中是否含有B1 B2 B3 即可。
[/Quote]
LZ真是好淫,3Q。
qldsrx 2012-08-02
  • 打赏
  • 举报
回复
我不知道什么是KMP,但是从那个解说上看,和我的思路一致,反正只要速度快,要知道自己用的是什么算法干嘛?而且算法本身也不代表效率,还要看实际编写的代码,代码编写的优化也决定了效率。

另外我还必须问清楚一个后,才能开始编码。你的A交B3=空的情况,是不是B3完全匹配不到,如果B3内部能匹配到部分,那么这时交集的结果不就不为空了吗?这个情况比较复杂,希望你可以详细说明下。

再有,3个条件是不是要同时满足。
qldsrx 2012-08-02
  • 打赏
  • 举报
回复
给你一段A交B1=B1的算法,这算法也写了好长时间,其它的类似。验证结果你可以任意修改二维数组的定义部分,看输出结果是否为期待值。

bool[,] a = new bool[5, 6] { { true, false, false, true, true, true }, { true, false, false, true, true, true }, { true, false, false, true, false, true }, { true, false, false, true, false, true }, { true, false, false, true, false, true } };
bool[,] b1 = new bool[3, 3] { { false, true, false }, { false, true, false }, { false, true, false } };
//bool[,] b2 = new bool[3, 3] { { false, true, false }, { false, true, false }, { false, true, false } };
//bool[,] b3 = new bool[3, 3] { { false, true, false }, { false, true, false }, { false, true, false } };
bool isfind = false;
unsafe
{
fixed (bool* pa = &a[0, 0])
fixed (bool* pb = &b1[0, 0])
{
B3* pb3 = (B3*)pb;
bool* pa1 = pa;
for (int x = 0; x <= 5 - 3; x++)//5-3表示a和b1的第二纬长度之差
{
for (int y = 0; y <= 6 - 3; y++)//6-3表示a和b1的第一纬长度之差
{
if (isfind = ((B3*)pa1)->Equals(*pb3))
{
bool* pa2 = pa1;
for (int i = 0; i < 2; i++)
{
pa2 += 6;//6为二维数组a的第一纬长度
if (!(isfind = ((B3*)pa2)->Equals(*pb3)))
{
break;
}
}
}
if (isfind)
break;
pa1++;
}
if (isfind)
break;
pa1 += 3;//3为二维数组b1的第一纬长度
}
}
}
Console.WriteLine(isfind);
Console.ReadLine();

自定义结构体,用户封装子集单行信息,进行快速比较,子集第一纬度的长度决定了这个结构体内bool类型字段的数目。

public struct B3
{
bool tmp1;
bool tmp2;
bool tmp3;
}
shilei831115 2012-08-02
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 的回复:]

我不知道什么是KMP,但是从那个解说上看,和我的思路一致,反正只要速度快,要知道自己用的是什么算法干嘛?而且算法本身也不代表效率,还要看实际编写的代码,代码编写的优化也决定了效率。

另外我还必须问清楚一个后,才能开始编码。你的A交B3=空的情况,是不是B3完全匹配不到,如果B3内部能匹配到部分,那么这时交集的结果不就不为空了吗?这个情况比较复杂,希望你可以详细说明下。

再有,3个条件……
[/Quote]

这样描述 你看行么?

A交B1=B1,A交B2=B2,A交B3!=B3,意思就是说,说是交集,其实也就是包含的意思,即:A要么包含B1,要么不包含B1。如果A和B1的交集是B1的一个子集的话,就可以认定其不符合要求。那么直接可丢弃掉。 在总结一次:求在矩阵A中是否完整存在矩阵B1,B2,B3。 呵呵,就这么个意思。
shilei831115 2012-08-01
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

楼主,我有两个方法
方法一:
暴力法,M*N的矩阵中只有(X+1)*(Y+1)个(M-X)*(N-Y)的子矩阵对吧,依次暴力枚举就行了,判断有没有一个是合适的

方法二:
用KMP算法对
对M*N的矩阵中的第一行开始,依次判断(M-X)*(N-Y)中的第一行在不在里面(KMP算法非常快)
如果不在,说明M*N矩阵的第一行肯定用不上,此时只需要对剩下的……
[/Quote]

你说的第二个方法我去了解了解。谢谢啊
续写经典 2012-08-01
  • 打赏
  • 举报
回复
题:求一个矩阵中最大的二维子矩阵(元素和最大).如:
1 2 0 3 4
2 3 4 5 1
1 1 5 3 0
中最大的是:
4 5
5 3
要求:(1)写出算法;(2)分析时间复杂度;(3)用C写出关键代码
分析:方法一、这是最容易想到也是最容易实现的方法。遍历矩阵(行迭代器为i,列迭代器为j),以当前遍历到的元素为首a[i,j],计算二维子矩阵的和(sum=a[i,j]+a[i+1,j]+a[i,j+1]+a[i+1,j+1]),并找出和最大的二维矩阵,注意矩阵的最后一行和最后一列不用遍历。时间复杂度为O(i*j)。
实现代码:

void get_max_22Matrix(int *a,int row,int col,int *result)
//a为原矩阵,row,col指a矩阵的行和列,result存储最终得到的子二维矩阵
{
int maxsum=0,result_i,result_j,sum;

#define a(i,j) *(a+(i)*col+(j)) //用二维的形式表示一维数组,访问需要一定的代价
#define result(i,j) *(result+(i)*2+(j))

for(int i=0; i<row-1; i++)
for(int j=0; j<col-1; j++)
{
sum = a(i,j)+a(i+1,j)+a(i,j+1)+a(i+1,j+1); //访问四个元素并相加得到当前的和
if(maxsum<sum) //更新最大子二维矩阵数据
{
maxsum = sum;
result_i = i;
result_j = j;
}
}

/* 将结果存储到result二维数组中*/
result(0,0)=a(result_i,result_j);
result(1,0)=a(result_i+1,result_j);
result(0,1)=a(result_i,result_j+1);
result(1,1)=a(result_i+1,result_j+1);
#undef a
#undef result
}
shilei831115 2012-08-01
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]

A
0,1,1,0
1,0,0,1
1,1,1,1
1,0,1,1

B1
1,1,0
0,0,1
1,1,1

B2
0,1,1
1,0,0
1,1,1

这种情况满足A交B1=B1 A交B2=B2吗?我的理解应该是满足
[/Quote]

完全是这个意思。 请教一下,有没有快速的算法判定其是否包含?不建议暴力的对比……
  • 打赏
  • 举报
回复
楼主,我有两个方法
方法一:
暴力法,M*N的矩阵中只有(X+1)*(Y+1)个(M-X)*(N-Y)的子矩阵对吧,依次暴力枚举就行了,判断有没有一个是合适的

方法二:
用KMP算法对
对M*N的矩阵中的第一行开始,依次判断(M-X)*(N-Y)中的第一行在不在里面(KMP算法非常快)
如果不在,说明M*N矩阵的第一行肯定用不上,此时只需要对剩下的(M-1)*N来同样处理,反之如果在里面,你就知道对齐的位置了对吧,你根据这个对齐的位置依次往下比较,如果全部相等,就找到了,否则同样地说明了第一行肯定用不上。
qldsrx 2012-08-01
  • 打赏
  • 举报
回复
A
0,1,1,0
1,0,0,1
1,1,1,1
1,0,1,1

B1
1,1,0
0,0,1
1,1,1

B2
0,1,1
1,0,0
1,1,1

这种情况满足A交B1=B1 A交B2=B2吗?我的理解应该是满足
shilei831115 2012-08-01
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]

最好能给点数据演示下效果。你说的包含情况我能理解,但是包含本身有地址包含和数据包含两种,如果你的矩阵是点阵,那么只有地址包含的概念,也就是我前面所说的,只要用Point结构存储这个点阵信息即可,如果你的矩阵是字符串的矩阵,或者是整型等复杂类型矩阵,那么是否要位置和内容都相同才算包含?
[/Quote]

继续补充。矩阵里面只有0和1两个值。 如果信息不明确,请继续跟帖
代码誊写工 2012-08-01
  • 打赏
  • 举报
回复
http://www.codeproject.com/Articles/51470/Advanced-Matrix-Library-in-C-NET,看看这个网址。
qldsrx 2012-08-01
  • 打赏
  • 举报
回复
最好能给点数据演示下效果。你说的包含情况我能理解,但是包含本身有地址包含和数据包含两种,如果你的矩阵是点阵,那么只有地址包含的概念,也就是我前面所说的,只要用Point结构存储这个点阵信息即可,如果你的矩阵是字符串的矩阵,或者是整型等复杂类型矩阵,那么是否要位置和内容都相同才算包含?
shilei831115 2012-08-01
  • 打赏
  • 举报
回复
A交B1=B1 A交B2=B2,再直接点就是是否包含……

再描述描述:

在2维矩阵A中,查找2维矩阵B1,B2,B3,看其是否存在。这样说行不行?
qldsrx 2012-08-01
  • 打赏
  • 举报
回复
再有一个问题,你这里的交集是不是是指位置的交集,我的理解是,把二维矩阵的每个点用Point结构来存储,那么只要比较这个Point是否有交集即可,而比较本身也只要循环遍历下,看每个元素是否包含即可。
不知道我理解是否正确。
yang2948443 2012-08-01
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
只判断存在性。 只要能判断出A中是否含有B1 B2 B3 即可。
[/Quote]
顶!求给分!
shilei831115 2012-08-01
  • 打赏
  • 举报
回复
只判断存在性。 只要能判断出A中是否含有B1 B2 B3 即可。
qldsrx 2012-08-01
  • 打赏
  • 举报
回复
你能不能再描述清晰点,你是要给出所有这样集合的组合呢,还是要验证给定的这样4个集合呢?

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧